使用Redis实现JMS/AMQP消息模式

19
这个问题是因为我看到一些提及(例如this)使用消息传递软件,如ZeroMQ与Redis,但我一直听说Redis本身就是一个消息系统。因此,如果Redis与其他消息系统一起使用,是否意味着Redis本身作为消息系统时存在一些严重缺陷?
虽然我清楚Redis用于缓存和发布/订阅的用途,但不清楚Redis是否可以代替完整的消息系统,如JMS、AMQP或ZeroMQ。
不考虑符合标准的方面,仅关注功能/特性,Redis是否支持消息系统所需的所有消息模式/模型?
我所说的消息模式是:
  1. RPC/请求-响应(使用ActiveMQ/JMS的example和使用RabbitMQ/AMQP的another
  2. 管道/工作队列(每个消息只消费一次或最多一次)
  3. 广播(所有订阅频道的人)
  4. 组播(基于消费者选择器在服务器上过滤消息)
  5. 还有其他的消息模式吗?

如果有,那么Redis似乎可以同时解决两个(可能更多)方面:缓存和消息传递。

我从一个Java / Java EE服务器支持的Web应用程序的角度来看待这个问题。我不是从概念验证的角度来看待这个问题,而是从大规模软件开发的角度来看待这个问题。

Edit1:
用户:791406提出了一个有效的问题:

"谁在乎redis是否支持这些模式; redis是否能满足您的SLA和QoS需求?"

我认为将此详细信息作为问题的一部分而不是在评论部分中提供更好。

我的当前需求与SLA和QOS无关,而更多地涉及选择一种工具(消息传递),即使在未来我的要求(合理地)增长时也可以使用。 我首先从简单的要求开始,我们都知道要求往往会增长。 而且,我不是在寻找一个可以完成所有工作的工具。 我只想知道Redis是否能够满足像ActiveMQ/RabbitMQ这样的消息传递系统通常期望的要求。当然,如果我的SLA/QOS需求极端/偏离常规,我需要获取一个特殊的工具来满足这些要求。例如:在某些情况下,由于特定的SLA要求,可能会选择ZeroMQ而不是RabbitMQ。我不是在谈论这些特殊要求。我关注的是平均企业需求。

基于我的一点了解,我担心Redis虽然可以用作今天我的消息传递需求的基本工具,但它可能不是未来真正消息传递工作的正确工具。我有使用ActiveMQ/RabbitMQ等消息传递系统的经验,知道它们可以用于简单到(合理地)复杂的消息传递需求。

编辑2:

  1. Redis的网站提到"Redis经常被用作消息服务器", 但如何实现消息传递模式并不清楚。

  2. Salvatore sanfilippo提到Redis用户倾向于将其用作数据库,作为消息总线或缓存。它在“消息总线”方面的服务程度未明确。

  3. 当我试图找出JMS所不支持的Redis消息需求时,我发现了一些Redis支持但JMS不支持的功能:模式匹配订阅,即客户端可以订阅符合给定模式的通道名称以接收所有发送到该模式匹配的通道的消息。

结论:

我决定使用JMS来满足我的消息需求,并使用Redis进行缓存。

1个回答

18
你的需求是什么?
在选择消息平台之前,我认为你应该问自己的问题是:“我需要什么样的消息质量来支持我的应用程序?”。不要只关注redis是否支持这些模式,而是要考虑redis是否能满足你的SLA和QoS需求。首先专注于这方面,然后再根据这个评估做出技术决策。
话虽如此,我会提供我的建议,帮助你做出决策...
高可靠性/持久性/耐久性的消息
让我们看一个极端情况:比如说你正在构建一个交易或金融应用程序。这种应用程序要求严格的SLA,其中消息持久性、可靠性、确切的一次性传递和耐久性至关重要。对于这种情况,将redis作为消息骨干可能是一个糟糕的选择,有很多原因...
- 消息重新传送(当情况恶化时) - 当redis崩溃时,消息存储复制 - 消息事务(redis无法执行XA) - 生产者/订阅者容错和断开连接的弹性 - 消息顺序排序 - 在代理关闭时发送消息(存储和转发) - 单线程redis可能成为瓶颈
如果你的系统有严格的SLA,那么这些问题中的一些或全部肯定会出现,那么你将如何处理这些限制?你可以为redis实现自定义代码来解决一些问题,但是当成熟的消息平台(如ActiveMq、WebsphereMQ和WebLogic JMS)提供持久性、可靠性和容错能力时,为什么要麻烦自己呢?根据你所说的,你在使用Java/Java EE堆栈,因此你可以使用某些最强大的消息框架,这些框架可以是开源或商业化的。如果你正在进行金融交易,那么你需要考虑这些选项。
高性能/大型分布式系统消息
...... (未完待续)如果您正在构建一个社交网络或游戏平台,希望性能优于可靠性,那么ZeroMq可能是一个很好的选择。它是一个包含类似消息传递的API的套接字通信库。它是去中心化的(没有代理),非常快速,并且高度弹性和容错。如果您需要执行像使用代理中介进行N对N发布/订阅、流控制、消息持久性或点对点同步等操作,则ZeroMq提供必要的设施和代码示例,可使用最少的代码完成所有这些操作,同时避免从零开始构建解决方案。它是用C编写的,但几乎为每种流行语言提供了客户端库。

希望这可以帮助到您...


1
+1 for "Having said that, I'll offer my input on how you can make that decision"!那真的很有帮助。根据您的评论,我会在我的问题中添加更多细节。 - 2020
在我看来,你在“高可靠性/持久性/耐用性消息传递”下提到的所有要点都是一个真正的消息系统应该支持的要求。用户是否启用该功能是另一个问题。今天我可能会选择非持久性消息。明天我可能希望在某些队列上使用持久性消息。我不想被迫使用不同的消息解决方案。这就是为什么我正在探索Redis在消息传递方面的能力的原因。 - 2020
准确地说,那就是我的观点。所有这些功能都是成熟的消息平台的标准提供,但不适用于redis,因此如果您需要可靠性、持久性、耐久性等等,redis可能不是最佳选择,但这又取决于您的需求。顺便说一下:没有所谓的“平均”企业要求,所有的要求,无论大小,都是具体的 :-) - raffian
明白了!谢谢!我目前正在查阅参考资料,以确定您提到的“无法使用Redis实现”的点是否属实。一旦我确认是这种情况,我会接受您的答案。如果您有任何相关的参考资料,并且可以发送给我,那将有助于加快进度。 - 2020
@brainOverflow 并非完全如此;请在这里阅读有关MULTI/EXEC的更多信息:http://redis.io/topics/transactions。如果在`EXEC`之后某些命令失败,则有些情况下以前的命令仍然会被提交,而不会回滚;这是故意设计的,因为Redis更注重性能而非可靠性。 - raffian
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接