kar*_*sch 11 python asynchronous heroku redis redistogo
我们目前正在使用我们的Heroku托管的Python应用程序使用Redis.
我们将Redis与python-rq一起用作任务队列,以延迟执行一些时间紧迫的任务.任务是从PostgreSQL数据库中检索一些数据并将结果写回给它 - 因此Redis实例中根本没有保存有价值的数据.我们注意到,根据执行的作业数量,Redis正在消耗越来越多的内存(增长@ 10 MB /小时).CLI上的FLUSHDB命令修复此问题(将其降至约700kB的RAM),直到RAM再次满为止.
根据我们的(未更改的标准)设置,作业结果保持500秒.随着时间的推移,一些作业当然会失败,并且它们会被移动到失败的队列中.
很抱歉这些漂亮的noobish问题,但我对排队的话题不熟悉,经过2天以上的研究,我已经达到了一个我不知道下一步要做的事情.谢谢,KH
kar*_*sch 14
经过两天的游戏,我发现了问题.我想与您分享这些以及有用的工具:
核心问题
实际问题是我们忽略了在将对象保存到PostgreSQL数据库之前将其转换为字符串.如果没有这个强制转换,字符串表示最终会出现在DB中(由于__str__()相应对象的功能正好返回我们想要的表示); 然而,对Redis来说,整个对象都被传递了.将其传递给Redis后,相关任务因UnpickleError异常而崩溃.这消耗了5 MB的RAM,在崩溃后没有释放.
其他行动
为了进一步减少内存占用,我们实现了以下补充操作(请注意,我们将所有内容保存到单独的数据库中,因此我们的应用程序中根本不会使用Redis保存的结果):
enqueue_call([...] result_ttl=0)black_hole- 获取所有异常并返回False.这可以防止Redis将任务移动到仍然使用一点内存的失败队列.事先通过电子邮件向我们发送例外情况以跟踪它们.一路上有用的工具:
我们刚刚合作过redis-cli.
redis-cli info | grep used_memory_human - >显示当前的内存使用情况.理想的是在执行任务之前和之后比较内存占用.redis-cli keys '*' - >显示存在的所有当前键.这个概述让我明白了一些任务即使应该被删除也不会被删除(如上所述,它们因UnpickleError而崩溃,因此没有被删除).redis-cli monitor - >显示Redis中发生的事情的实时概述.这有助于我发现来回移动的物体太大了.redis-cli debug object <key> - >显示密钥值的转储.redis-cli hgetall <key> - >显示了一个更可读的密钥值转储(特别适用于将Redis纯粹用作任务队列的特定用例,因为看起来这些任务是由python-rq以这种格式创建的.此外,我可以回答上面发布的一些问题:
从文档我知道500秒TTL意味着一个密钥然后"过期",但没有真正删除.此时密钥是否还消耗内存?我可以以某种方式改变这种行为吗?
实际上,它们被删除了,就像文档所暗示的那样.
它是否与失败的队列有关(显然没有TTL附加到作业,这意味着(我认为)这些是永久保存的)?
令人惊讶的是,Redis本身崩溃的工作没有转移到失败的队列,他们只是"放弃",这意味着价值仍然存在,但RQ并不关心它与失败工作的正常方式.
相关文件
| 归档时间: |
|
| 查看次数: |
2014 次 |
| 最近记录: |