在zookeeper重启后,Kafka集群丢失消息

时间:2018-03-06 08:00:15

标签: docker apache-kafka apache-zookeeper kafka-cluster

我正在使用Docker启动一个kafka经纪人集群(例如,5个经纪人,每个集装箱一个经纪人)。 Kafka版本2.12-0.11.0.0,Zookeeper 3.4.10。

情景:

  • 使用下面的配置启动第一个经纪人

zoo.cfg

tickTime=2000
initLimit=10
syncLimit=5

dataDir=/opt/zookeeper/data

clientPort=2181
maxClientCnxns=10
minSessionTimeout=4000
maxSessionTimeout=1000000
server.1=0.0.0.0:2888:3888

server.properties

broker.id=1
listeners=PLAINTEXT://:9092
advertised.listeners=PLAINTEXT://broker1_IP:broker1_PORT
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/tmp/kafka-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
zookeeper.connect=127.0.0.1:2181
zookeeper.session.timeout.ms=6000
zookeeper.connection.timeout.ms=1000000
group.initial.rebalance.delay.ms=0

producer.properties

bootstrap.servers=localhost:9092
compression.type=none

consumer.properties

zookeeper.connect=127.0.0.1:2181
zookeeper.session.timeout.ms=6000
zookeeper.connection.timeout.ms=1000000
group.id=test-consumer-group
  • Zookeeper以独立模式启动,然后启动kafka

  • 创建主题

/opt/kafka/bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic my-test-topic1

  • 发送消息

echo "test_kafka1" | /opt/kafka/bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-test-topic1

  • 检查消息

/opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-test-topic1 --max-messages 1

收到消息

  • 描述主题

/opt/kafka/bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-test-topic1 Topic:my-test-topic1 PartitionCount:1 ReplicationFactor:1 Configs: Topic: my-test-topic1 Partition: 0 Leader: 1 Replicas: 1 Isr: 1

  • 开始休息4经纪人
每个经纪人从第1位到第5位的

zoo.cfg (只有0.0.0.0:2888:3888位置不同)

tickTime=2000
initLimit=10
syncLimit=5

dataDir=/opt/zookeeper/data

clientPort=2181
maxClientCnxns=10
minSessionTimeout=4000
maxSessionTimeout=1000000
server.1=0.0.0.0:2888:3888
server.2=broker2_IP:broker2_2888:broker2_3888
server.3=broker3_IP:broker3_2888:broker3_3888
server.4=broker4_IP:broker4_2888:broker4_3888
server.5=broker5_IP:broker5_2888:broker5_3888
从1到5的每个代理上的

server.properties (broker.id是唯一的,broker_IP:broker_PORT因ech代理而异)

broker.id=N
listeners=PLAINTEXT://:9092
advertised.listeners=PLAINTEXT://broker_IP:broker_PORT
num.network.threads=3
num.io.threads=8
socket.send.buffer.bytes=102400
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
log.dirs=/tmp/kafka-logs
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
zookeeper.connect=127.0.0.1:2181
zookeeper.session.timeout.ms=6000
zookeeper.connection.timeout.ms=1000000
group.initial.rebalance.delay.ms=0
每个经纪商的第1到第5个

producer.properties

bootstrap.servers=localhost:9092
compression.type=none
每个代理从第1个到第5个

consumer.properties

zookeeper.connect=127.0.0.1:2181
zookeeper.session.timeout.ms=6000
zookeeper.connection.timeout.ms=1000000
group.id=test-consumer-group
  • 在每个代理上重新启动zookeeper以使zoo.cfg

  • 生效
  • Zookeepers聚集到群集

  • 主题已移至经纪人5

/opt/kafka/bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-test-topic1 Topic:my-test-topic1 PartitionCount:1 ReplicationFactor:1 Configs: Topic: my-test-topic1 Partition: 0 Leader: 5 Replicas: 5 Isr: 5

这是正常行为吗?还是应该留在经纪人1?

  • 检查每个经纪人的消息

/opt/kafka/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-test-topic1 --max-messages 1

消息丢失(当主题停留在代理1上时,消息不会丢失,所以    这是浮动的情况)

2 个答案:

答案 0 :(得分:0)

你有没有尝试将滴答时间提高到6000?根据Hadoop的设置,他们默认使用此设置,说明2000毫秒设置太低。我认为这同样适用。我现在正在处理一个非常相似的卡夫卡问题。

答案 1 :(得分:0)

在Kafka文档中,config descriptionconfig example都建议指定代理zookeeper.connect中的所有Zookeeper服务器。同样在生产中,期望您运行一个单独的Zookeeper集群和一个单独的Kafka集群,而不是在一个docker容器中共同运行Kafka和ZK。

我想这样的事情可能会发生:

  • 由于如何重启Docker容器的某些细节,ZK 2-5不知道Kafka 1在ZK 1中创建了一个znode来描述您的测试主题为“ Replicas:1,ISR:1”,或don由于没有法定人数,因此不同意使用ZK 1版本
  • 容器2-5的某些子集开始,并且其中5个ZK中的3个形成了仲裁,而没有等待ZK 1
  • 某事(消费者或命令行工具或代理自动创建)尝试使用该主题,并且由于ZK仲裁同意该主题尚不存在,因此创建了该主题并将副本分配给当前可用的代理之一(5这种情况)。
  • 容器1开始,ZK 1必须放弃其主题主题znode以支持仲裁,而Kafka必须放弃其副本以支持当前描述。

我不确定从单节点Zookeeper转移到复制设置的正确方法是什么,并且无法在文档中找到它。也许您最初必须为第一个ZK分配更多weight,以便确保它成为领导者并在其他ZK节点上强制其主题配置。

您创建了JIRA问题吗?得到了开发人员的任何回应?