【问题标题】:Small Flask-SQLAlchemy Query taking 900Mb of RAM within Celery Task (Kubernetes Cluster)在 Celery 任务(Kubernetes 集群)中占用 900Mb RAM 的小型 Flask-SQLAlchemy 查询
【发布时间】:2021-05-16 07:34:42
【问题描述】:

我有一个非常简单的查询,在一个非常简单的表中:

def get_defaults(domain):
    defaults = BaseDefaults.query.filter_by(domain=domain).first()
    return defaults

该表有(不开玩笑)3 行,34 列,1 PK,1 Unique,2 FK。以下类型:

Timestamp: 2 Cols
Integer: 5 Cols
Booleans: 8 Cols
VarChar(100) & Varchar(250): 19 Cols

通常,这些列中约有 5-8 个具有空值。 此函数在 Celery 任务的上下文中运行,该任务在内存 (1.2Gb) 中爆炸,而另一个正在运行的任务使用大约 110Mb。

所以我用memory_profiler 分析了代码,结果发现这个特定的函数defaults = get_defaults(domain) 占用了大约800-900Mb 的RAM,这完全没有意义。

我在本地看不到相同的行为 - 它只发生在 Kubernetes 集群(托管在 DigitalOcean 上)内,因此很难理解可能发生的情况。

该函数查询托管在 RDS 上的 Postgres DB,它似乎工作正常(来自本地 pc 或 SQL 客户端的查询工作不到 200 毫秒)。

我还发现,大部分高内存消耗发生在第一次运行查询时,在第二次运行查询(另一个任务运行)时,同一行增加了大约 120Mb 的使用量,这似乎更多似是而非。因此,Celery 中 Flask-SQLAlchemy 中的会话管理也可能会遇到问题。

它消耗集群内的大量 RAM 并威胁节点的健康。如果我将 pod 消耗限制为 512Mb,则 pod 会被创建但随后会立即死亡。

关于如何解决、优化和修复此问题的任何想法?

【问题讨论】:

    标签: python flask kubernetes celery flask-sqlalchemy


    【解决方案1】:

    对于遇到类似情况的任何人,我在backref 模型声明中解决了lazy=True 的问题。

    在数据库中一个完全不同的表开始快速增长之前,这不是问题 - 我们使用lazy='joined',它会自动加入每个具有BsaeDefaults 声明的关系的表。

    通过使用lazy=True,您只加载您查询过的表,因此 pod 中的内存消耗从 1.2Gb 下降到 140Mb。

    【讨论】:

      猜你喜欢
      • 2012-08-16
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 2019-05-25
      • 2019-06-07
      相关资源
      最近更新 更多