redis - ServiceStack Redis Mq:最终一致性是个问题吗?
问题描述
我正在考虑将单体应用程序转变为面向微服务的应用程序,这样做需要一个健壮的消息传递系统来进行进程间通信。这个想法是让微服务进程在 HA 服务器集群上运行,将要处理的请求添加到所有应用程序都可以访问的消息队列中。我正在考虑将 Redis 用作瞬态数据的 KV 存储,也用作使用 .Net 的 ServiceStack 框架的消息代理,但我担心 Redis 应用的最终一致性概念会使请求的处理不可靠。这就是我理解 Redis 在 Mq 方面的作用:
- 客户端 1 向节点 1 上的队列发布请求
- 节点 1 将使用 pub/sub 通知该队列上的所有侦听器请求的存在,并将请求异步推送到节点 2。
- 节点 1 上的侦听器将从节点拉取请求,其中只有 1 个会按原样获取它。请求删除的更新异步发送到节点 2,但需要一些时间才能到达。
- 初始请求由节点 2 接收(假设 RTT 有一点延迟),它将继续并通知使用 pub/sub 连接到它的侦听器。在从节点 1 接收到关于从队列中删除请求的更新之前,节点 2 上的侦听器也可以拉取请求。结果是两个监听器最终处理了同一个请求,这将对我们的系统造成严重破坏。
Redis 或 ServiceStack Redis Mq 的实现中是否有任何东西可以防止所描述的场景发生?还是我误解了关于 Redis 中的复制的其他内容?或者我应该放弃 Mq 的 Redis/SS 方法并使用 RabbitMQ 之类的东西,而不是我理解为符合 ACID 的东西?
解决方案
同一条消息不可能在Redis MQ中处理两次,因为消息工作者将消息从Redis 列表支持的 MQ中弹出,并且所有 Redis 操作都是原子的,因此其他消息工作者将无法访问已从列表。
ServiceStack.Redis(Redis MQ 使用)仅支持用于 HA 的 Redis Sentinel,尽管 Redis 支持多个副本,但它们仅包含主数据集的只读视图,因此所有写入操作(如列表添加/删除操作)只能在单个主服务器上发生实例。
与使用 Redis MQ 而不是像 Rabbit MQ 这样的特定用途 MQ 的一个显着区别是 Redis 不支持 ACK,因此如果从 MQ 弹出消息的消息工作进程崩溃,那么它的消息就会丢失,而不是 Rabbit MQ如果未确认消息的状态连接断开,则 RabbitMQ 服务器将消息恢复回 MQ。
推荐阅读
- c# - 关于 C、C# 和 Unity 编译时间
- javascript - 我有一个对象数组。我想随机输出值总和等于八的对象
- python - 在python中使用硒的ElementNotInteractableException
- svg - 为什么在 SVG feComposite 过滤器中用作源的文本大小受 svg 元素大小的影响?
- amazon-web-services - 定期在 AWS RDS 中归档特定表的数据
- google-apps-script - 使用受保护的工作表和范围“仅查看”模式
- python - 我附上了我的代码。请检查它并告诉我错误的原因。解释一下?
- python - python def 方法应该有“self”作为第一个参数
- python-3.x - 如何更改 Visual Studio 代码工具栏的颜色?
- c# - 检查对象是从哪个类创建的