pyzmq----ProcessDevice、ProcessProxy、monitored_queue 性能比较
说明
ProcessDevice、ProcessProxy、monitored_queue 在队列转发性能比较,
测试数据:单进程顺序 50w条信息
客户端脚本
- 顺序PUB发送50w条数据
# 测试数据发送脚本
import zmq
import time
state_url = 'tcp://127.0.0.1:5607'
log_url = 'tcp://127.0.0.1:5606'
def log_client():
topic = b'logTestV1'
ctx = zmq.Context.instance()
state_socket = ctx.socket(zmq.REQ)
state_socket.connect(state_url)
state_socket.send_multipart([b'INIT', topic])
resp = state_socket.recv_multipart()
print(resp)
print('准备写入日志')
log_pub = ctx.socket(zmq.PUB)
log_pub.hwm = 30000
log_pub.connect(log_url)
time.sleep(1)
for i in range(500000):
print(i)
log_pub.send_multipart([topic, f'日志写入测试日志写入测试:{i}\n'.encode('utf-8')])
print(f'{topic}发送完毕')
time.sleep(60 * 2)
log_client()
服务端转发部分代码
- ProcessDevice 、ProcessProxy 涉及代码
- ProcessDevice 、ProcessProxy 都是在新的进程中启动
def log_queue_device(self):
"""
转发进程队列设备
:return:
"""
if self.concurrency == 'process':
# pd = ProcessDevice(zmq.QUEUE, zmq.SUB, zmq.PUB)
pd = ProcessProxy(zmq.SUB, zmq.PUB)
else:
pd = ThreadDevice(zmq.QUEUE, zmq.SUB, zmq.PUB)
pd.bind_in(self.in_url)
pd.bind_out(self.out_url)
pd.setsockopt_in(zmq.SUBSCRIBE, b'')
pd.setsockopt_in(zmq.RCVHWM, RCV_HWM_VALUE)
pd.setsockopt_out(zmq.SNDHWM, SND_HWM_VALUE)
return pd
- monitored_queue 函数使用,该函数用Cython写的,因此循环不涉及Python。理论上性能会比较好。
- log_monitored_queue 通过 multiprocessing.Process 启动,在一个新的进程中运行
from zmq.devices import monitored_queue
def log_monitored_queue(in_url, out_url, RCV_HWM_VALUE, SND_HWM_VALUE):
ctx = zmq.Context.instance()
ins = ctx.socket(zmq.SUB)
ins.setsockopt(zmq.SUBSCRIBE, b'')
ins.setsockopt(zmq.RCVHWM, RCV_HWM_VALUE)
ins.bind(in_url)
outs = ctx.socket(zmq.PUB)
outs.setsockopt(zmq.SNDHWM, SND_HWM_VALUE)
outs.bind(out_url)
mons = ctx.socket(zmq.PUB)
mons.bind('inproc://MonQueue')
monitored_queue(ins, outs, mons)
结论
三种模式,性能差不多,我测试项目是一个分布式日志项目,测试环境是我个人笔记本电脑,结果仅供参考
模式 | 耗时 |
---|---|
ProcessDevice | 1分22秒 |
ProcessProxy | 1分16秒 |
monitored_queue | 1分22秒 |