假设该分区有4个副本(1个领导者,3个粉丝),并且所有目前都处于同步状态。 min.insync.replicas
设置为3,request.required.acks
设置为全部或-1。
制作人向领导者发送消息,领导者将其附加到其日志中。在那之后,两个副本在他们可以获取此消息之前崩溃。剩下的一个副本成功获取了该消息并附加到它自己的日志中。
领导者在某个超时后,会向生产者发送错误(NotEnoughReplicas,我认为),因为不满足min.insync.replicas条件。
我的问题是:附加到领导者和其中一个副本日志的消息会发生什么?
当崩溃的副本重新上线并且经纪人开始接受并提交新消息(即在日志中转发高水印)时,是否会将其传递给消费者?
答案 0 :(得分:4)
如果没有min.insync.replicas可用且生产者使用ack = all,则消息未提交且消费者将不会收到该消息,即使崩溃的副本返回并再次添加到ISR列表中也是如此。您可以通过以下方式对此进行测试。
使用min.insync.replicas = 2
启动两个代理$ ./bin/kafka-server-start.sh ./config/server-1.properties
$ ./bin/kafka-server-start.sh ./config/server-2.properties
创建一个包含1个分区且RF = 2的主题。确保两个经纪人都在ISR列表中。
$ ./bin/kafka-topics.sh --zookeeper zookeeper-1 --create --topic topic1 --partitions 1 --replication-factor 2
Created topic "topic1".
$ ./bin/kafka-topics.sh --zookeeper zookeeper-1 --describe --topic topic1
Topic:topic1 PartitionCount:1 ReplicationFactor:2 Configs:
Topic: topic1 Partition: 0 Leader: 1 Replicas: 1,2 Isr: 1,2
运行控制台消费者和控制台生产者。确保产品使用ack = -1
$ ./bin/kafka-console-consumer.sh --new-consumer --bootstrap-server kafka-1:9092,kafka-2:9092 --topic topic1
$ ./bin/kafka-console-producer.sh --broker-list kafka-1:9092,kafka-2:9092 --topic topic1 --request-required-acks -1
制作一些消息。消费者应该收到它们。
杀死其中一个经纪人(我杀了一个id为2的经纪人)。检查ISR列表是否减少为一个代理。
$ ./bin/kafka-topics.sh --zookeeper zookeeper-1 --describe --topic topic1
Topic:topic1 PartitionCount:1 ReplicationFactor:2 Configs:
Topic: topic1 Partition: 0 Leader: 1 Replicas: 1,2 Isr: 1
尝试再次制作。在制片人中你应该得到一些
Error: NOT_ENOUGH_REPLICAS
(每次重试一次),最后
Messages are rejected since there are fewer in-sync replicas than required.
消费者不会收到这些消息。
重新启动被杀死的经纪人并尝试重新制作。 消费者将收到这些消息,但不会收到您在其中一个副本发生故障时发送的消息。
答案 1 :(得分:0)
根据我的理解,水印不会在两次失败之前前进 跟随经纪人恢复并赶上了。
有关详细信息,请参阅此博客文章:http://www.confluent.io/blog/hands-free-kafka-replication-a-lesson-in-operational-simplicity/