我正在为通过 1Gb 以太网连接到 PC 的科学测量设备开发客户端。
测试 PC CPU 为 i5-460M (2.53x2) + 8Gb 内存。操作系统 Win 7 x64(不能更改为 linux)。
Python 2.7.6 x86
设备以 UDP 数据包的形式发送数据,格式如下:
uint meas_id;
uint part_id;
ubyte data[1428];
数据速率为 1Gb/s(大约每秒 70,000 个数据包)。
我需要在磁盘上接收和转储数据(大约 10 分钟)以供将来处理,但面临两个问题:数据包丢失(在线程之间传输数据时)和 HDD 使用情况。
目前的结构是两个工作流程:
使用原始 python 套接字,我可以在我的机器上接收大约 110k pps 而不会丢包,只需
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1024*1024*256) # real buffer is less
s.bind(("0.0.0.0", 8201))
while is_active:
...
data = s.recv(1536)
但是有些数据包会被丢弃。当我尝试使用如下代码将数据发送到另一个进程时:
data_buf = []
while 1:
d = s.recv(1536)
data_buf.append(d)
if len(data_buf) == CHUNK_SIZE:
xchg_queue.put(data_buf)
data_buf = []
管道更快,但正如我所见 - 如果管道中有一些对象,pipe.send() 可能会锁定。
是否有更快的方法在进程之间发送数据?
我尝试使用 MySQL 作为存储,禁用索引并启用延迟写入,但每秒节省大约 30-35k 个数据包。
当每个文件保存 1000 - 100000 个数据包时,使用 cPickle 可以获得 40-50k pps。
是否有更快的方法来保存数据? 可能是 PyTables(HDF5) 或一些快速的 NoSQL DB(类似 redis)。
另外我不确定这个客户端是否可以在 python 中使用 - 可能有必要用纯 C 重写模块。
或者python套接字上可能有快速包装器(如gevent)?
希望你会有所帮助。
最佳答案
如果您只需要保存数据以供将来处理,我不会使用 python 和数据库的开销,而是使用 tshark 或 windump 以尽可能快的速度将数据保存到单个文件中,并且开销最少。这也是 HDD 最便宜的,因为您只附加在文件中。稍后您可以使用带有 winpcap 或其他工具的 python 来处理数据,而不会丢失任何数据并以您需要的格式写入它们。
关于python - 在 python 中处理和保存 UDP 流的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23660631/