使用消息队列和协调服务设计系统

时间:2016-04-26 07:52:25

标签: apache-kafka apache-zookeeper microservices distributed-system

我是Designing系统的新手,对消息队列和协调服务(zookeeper)有一些疑问。

如果有人能澄清这些概念,那就太棒了: -

我对我正在设计的系统中的MQ的理解: -

我将有生产者服务,它将创建消息并添加到MQ。消费者将使用此消息并执行适当的操作。一旦消费者确认消息处理完成; MQ会将偏移量移动到下一个。我不希望错过我的邮件,因此我必须确保邮件已成功使用。此外,我试图让这个系统只消耗一次消息(尝试尽可能接近)。

现在基于这种理解我有以下问题: -

1)如果我希望我的生产者和消费者在同一个DC中运行多个实例(用于高可用性),那么我是否需要将生产者和消费者作为单独的Zookeeper服务?我所有不同的服务(在微服务世界中)是否需要单独的zookeeper服务器/实例或同一个实例才能解决这个问题?

2)当消费者使用消息时,它将在消费之后确认MQ(完成处理并采取任何所需的操作)。我试图了解这对于每秒会有数千个请求的系统来说会更快。如果我们读取更多消息或者等待ACK直到处理,那么在消费者失败的情况下,这些消息将被丢失,因为它们从未成功处理过。我知道有更多的消费者会让它同时工作,但我不清楚这个概念是如何运作的。有人可以解释一下,消费和配置组件之间的交互的正确方法是什么,以便优化以及持久,高可用,可靠,并且只关闭一次模型。

编辑:我打算在系统中使用Java,Zookeeper,Kafka,Cassandra。

1 个答案:

答案 0 :(得分:0)

与任何邮件系统一样,邮件队列可以在两种基本模式下工作:至少一次传递,或者最多一次传递。两者都争取一次交付,但我们在这里谈论边缘案例。你将不得不选择其中一个。如果生成者和使用者(包括生产者 - 生产者和消费者 - 消费者)之间的所有通信都通过消息队列,那么只有消息队列需要一个zookeeper集群。通过单个系统集中所有消息是实现此目的的首选方式。

你的目标只是一次交付,因为两次做同样的工作是浪费,或者如果你做了两次相同的事情,一切都会烧到地上?

如果是前者,建立一些简单的东西。消息队列本身可以跟踪这一点,因为一旦其中一个回复结果,它将停止要求新消费者使用该任务,或者,如果存储必须更加永久,请使用redis或couchbase或cassandra或一些简单的键/值存储来存储已成功完成的事情。记下您发出的请求,但没有收到内存中的答复。存储"此操作已完成"请注意数据库。

如果是后者,那么你将很难设计这个系统。您需要能够判断进程是否崩溃,或者是否只需要比平时更长的时间。你还需要继续它离开的地方,可能是再做一遍的工作。如果更新类似于递增十个不同的计数器,则再次执行更新可能会使某些计数器增加两次。