使用 Google Cloud Datastore Python 库时应如何调查内存泄漏?

2024-05-25

我有一个使用 Google 数据存储的网络应用程序,在发出足够的请求后内存不足。

我已将范围缩小到数据存储查询。下面提供了最低 PoC,稍长的版本 https://gist.github.com/edeca/214d7a7c51f84b9c2dc2a2c2656c191e其中包括内存测量,位于 Github 上。

from google.cloud import datastore
from google.oauth2 import service_account

def test_datastore(entity_type: str) -> list:
    creds = service_account.Credentials.from_service_account_file("/path/to/creds")
    client = datastore.Client(credentials=creds, project="my-project")
    query = client.query(kind=entity_type, namespace="my-namespace")
    query.keys_only()
    for result in query.fetch(1):
        print(f"[+] Got a result: {result}")

for n in range(0,100):
    test_datastore("my-entity-type")

分析进程 RSS 显示每次迭代大约增长 1 MiB。即使没有返回结果也会发生这种情况。以下是我的 Github 要点的输出:

[+] Iteration 0, memory usage 38.9 MiB bytes
[+] Iteration 1, memory usage 45.9 MiB bytes
[+] Iteration 2, memory usage 46.8 MiB bytes
[+] Iteration 3, memory usage 47.6 MiB bytes
..
[+] Iteration 98, memory usage 136.3 MiB bytes
[+] Iteration 99, memory usage 137.1 MiB bytes

但与此同时,Python 的mprof https://pypi.org/project/memory-profiler/显示一个平面图(像mprof run python datastore_test.py):

问题

我调用数据存储的方式是否有问题,或者这可能是库的根本问题?

环境是 Windows 10 上的 Python 3.7.4(也在 Docker 中的 Debian 3.8 上进行了测试)google-cloud-datastore==1.11.0 and grpcio==1.28.1.

Edit 1

澄清一下,这不是典型的 Python 分配器行为,它从操作系统请求内存,但不会立即从内部竞技场/池中释放它。下面是我受影响的应用程序在其中运行的 Kubernetes 图表:

由此可见:

  • 内存线性增长,直到大约 2GiB,应用程序实际上崩溃了,因为内存不足(从技术上讲,Kubernetes 驱逐了 pod,但这与这里无关)。
  • 运行相同的 Web 应用程序,但不与 GCP 存储或数据存储进行交互。
  • 仅添加了与 GCP Storage 的交互(随着时间的推移略有增长,可能是正常的)。
  • 仅添加了与 GCP 数据存储的交互(内存增长更大,一小时内大约 512MiB)。数据存储查询与本文中的 PoC 代码完全相同。

Edit 2

为了绝对确定 Python 的内存使用情况,我使用以下命令检查了垃圾收集器的状态gc https://docs.python.org/3/library/gc.html。退出前,程序报告:

gc: done, 15966 unreachable, 0 uncollectable, 0.0156s elapsed

我还使用手动强制垃圾收集gc.collect()在循环的每次迭代期间,这没有什么区别。

由于不存在无法收集的对象,因此内存泄漏似乎不太可能来自使用 Python 内部内存管理分配的对象。因此,外部 C 库更有可能泄漏内存。

潜在相关

有一个打开grpc问题 https://github.com/grpc/grpc/issues/22123我不确定是否相关,但与我的问题有很多相似之处。


我已将内存泄漏范围缩小到创建datastore.Client https://googleapis.dev/python/datastore/latest/client.html目的。

对于以下概念验证代码,内存使用量不会增加:

from google.cloud import datastore
from google.oauth2 import service_account

def test_datastore(client, entity_type: str) -> list:
    query = client.query(kind=entity_type, namespace="my-namespace")
    query.keys_only()
    for result in query.fetch(1):
        print(f"[+] Got a result: {result}")

creds = service_account.Credentials.from_service_account_file("/path/to/creds")
client = datastore.Client(credentials=creds, project="my-project")

