我正在为通过1Gb以太网连接到PC的科学测量设备开发客户端。
测试PC CPU是i5-460M(2.53x2)+ 8Gb内存。 OS 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数据包。
使用cPickle时,每个文件保存1000 - 100000个数据包时得到40-50k pps。
有更快的方法来保存数据吗?可能是PyTables(HDF5)或一些快速的NoSQL DB(类似redis)。
此外,我不确定这个客户端是否可以在python中使用 - 可能需要在纯C中重写模块。
或者可能是python套接字上有快速包装器(如gevent)?
希望你能提供帮助。
答案 0 :(得分:0)
如果您只需要保存数据以备将来处理,我就不会使用python和数据库的开销,而只需使用tshark或windump尽可能快地保存数据,并将最少的开销存入单个文件。这也是HDD最便宜的,因为你只附加在文件中。稍后你可以使用python和winpcap或其他工具来处理数据,而不会丢失任何数据,并以你需要的格式写出来。