我目前正在开发一个从外部源接收大量数据的程序。我们开始用Python开发这个程序,但我们不知道如何使Python有效地使用多核CPU。
我已经研究了Python提供的用于启用并行处理的不同选项。使用Parallel Python和标准库,我一直遇到Pickling错误。我从这两个模块得到的唯一消息是“无法腌制”,这种错误信息是我无法工作的。我已经花了很长时间才找到问题并解决它。我支持提交错误以获得更好的Pickle错误,因此将来其他开发人员会有更多运气。但对我来说,是时候继续前进了。
该程序建立了与Web服务的连接,该Web服务提供了持续的消息流。这些消息每分钟可以传输一百万条消息,这个数字将来会更高。收到消息后,需要处理消息并将其保存在适当的数据库中。处理由另一个可在多个服务器上扩展的程序完成。该软件唯一要做的就是接收消息并暂时保存。
或者我应该考虑使用Java来做这件事吗?
主要问题是,处理大量传入网络消息的最佳语言是什么。以及如何在单个服务器上实现适当的多核/并行处理?
过去几周我测试了一个新编写的软件版本,现在我获胜的设置是。
Perl与Anyevent一起处理收到的消息。 使用ZeroMQ的Python接收数据在多个服务器上进行解析。
CPU负载现在减少到5%CPU,每分钟有3000条消息。
答案 0 :(得分:1)
这个问题太模糊了,现在几乎所有的编程语言都支持多种CPU核心,无论你是在Linux还是其他平台上。
响应“Python不支持多核CPU”的说法,大概你指的是全局解释器锁(或GIL),它阻止在任何给定时间执行多个单个Python线程。有很多解决方法,但最常见的是简单地使用Multiprocessing库。这允许你的Python程序充分利用多个核心,但是你使用(重量级)进程而不是(轻量级)线程具有相对较大的缺点(例如进程间通信比线程通信更昂贵,因为发送内容通过队列和/或管道需要序列化/反序列化正在发送的对象。
至于“哪种语言最好”,这完全取决于您的要求,而这些要求在您的问题中明显缺失,因此很难做出特定的推荐。
答案 1 :(得分:1)
我目前正在开发一个从外部源接收大量数据的程序。我们开始用Python开发这个程序,但似乎Python不支持多核CPU的
我认为你必须在这里误解一些东西。
接收数据通常受I / O限制,在这种情况下并行使用多个内核无济于事。 CPython有一个全局解释器锁,可防止多个线程执行Python代码同时。对于接收数据这样的事情,这很少是一种限制,因为几乎所有的时间都花在等待数据到达上,这在1 CPU和8上一样快。
事实上,对于受I / O限制的程序,通常最好不要使用多线程。通常,通过使用异步I / O可以在并发通信中获得更好的性能,所有这些都在一个进程的一个线程中。在Python中实现此方法的一个示例是使用Twisted。当然,在某些时候,CPU密集型部分将开始变得重要,但我提到的线程锁是阻止使用线程在Python中编写的代码的并行化,但这不是我们唯一或最好的并行化选项...
Python可以用于并行程序。所有CPython都会阻止线程并行执行Python代码,这很少是一个限制,特别是因为这几乎总是一个次优的模型开始。 人们可以并且确实一直使用Python进行大规模并行程序,不仅适用于一个CPU上的多个内核,而且对于那么大的作业,它们位于高性能计算中的不同计算机中的数千个CPU上站点。他们通过编写利用多个进程进行并行化的程序来实现这一目标。
在Python中有许多利用多个进程进行并行计算的解决方案。用于高性能计算的传统MPI是MPI;我首选的Python MPI绑定是mpi4py。另一类问题的另一个很好的选择是使用消息队列;所有主要消息队列都有Python绑定。 stdlib多处理模块是一种方便,简单,简单,低质量的流行选项。我还没有在这里列出更多选项,因为这些是最值得注意的选项。
答案 2 :(得分:-1)
如果你不害怕处理新事物,我可以建议Scala。通过添加parallel collections,并行处理变得更加容易。想象一下这样的代码:
myCollection.foreach(element => doSomethingWithElement(element))
使用方法par
,它可以像这样并行化:
myCollection.par.foreach(element => doSomethingWithElement(element))
一切都将并行发生。这只是一个演示,但是,相信我,这可以节省这么多时间:)
答案 3 :(得分:-1)
是。这个名单几乎无穷无尽:
C,C ++,Java,Lisp,Haskell,Erlang,Ruby,C#,Ada,Assembly,Fortran,Go,Groovy,D,......
我可能还没有提到过数百。我提到的许多语言本地支持多线程,你必须找到一个特定的实现或库,但它们完全有能力。