[英]How to speed up python networking?
我发现python网络很慢 。
我有一台服务器(用C语言编写)。 我用我的客户端(python)测试了它。 我可以达到2MB/s
。 它让我担心所以我检查了这个:
host1(client): cat some_big_file | nc host2 9999
cat some_big_file | nc host2 9999
host2(server): nc -l 0.0.0.0 9999 | pv > /dev/null
nc -l 0.0.0.0 9999 | pv > /dev/null
我达到了大约120MB / s(1Gb)的速度。
服务器不是瓶颈,我们在生产中使用它,它可以处理更多。 但是要确保我复制了简单的python gevent
服务器进行测试。 它看起来像这样:
#!/usr/bin/env python
from gevent.server import StreamServer
from gevent.pool import Pool
def handle(socket, address):
while True:
print socket.recv(1024)
pool = Pool(20000)
server = StreamServer(('0.0.0.0', 9999), handle, spawn=pool)
server.serve_forever()
接下来的措施是从nc (host1)
发送到gserver (host2)
。
host1: cat some_big_file | nc host2 9999
cat some_big_file | nc host2 9999
host2: ./gserver.py | pv > /dev/null
./gserver.py | pv > /dev/null
host2
上的输出: [ 101MB/s]
。 不错。
但是,当我使用我的python客户端时,它很慢。 我把客户gevent
了gevent。我尝试过几个greenlets。 1,10,100,1000 - 它没有太多帮助,我可以通过一个python进程达到20MB/s
或者对于~30MB/s
个单独的python进程达到~30MB/s
,这是一些东西,但仍然不是这样好)。 仍然很慢。 我重写了客户端是愚蠢的,像这样:
#!/usr/bin/env python
import sys
import socket
c = socket.create_connection((sys.argv[1], sys.argv[2]))
while 1:
c.send('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n')
通过这种方法,我可以达到10MB/s
。 我也尝试了将整个大2GB
文件读取到内存并发送它的方法,类似的结果。
我还尝试将python脚本作为单独的进程运行(使用tmux
)。 如果我使用1个进程,我可以达到10MB/s
,2个进程20MB/s
,3个23MB 23MB/s
,4个,5个,6个进程没有改变任何东西(使用gevent
版本和简单版本进行测试)。
详细信息:Python-2.7.3 Debian 7 - 标准安装机器是AWS实例,客户端是c1.medium,服务器是c3.xlarge。 nc和iperf在机器之间测得1Gb / s。
问题:
问题不在于网络速度慢 - python函数调用有很多开销。 如果你多次调用connection.send
,你将在函数调用上浪费大量的CPU时间。
在我的计算机上,您的程序平均大约35 MB / s。 做一个简单的修改,我得到450 MB / s:
#...
c.send('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'*10+'\n')
通过一次发送更多数据,我可以达到超过1GB / s的速度。
如果要最大化吞吐量,则应在一次调用中send
尽可能多的数据。 一种简单的方法是在发送最终结果之前连接几个字符串。 如果你这样做,请记住python字符串是不可变的,因此连续的字符串连接(使用大字符串)很慢。 你会想要使用bytearray
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.