在两个python进程之间共享队列的最有效方法是什么?

2024-05-17 06:57:43 发布

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

我正在python中实现一个syslog服务器。一般的想法是接受消息并将它们转发到RabbitMQ队列以进行进一步处理。

所以有两个部分:

  • P1 syslog侦听器,负责接收消息
  • P2后台办公室负责分析syslog消息,检查它们的格式、完整性、签名并将它们转发到RabbitMQ

显然P2做了主要的工作,并且做了昂贵的操作。

P1 syslog侦听器应:

  • 自治和健壮:我们希望它具有最大的可用性,所以我不想依赖外部组件(例如redis)。它还应该能够接收消息,即使P2处于脱机状态,也可以缓存它们一段时间。
  • 具有最大性能(预期40k消息/秒)
  • 回答syslog客户端(当客户端使用rsyslog RELP协议时,实现ACK)

P1可能使用Tornado实现。

P2处理器只接收P1的消息,处理它们并将它们转发给RabbitMQ,可能使用Torno与RabbitMQ进行异步通信。

所以我需要P1和P2在两个方向上互相交谈。

将P1和P2实现为本机python线程不合适:因为python GIL,只有一个线程同时执行。它违背了绩效目标。

同样,在同一个单线程python进程中在同一个tornado循环中实现P1和P2对P1有性能影响(因为P2中的某些操作可能“有点长”,并使IOLOP忙碌)。

因此P1和P2可能必须是不同的unix进程。

我不希望P2一直可用,所以简单的IPC无法工作。

在P1和P2之间共享Redis队列将完成任务,但P1将依赖于Redis可用。

我尝试使用LMDB作为共享队列,但性能并不好(LMDB的错误用例:读操作和写入一样多,而一些锁的发生与P1和P2是不同的unix进程)。

实现这一切的最佳方法是什么?(除了“不要使用python!”)


Tags: 服务器redis消息客户端lmdb队列进程rabbitmq