如何加速python网络?

2024-05-21 12:54:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我发现python网络速度慢。

我有一个服务器(用C写的)。我用我的客户机(python)测试了它。 我可以到达2MB/s。我很担心,所以我检查了一下:

主机1(客户端): cat some_big_file | nc host2 9999

主机2(服务器): nc -l 0.0.0.0 9999 | pv > /dev/null

我达到了120MB/s(1Gb)的速度。

服务器不是瓶颈,我们在生产中使用它,它可以处理更多的问题。但为了确保我复制了简单的pythongevent服务器进行测试。看起来是这样的:

  #!/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)

主机1:cat some_big_file | nc host2 9999 主机2:./gserver.py | pv > /dev/null

host2[ 101MB/s]上的输出。不错。

但是,当我使用python客户端时,它仍然很慢。我把客户换成了gevent。我试过几次绿叶菜。1,10,100,1000-这并没有太大的帮助,我可以用一个python进程达到20MB/s,或者~30MB/s对于2,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')

用这种方法我可以达到10MB/s。我还尝试了将整个大2GB文件读入内存并发送给内存的方法,结果类似。

我还尝试将python脚本作为单独的进程运行(使用tmux)。如果我使用1个进程,我可以达到10MB/s,2个进程20MB/s,3个进程23MB/s,4,5,6个进程没有任何改变(用gevent版本和简单版本测试)。

详细信息: Python-2.7.3 Debian 7-标准安装 机器是AWS实例,客户机是c1.medium,服务器是c3.xlarge。 nc和iperf在两台机器之间测量到1Gb/s。

问题:

  1. 为什么我可以使用python服务器(gevent服务器)快速接收大量数据,但即使C程序可以,也不能以同样的速度发送。
  2. 为什么两倍的进程不能将发送速度提高到极限,只会增加到某个值。
  3. 有没有什么方法可以使用套接字在python中快速发送数据?

Tags: 方法import服务器客户端客户机server进程sys
1条回答
网友
1楼 · 发布于 2024-05-21 12:54:40

问题不在于网络速度太慢——python函数调用有很多开销。如果您多次调用connection.send,您将在函数调用上浪费大量的CPU时间。

在我的电脑上,你的程序平均速度约为35 MB/s。做一个简单的修改,我得到450 MB/s:

#...
c.send('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'*10+'\n')

通过一次发送更多的数据,我可以达到超过1GB/s的速度。

如果您想最大化吞吐量,您应该在对send的单个调用中发送尽可能多的数据。一种简单的方法是在发送最终结果之前连接几个字符串。如果这样做,请记住python字符串是不可变的,因此连续的字符串连接(使用大字符串)速度很慢。您需要使用bytearray来代替。

相关问题 更多 >