多处理内存使用和扭曲/ gevents

时间:2013-09-30 10:49:53

标签: memory multiprocessing twisted cpu gevent

所以我...错误...应用程序执行以下操作:

  • 在队列中搜索“工作”
  • 每个服务器产生大约100个工作者(跨3个服务器),每个服务器都在队列中监听
  • 每个工作者基本上做一些网络的东西(ssh,snmp等)(i / o密集),然后搅拌输出(非常cpu密集)

我在multiprocessing下工作,效果很好。然而:每个工作者使用的内存比我想要的多(大约30MB RES,450MB VIRT根据顶部)。所以我有两个问题:

  • 对我来说,确定开销如此之高的最佳方法是什么?我猜COW工作得不太好...我可以使用哪些模块在多处理之前获取所有主线程内存的快照,这样我可以尝试减少初始占用空间?

  • 鉴于我的大多数进程都是cpu绑定的,将代码移植到gevent / twisted会有好处吗?我想利用每个服务器的双十六进制核心。

谢谢!

2 个答案:

答案 0 :(得分:3)

CPython使用引用计数来实现所有Python对象的内存管理。这种方式的工作方式是每个Python对象都表示为一个结构,每个结构中都有一个字段,给出引用计数。每当对该对象进行新的引用时,该字段中的引用计数就会递增。每当放弃对该对象的引用时,该字段中的引用计数递减。一旦引用计数为零,解释器就可以非常确定不再需要Python对象,并且可以释放分配给代表它的结构的内存。

很多东西会改变对象的引用计数。将其传递给函数或将其分配给(本地或全局)变量或对象的属性将增加引用计数(因此将进行许多其他操作)。这些反向递减引用计数:例如,从函数返回会减少所有本地的引用计数。

所有与您的问题相关的原因是,它应该让您知道为什么您从fork()获得的写时复制行为不会帮助您节省一个整体很多记忆。几乎立刻,CPython运行时将访问大部分内存页(内存拷贝的基本单元考虑 - 通常为4kB,可能更大)并用3s或3等3s或4s替换大量2s。这将强制复制进程的大部分内存。

事件驱动系统可以帮助您同时执行许多I / O绑定任务。您仍然可以使用多个进程(至少使用Twisted)来利用您拥有的额外CPU资源。单个事件驱动的进程可以执行所有必要的联网,然后将结果数据交给可以使用其余CPU的工作进程。但是,您可以更精确地了解在这些额外进程中运行的代码。从您的问题来看,我怀疑您认为您的员工不需要已经加载到您的" main"处理。使用Twisted的流程管理API,他们不必在这些事情上花费任何记忆。

答案 1 :(得分:1)

有关Pycon的精彩演讲解释了memory usage in python的主题。它肯定花了半个小时。

最重要的是,要真正了解使用了多少内存,您不应该查看最高输出,而是检查在运行100名工作人员之前和之后有多少内存。