大内存 Python 后台作业
Large memory Python background jobs
我是 运行 一个将数据加载到 MongoDB 数据库的 Flask 服务器。由于数据量大,耗时长,所以想通过后台作业来完成。
我使用 Redis 作为消息代理,使用 Python-rq 来实现作业队列。所有代码都在 Heroku 上运行。
据我了解,python-rq 使用 pickle 序列化要执行的函数,包括参数,并将其与其他值一起添加到 Redis 哈希值中。
由于参数包含要保存到数据库的信息,因此它非常大(~50MB),当将其序列化并保存到 Redis 时,不仅需要花费大量时间,而且还消耗了大量内存。 Heroku 上的 Redis 计划仅 100MB 的费用为 30 美元 p/m。事实上,我经常遇到 OOM 错误,例如:
OOM command not allowed when used memory > 'maxmemory'.
我有两个问题:
- python-rq 是否非常适合此任务,还是 Celery 的 JSON 序列化更合适?
- 有没有办法不序列化参数而是引用它?
非常感谢您提出最佳解决方案!
原来有效的解决方案是将数据保存到Amazon S3存储,然后将URI传递给后台任务。
鉴于您在评论中提到您的任务输入是一个很大的键值对列表,我将推荐以下内容:
- 在文件中加载 key/value 对列表。
- 将文件上传到 Amazon S3。
- 获取生成的文件 URL,并将其传递到您的 RQ 任务中。
- 在您的工作任务中,下载文件。
- 逐行解析文件,将文件插入Mongo。
使用上述方法,您将能够:
- 快速将您的任务分解为可管理的块。
- 将这些压缩的小文件快速上传到 S3(使用 gzip)。
- 需要通过网络传输的数据更少,从而大大减少了您的 Redis 使用量。
- 将 S3 配置为在一定时间后自动删除您的文件(有 S3 设置:例如,您可以让它在 1 天后自动删除)。
- 通过一次处理一行文件,大大减少工作人员的内存消耗。
对于像您正在做的这样的用例,与通过您的排队系统发送这些项目相比,这将更快并且需要更少的开销。
希望对您有所帮助!
我是 运行 一个将数据加载到 MongoDB 数据库的 Flask 服务器。由于数据量大,耗时长,所以想通过后台作业来完成。
我使用 Redis 作为消息代理,使用 Python-rq 来实现作业队列。所有代码都在 Heroku 上运行。
据我了解,python-rq 使用 pickle 序列化要执行的函数,包括参数,并将其与其他值一起添加到 Redis 哈希值中。
由于参数包含要保存到数据库的信息,因此它非常大(~50MB),当将其序列化并保存到 Redis 时,不仅需要花费大量时间,而且还消耗了大量内存。 Heroku 上的 Redis 计划仅 100MB 的费用为 30 美元 p/m。事实上,我经常遇到 OOM 错误,例如:
OOM command not allowed when used memory > 'maxmemory'.
我有两个问题:
- python-rq 是否非常适合此任务,还是 Celery 的 JSON 序列化更合适?
- 有没有办法不序列化参数而是引用它?
非常感谢您提出最佳解决方案!
原来有效的解决方案是将数据保存到Amazon S3存储,然后将URI传递给后台任务。
鉴于您在评论中提到您的任务输入是一个很大的键值对列表,我将推荐以下内容:
- 在文件中加载 key/value 对列表。
- 将文件上传到 Amazon S3。
- 获取生成的文件 URL,并将其传递到您的 RQ 任务中。
- 在您的工作任务中,下载文件。
- 逐行解析文件,将文件插入Mongo。
使用上述方法,您将能够:
- 快速将您的任务分解为可管理的块。
- 将这些压缩的小文件快速上传到 S3(使用 gzip)。
- 需要通过网络传输的数据更少,从而大大减少了您的 Redis 使用量。
- 将 S3 配置为在一定时间后自动删除您的文件(有 S3 设置:例如,您可以让它在 1 天后自动删除)。
- 通过一次处理一行文件,大大减少工作人员的内存消耗。
对于像您正在做的这样的用例,与通过您的排队系统发送这些项目相比,这将更快并且需要更少的开销。
希望对您有所帮助!