for n in range(0,100):
    test_datastore(client, "my-entity-type")

这对于一个小脚本来说是有意义的,其中client对象可以创建一次并在请求之间安全地共享。

在许多其他应用程序中,安全地传递客户端对象更困难(或不可能)。我希望当客户端超出范围时库会释放内存,否则任何长时间运行的程序都可能会出现此问题。

Edit 1

我已经将范围缩小到 grpc。环境变量GOOGLE_CLOUD_DISABLE_GRPC可以设置(为任何值)以禁用 grpc。

设置完成后,我在 Kubernetes 中的应用程序如下所示:

对 valgrind 的进一步调查表明它可能与 grpc 中的 OpenSSL 使用有关,我在这张票 https://github.com/googleapis/python-datastore/issues/25在错误跟踪器上。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Google Cloud Datastore Python 库时应如何调查内存泄漏? 的相关文章

  • Python:在列表理解本身中引用列表理解?

    这个想法刚刚出现在我的脑海中 假设您出于某种原因想要通过 Python 中的列表理解来获取列表的唯一元素 i if i in created comprehension else 0 for i in 1 2 1 2 3 1 2 0 0 3
  • 无法“安装”plpython3u - postgresql

    我正在尝试在 postgresql 中使用 python 语言 像这样的事情 create or replace function test a integer returns integer as if a 2 0 return even
  • Django 代理模型的继承和多态性

    我正在开发一个我没有启动的 Django 项目 我面临着一个问题遗产 我有一个大模型 在示例中简化 称为MyModel这应该代表不同种类的物品 的所有实例对象MyModel应该具有相同的字段 但方法的行为根据项目类型的不同而有很大差异 到目
  • Python 的键盘中断不会中止 Rust 函数 (PyO3)

    我有一个使用 PyO3 用 Rust 编写的 Python 库 它涉及一些昂贵的计算 单个函数调用最多需要 10 分钟 从 Python 调用时如何中止执行 Ctrl C 好像只有执行结束后才会处理 所以本质上没什么用 最小可重现示例 Ca
  • 将 saxon 与 python 结合使用

    我需要使用 python 处理 XSLT 目前我正在使用仅支持 XSLT 1 的 lxml 现在我需要处理 XSLT 2 有没有办法将 saxon XSLT 处理器与 python 一起使用 有两种可能的方法 设置一个 HTTP 服务 接受
  • 使 django 服务器可以在 LAN 中访问

    我已经安装了Django服务器 可以如下访问 http localhost 8000 get sms http 127 0 0 1 8000 get sms 假设我的IP是x x x x 当我这样做时 从同一网络下的另一台电脑 my ip
  • 使用带有关键字参数的 map() 函数

    这是我尝试使用的循环map功能于 volume ids 1 2 3 4 5 ip 172 12 13 122 for volume id in volume ids my function volume id ip ip 我有办法做到这一点
  • 使用 matplotlib 绘制时间序列数据并仅在年初显示年份

    rcParams date autoformatter month b n Y 我正在使用 matpltolib 来绘制时间序列 如果我按上述方式设置 rcParams 则生成的图会在每个刻度处标记月份名称和年份 我怎样才能将其设置为仅在每
  • python 相当于 R 中的 get() (= 使用字符串检索符号的值)

    在 R 中 get s 函数检索名称存储在字符变量 向量 中的符号的值s e g X lt 10 r lt XVI s lt substr r 1 1 X get s 10 取罗马数字的第一个符号r并将其转换为其等效整数 尽管花了一些时间翻
  • 从 Flask 访问 Heroku 变量

    我已经使用以下命令在 Heroku 配置中设置了数据库变量 heroku config add server xxx xxx xxx xxx heroku config add user userName heroku config add
  • 如何在Python中获取葡萄牙语字符?

    我正在研究葡萄牙语 角色看起来很奇怪 我怎样才能解决这个问题 代码 import feedparser import random Vou definir os feeds feeds conf feedurl http pplware s
  • Flask如何获取请求的HTTP_ORIGIN

    我想用我自己设置的 Access Control Allow Origin 标头做出响应 而弄清楚请求中的 HTTP ORIGIN 参数在哪里似乎很混乱 我在用着烧瓶 0 10 1 以及HTTP ORIGIN似乎是这个的特点之一object
  • 无法在 Python 3 中导入 cProfile

    我试图将 cProfile 模块导入 Python 3 3 0 但出现以下错误 Traceback most recent call last File
  • Jupyter Notebook 内核一直很忙

    我已经安装了 anaconda 并且 python 在 Spyder IPython 等中工作正常 但是我无法运行 python 笔记本 内核被创建 它也连接 但它始终显示黑圈忙碌符号 防火墙或防病毒软件没有问题 我尝试过禁用两者 我也无法
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 向 Altair 图表添加背景实心填充

    I like Altair a lot for making graphs in Python As a tribute I wanted to regenerate the Economist graph s in Mistakes we
  • 使用 Python 绘制 2D 核密度估计

    I would like to plot a 2D kernel density estimation I find the seaborn package very useful here However after searching
  • 使用 Python 的 matplotlib 选择在屏幕上显示哪些图形以及将哪些图形保存到文件中

    我想用Python创建不同的图形matplotlib pyplot 然后 我想将其中一些保存到文件中 而另一些则应使用show 命令 然而 show 显示all创建的数字 我可以通过调用来避免这种情况close 创建我不想在屏幕上显示的绘图
  • 从列表指向字典变量

    假设你有一个清单 a 3 4 1 我想用这些信息来指向字典 b 3 4 1 现在 我需要的是一个常规 看到该值后 在 b 的位置内读写一个值 我不喜欢复制变量 我想直接改变变量b的内容 假设b是一个嵌套字典 你可以这样做 reduce di
  • 如何将输入读取为数字?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 Why are x and y下面的代码中使用字符串而不是整数 注意 在Python 2

