apache-kafka - 开源多区域、一致的至少一次 FIFO 解决方案:专用队列(例如 Kafka)与数据库(例如 Cassandra、RethinkDB)?
问题描述
我一直在寻找一种 FIFO 解决方案,其中生产者和消费者可以部署在不同区域的多个数据中心(例如 >20ms ping)。显然付出了增加延迟的代价,主要目标是透明地处理增加的延迟、延迟峰值、链接故障。
这个理论用例是这样的:
Super Fast Producer --sticky-load-balancing-with-fail-over--> Multi-Region Processors -->
Queue(FIFO based on order established by the producer) --> Multi-Region Consumers with fail-over
消费者不应该同时从同一个“队列”消费,但是,我们在这里不考虑缩放方面。如果复制和故障转移对一个“队列”运行良好,则即使在应用程序级别也可以应用分区,但需要付出相当大的努力。
想法:
- 为了使故障转移正常工作,队列(例如消息、消费者偏移量)必须在数据中心之间进行主动-主动同步复制。我看不到主动-备用异步拓扑如何在不丢失消息或在故障情况下破坏 FIFO 的情况下工作。
- Kafka 拉伸集群将是完美的,尽管它可以跨越多个可用区(<2ms ping 和稳定连接),但大多数人建议不要使用多个区域(>15ms ping,不稳定连接)。
- 具有同步复制功能的 Confluent Platform 5.4 处于预览阶段,我们可以在应用程序级别对消费者进行故障转移,以防本地集群出现故障。由于数据是同步复制的,我们不应该在故障转移期间破坏 FIFO 或丢失消息。为了确保更主动-主动的设置,我们可以在数据中心之间定期轮换消费者(例如,在非高峰时间每天一次或两次)。
- 数据库(如 Cassandra)可以处理跨多个数据中心/区域的一致性。但是,队列用例是一种反模式(将 Cassandra 用作队列)。
- 第一点是关于纯插入/删除工作负载,这将使数据库非常难以删除墓碑。这是对数据库的次优使用,但如果它能够可靠地处理工作负载,那么恕我直言,这不是问题
- 第二点是关于轮询,即使没有数据,消费者也会产生大量的仲裁读取只是为了轮询数据库。恕我直言,Cassandra 将再次可靠地处理这个问题,即使它没有充分利用其功能。
- 使用带有通知的数据库,例如 CouchDB/RethinkDB。CouchDB 的复制是异步的,所以我看不出消费者如何能够拥有一致的队列视图。对于 RethinkDB,我不确定它跨区域的
majority
读写操作有多可靠。
你有没有在生产中部署过这样的“队列”,你会选择哪个?
解决方案
Kafka 支持 2 种模式 Publish-Subscribe 和 Message Queue。有一些地方讨论了不同之处。这里
您所说的问题可以使用Kafka解决。FIFO 队列可以使用主题/分区/键消息来实现。具有相同键的所有消息将属于同一个分区,因此我们可以实现 FIFO 属性。如果您想增加消费吞吐量,您只需要增加每个主题的分区总数并增加消费者数量。
不过,其他队列(例如 RabbitMQ)并不容易。为了负载均衡工作负载,我们必须使用单独的队列,这增加了管理成本。
您可以在生产者端和消费者端实现多种交付语义,例如最多一次、至少一次、精确一次(字面意思)。Kafka 还支持多中心部署。