为了账号安全,请及时绑定邮箱和手机立即绑定

Google App Engine / Datastore / Flask / Python

Google App Engine / Datastore / Flask / Python

皈依舞 2023-08-08 16:01:29
我构建了一个简单的新闻聚合器网站,其中所有 App Engine 实例的内存使用量不断增长,直到达到限制并因此被关闭。我已经开始消除应用程序中的所有内容,以获得最小的可复制版本。这就是我现在所拥有的:app = Flask(__name__)datastore_client = datastore.Client()@app.route('/')def root():        query = datastore_client.query(kind='source')    query.order = ['list_sequence']    sources = query.fetch()         for source in sources:        pass    统计数据显示了典型的锯齿模式:实例启动时,内存使用量达到 190 - 210 Mb,然后根据一些请求(但不是所有请求),内存使用量增加 20 - 30 Mb。(顺便说一句,这大致对应于查询结果的估计大小,尽管我不能确定这是相关信息。)这种情况一直发生,直到它超过 512 Mb,然后关闭。它通常发生在第 50-100 个对“/”的请求左右。在此期间,不会对其他任何事情提出其他请求。现在,如果我消除“for”循环,只保留查询,问题就会消失,内存使用量保持在 190 Mb 不变,即使在 100 多个请求之后也不会增加。gc.collect() 最后没有帮助。我还尝试查看函数开头和结尾处的tracemalloc 统计信息的差异,但没有发现任何有用的东西。请问有人经历过类似的事情吗?有什么想法可能会出问题吗?您可以推荐哪些额外的测试/调查?这是否可能是我无法控制的 Google App Engine/数据存储问题?谢谢。
查看完整描述

2 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

现在,如果我消除“for”循环,只保留查询,问题就会消失,内存使用量保持在 190 Mb 不变,即使在 100 多个请求之后也不会增加。

query.fetch()返回一个迭代器,而不是结果的实际数组


查看源代码,看起来这个迭代器具有用于获取查询的下一页的代码。所以你的 for 循环强制它获取结果的所有页面。事实上,在您开始迭代之前,我认为它实际上不会获取任何内容。这就是为什么删除 for 循环会产生影响

不幸的是,除此之外我不确定,因为当您深入研究源代码时,您很快就会遇到 GRPC 存根,并且不清楚问题是否在那里。

查看完整回答
反对 回复 2023-08-08
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

尝试使用NDB Library。对该库的所有调用都必须包装到上下文管理器中,这应该保证关闭后的清理工作。这可以帮助解决您的问题:

ndb_client = ndb.Client(**init_client)


with ndb_client.context():

    query = MyModel.query().order(MyModel.my_column)

    sources = query.fetch()

    for source in sources:

        pass


# if you try to query DataStore outside the context manager, it will raise an error

query = MyModel.query().order(MyModel.my_column)


查看完整回答
反对 回复 2023-08-08
  • 2 回答
  • 0 关注
  • 73 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信