随机推荐

  • 为什么我的唯一设备 ID 发生了变化?

    我已经使用以下方法大约一个月了 没有任何问题 即使卸载应用程序后 设备 ID 仍保持不变 最近我注意到我的设备 ID 发生了变化 我最近在 Xcode6 上做了很多应用程序的构建 这可能是一个原因吗 我希望我确切地知道它什么时候发生变化 这
  • 在 jupyter 笔记本中内联显示 R ggplots

    我正在尝试运行这里找到的一个简单示例 https www datacamp com community blog jupyter notebook r gs OczVCjA https www datacamp com community
  • C# winform 如何在按钮第二次单击时文本框变为空?

    在一个表单中 我有一个组 Box 其中包含带有 4 个选项卡的选项卡控件 在第二个选项卡中 我有一些文本框 在保存数据之前 我需要验证在这些文本框中输入的输入 请注意我的保存按钮位于最后一个选项卡中 以下测试场景有效 第一个文本框中的输入无
  • 对c中宏SQR的平方感到困惑[重复]

    这个问题在这里已经有答案了 这个问题是在模拟面试中问我的 真的很惊讶地发现尴尬的答案 考虑一个宏 define SQR x x x 示例1 SQR 2 prints 4 示例2 如果给出 SQR 1 1 则它不会求和 1 1 to 2反而
  • 使用 Powershell 在字符串中搜索反斜杠

    我需要搜索字符串中反斜杠的数量以确定一些文件路径参数 我还没有找到一种方法来搜索反斜杠而不让 Powershell 认为它是一个转义字符 regex Matches FilePath count Or a match 这两个都会出现错误 非
  • 我刚刚被收取 134.53 美元的 Google 云托管 DNS 费用 [已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我知道这不是它的地方 但谷歌云绝对没有任何指南来解释为什么我要为他们托管的域名收取那么多费用 我需要了解发生了什么 这样我明天就不会再收费
  • .NET 线程 - HttpWebRequest BeginGetResponse + AutoResetEvent

    我想知道这两种方法中哪种方法更好实施 我需要创建一个持续时间在 200 毫秒到 5 秒之间的 Web 请求 我需要 html 响应才能继续 因此需要在主线程上阻塞 第一种方法 string GetResponse HttpWebReques
  • Rails 3 - 创建复选框(与 _destroy 相反)

    我有一个与 OutputFields 具有 has many 关系的查询模型 在查询控制器的新函数中 我在查询实例中构建了多个输出字段 在我的表单中 我希望每个复选框都确定是否保存对象 检查意味着将此 OutputField 实例保存到数据
  • 如何删除Wamp中的index.php?

    我一直在 XAMPP 中使用 CodeIgniter 重定向到函数 URL 没有问题 例如 功能1 http localhost function1 当我换成WAMP时 我遇到了问题 我无法重定向到功能1 然而 功能1仍可在以下位置访问 h
  • 转换 Pandas Dataframe 类型

    我有一个通过 mysql 调用创建的 pandas dataFrame 它以对象类型返回数据 数据主要是数字 有一些 na 值 如何转换 dataFrame 的类型 以便正确输入数值 浮点数 并将 na 值表示为 numpy NaN 值 在
  • MySQL - 使用可变路径加载数据文件

    我在设置用于将数据放入表中的变量路径时遇到问题 这就是我构建路径的方式 SET path1 CONCAT C Projekte Metrics DXL CSV EXPORT DATA YEAR NOW MONTH NOW DAY NOW B
  • Javascript:在div上执行的scrollBy函数

    我有一个 divoverflow scroll 我想放一个按钮 当你按下它时 内容div卷轴 就像是 function scrollDiv document getElementById d scrollBy 100 100 div p C
  • 如何在没有数学库的情况下在 JavaScript 中截断小数?

    我需要数字只有 2 位小数 如金钱 我使用的是 Number parseFloat Math trunc amount to truncate 100 100 但我不能再支持数学库 在没有数学库并且不四舍五入小数的情况下如何实现这一目标 您
  • HTML 表单似乎同时提交*POST 和 GET?

    这不是诸如此类的问题的重复this https stackoverflow com questions 4726809 send both post and get in a form 而是相反 我有一个通过 jQuery 提交的表单
  • Drupal:需要上传文件吗?

    由于某种原因 当我尝试要求上传文件时 我的表单中断了 这是它的代码 form id upload form form form id array type gt fieldset description gt t This is a uti
  • 将 JSF 2.1 与 JSP 2.0 结合使用时出错:无法从 JAR 文件中读取 TLD

    我尝试在 JSP 2 0 中使用 JSF 2 1 当我添加这个时 我收到以下错误 Unable to read TLD META INF html basic tld from JAR file file home fadhel m2 re
  • Android:您可以通过电话发送/接收数据吗?

    我正在尝试将一些数据传递到我正在拨打的电话上 我有什么办法可以做到这一点吗 我并不真正关心数据的类型 一位就足够了 只要我能识别它并触发特定的操作 发送代码 Intent call new Intent call setAction Int
  • 如何使用 NodeJS 和 Express 为 OpenShift 应用程序配置路由

    我是 OpenShift 新手 我需要一些帮助来在 OpenShift 上配置我的应用程序的路由 这是我尝试部署的 NodeJS Express 应用程序中的端口和 IP 配置 const server port process env O
  • 获取R中另一列值为1的列的中位数

    好的 我有一个类似于此结构的 csv 文件 hashID value flag 98fafd 35 1 fh56w2 25 0 ggjeas 55 1 adfh5d 45 0 基本上我想要做的是获取值列的中位数 但只包含其中的行flag 1
  • 使用 Google Cloud Datastore Python 库时应如何调查内存泄漏?

    我有一个使用 Google 数据存储的网络应用程序 在发出足够的请求后内存不足 我已将范围缩小到数据存储查询 下面提供了最低 PoC 稍长的版本 https gist github com edeca 214d7a7c51f84b9c2dc