小型 Flask-SQLAlchemy 查询在 Celery 任务(Kubernetes 集群)中占用 900Mb RAM

Small Flask-SQLAlchemy Query taking 900Mb of RAM within Celery Task (Kubernetes Cluster)

我有一个非常简单的查询,非常简单 table:

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

table 有(不是开玩笑)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 个具有空值。 这个函数 运行s 在 Celery 任务的上下文中,它在内存中爆炸 (1.2Gb),而另一个 运行ning 的任务使用大约 110Mb。

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

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

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

我还发现大部分高内存消耗发生在第一次查询 运行,第二次查询 运行s(另一个任务 运行), 同一行增加了大约 120Mb 的使用量,这似乎更合理。 Flask-SQLCelery 中的 Alchemy 中的会话管理可能也是这种情况。

它在集群中消耗大量 RAM 并威胁到节点的健康。如果我将 pod 消耗限制为 512Mb,pods 会创建但随后立即消失。

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

对于正在经历类似事情的任何人,我在 backref 模型声明中使用 lazy=True 解决了我的问题。

这不是问题,直到数据库中完全不同的 table 开始快速增长 - 我们使用 lazy='joined',它会自动加入每个 table 已声明的关系BsaeDefaults.

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