ServiceStack Redis Mq:最终一致性是一个问题吗?

时间:2020-05-29 01:55:09

标签: redis servicestack.redis

我正在考虑将整体应用程序变成面向微服务的应用程序,这样做将需要一个健壮的消息传递系统来进行进程间通信。这个想法是使微服务进程在用于HA的服务器集群上运行,将要处理的请求添加到所有应用程序都可以访问的消息队列中。我正在考虑将Redis既用作瞬态数据的KV存储,又用作使用.Net ServiceStack框架的消息代理,但是我担心Redis所采用的最终一致性的概念会使处理请求变得不可靠。这就是我对Redis关于Mq起作用的理解:

  1. 客户端1将请求发布到节点1上的队列
  2. 节点1将使用pub / sub通知存在该队列的所有侦听器 请求,并且还将异步将请求推送到节点2。
  3. 节点1上的侦听器将从该节点拉出请求,只有其中1个侦听器将应有的请求。删除请求的更新会异步发送到节点2,但要花一些时间才能到达。
  4. 节点2接收到初始请求(假设RTT有点延迟),节点2将继续发送该请求,并使用pub / sub通知与其连接的侦听器。在从节点1接收到有关从队列中删除请求的更新之前,节点2上的侦听器也可以拉出该请求。结果是两个侦听器最终处理了相同的请求,这会对我们的系统造成破坏。

Redis或ServiceStack Redis Mq的实现中是否有任何东西可以防止上述情况的发生?还是我对Redis中的复制有误解?还是应该放弃Mq的Redis / SS方法,而是使用RabbitMQ之类的东西来代替我理解为符合ACID的东西?

1 个答案:

答案 0 :(得分:1)

同一条消息无法在Redis MQ中处理两次,因为消息工作程序将消息从Redis List支持的MQ弹出,并且所有Redis操作都是原子操作,因此没有其他消息工作程序可以访问从列表中删除的邮件。

ServiceStack.Redis(Redis MQ使用的)仅支持Redis Sentinel for HA,尽管Redis支持multiple replicas,但它们仅包含主数据集的只读视图,因此所有写操作(如列表添加/删除操作)只能在单个主实例上发生。

与使用Redis MQ代替特定用途的MQ(例如Rabbit MQ)相比,一个显着的区别是Redis不支持ACK,因此,如果从MQ弹出消息的消息工作进程崩溃了,那么它的消息就会丢失,而不是Rabbit MQ,如果Un Ack'd消息的状态连接死亡,则该消息将由RabbitMQ服务器恢复回MQ。

相关问题