spi*_*nus 3 python sockets performance network-programming python-2.7
我发现python网络很慢.
我有一台服务器(用C语言编写).我用我的客户端(python)测试了它.我能达到2MB/s.它让我担心所以我检查了这个:
host1(客户端):
cat some_big_file | nc host2 9999
host2(服务器):
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()
Run Code Online (Sandbox Code Playgroud)
接下来的措施是发送nc (host1)给gserver (host2).
host1:cat some_big_file | nc host2 9999
host2:./gserver.py | pv > /dev/null
输出host2:[ 101MB/s].不错.
但是,当我使用我的python客户端时,它很慢.我把客户gevent换成了.我试过几个greenlets.1,10,100,1000 - 它没有太大的帮助,我可以20MB/s通过一个python进程或~30MB/s2,3,4,5个单独的python进程,这是一些东西,但仍然不是那么好).仍然很慢.我重写了客户端是愚蠢的,像这样:
#!/usr/bin/env python
import sys
import socket
c = socket.create_connection((sys.argv[1], sys.argv[2]))
while 1:
c.send('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n')
Run Code Online (Sandbox Code Playgroud)
通过这种方法,我可以达到10MB/s.我也尝试了将整个大2GB文件读取到内存并发送它的方法,类似的结果.
我还尝试将python脚本作为单独的进程运行(使用tmux).如果我使用了1个我可以达到的过程10MB/s,2个过程20MB/s,3 个过程,23MB/s4个,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')
Run Code Online (Sandbox Code Playgroud)
通过一次发送更多数据,我可以达到超过1GB/s的速度.
如果您想最大化吞吐量,您应该在一次调用中发送尽可能多的数据send.一种简单的方法是在发送最终结果之前连接几个字符串.如果你这样做,请记住python字符串是不可变的,因此连续的字符串连接(使用大字符串)很慢.你会想要用一个bytearray代替.
| 归档时间: |
|
| 查看次数: |
8247 次 |
| 最近记录: |