如果Zookeeper群集中的节点死亡,则Kafka群集不可用

时间:2016-09-23 14:20:26

标签: apache-kafka apache-zookeeper

我正在配置一个由3个代理组成的Kafka集群。 集群使用3个节点的Zookeeper集群。

使用Docker,这就是我启动3 Zookeeper节点的方式:

docker run --net=my_network --name zoo1 -d -e ZOO_MY_ID=1 -e ZOO_SERVERS="server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888" zookeeper

docker run --net=my_network --name zoo2 -d -e ZOO_MY_ID=2 -e ZOO_SERVERS="server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888" zookeeper

docker run --net=my_network --name zoo3 -d -e ZOO_MY_ID=3 -e ZOO_SERVERS="server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888" zookeeper

这就是我开始我的3个Kafka节点的方式:

docker run --net=my_network --name kafka1 -d -e KAFKA_ADVERTISED_PORT=9092 -e KAFKA_BROKER_ID=1 -e KAFKA_ZOOKEEPER_CONNECT="zoo1:2181,zoo2:2181,zoo3:2181" wurstmeister/kafka

docker run --net=my_network --name kafka2 -d -e KAFKA_ADVERTISED_PORT=9092 -e KAFKA_BROKER_ID=2 -e KAFKA_ZOOKEEPER_CONNECT="zoo1:2181,zoo2:2181,zoo3:2181" wurstmeister/kafka

docker run --net=my_network --name kafka3 -d -e KAFKA_ADVERTISED_PORT=9092 -e KAFKA_BROKER_ID=3 -e KAFKA_ZOOKEEPER_CONNECT="zoo1:2181,zoo2:2181,zoo3:2181" wurstmeister/kafka

Zookeeper和Kafka群集在独立测试时表现良好。

我的意思是,我可以连接到其中一个Zookeeper节点(例如 zoo1 )并创建 znode 。我之后可以停止节点(例如, docker stop zoo1 ),我仍然可以从Zookeeper集群中的任何其他节点查询 znode

Kafka集群也表现良好。假设Zookeeper中的3个节点已启动,我可以创建主题,发送消息,删除代理领导者,并验证消息是否仍然可以使用。

我的问题是,如果其中一个Zookeeper节点死亡,Kafka集群将停止工作。

例如,如果我停止一个zookeeper节点(例如, docker stop zoo1 ),然后尝试使用此命令创建一个主题:

 ./kafka-topics.sh --create --zookeeper "zoo1:2181,zoo2:2181,zoo3:2181" --replication-factor 3 --partitions 1 --topic my-replicated-topic

我将收到 UnknownHostException

Exception in thread "main" org.I0Itec.zkclient.exception.ZkException: Unable to connect to zoo1:2181,zoo2:2181,zoo3:2181
    at org.I0Itec.zkclient.ZkConnection.connect(ZkConnection.java:71)
    at org.I0Itec.zkclient.ZkClient.connect(ZkClient.java:1227)
    at org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:156)
    at org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:130)
    at kafka.utils.ZkUtils$.createZkClientAndConnection(ZkUtils.scala:75)
    at kafka.utils.ZkUtils$.apply(ZkUtils.scala:57)
    at kafka.admin.TopicCommand$.main(TopicCommand.scala:54)
    at kafka.admin.TopicCommand.main(TopicCommand.scala)
Caused by: java.net.UnknownHostException: zoo3: Name or service not known
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928)
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323)
    at java.net.InetAddress.getAllByName0(InetAddress.java:1276)
    at java.net.InetAddress.getAllByName(InetAddress.java:1192)
    at java.net.InetAddress.getAllByName(InetAddress.java:1126)
    at org.apache.zookeeper.client.StaticHostProvider.<init>(StaticHostProvider.java:61)
    at org.apache.zookeeper.ZooKeeper.<init>(ZooKeeper.java:445)
    at org.apache.zookeeper.ZooKeeper.<init>(ZooKeeper.java:380)
    at org.I0Itec.zkclient.ZkConnection.connect(ZkConnection.java:69)

但是我确实需要Kafka集群才能完全正常运行,即使其中一台托管Zookeeper节点的计算机都会烧毁。 我如何才能达到这种弹性?

1 个答案:

答案 0 :(得分:1)

正如例外所述,主机名可能无法从运行create topic命令的位置解析。尝试ping到zoo1,zoo2,zoo3以检查它们是否正在解析为正确的IP。

我认为这不是卡夫卡问题。但Zookeeper主机名解析可能无法正确进行。我建议首先通过创建一个新的znode并读取之前创建的znode来检查Zookeeper集合是否正常工作。另外,尝试在kafka-topics.sh命令中传递Zookeeper IP地址来代替主机名。

当您重新启动docker实例(比如zoo1)时,它可能以新IP开始。 zoo2和zoo3还能解析zoo1主机名吗?