2016-09-23 81 views
0

我正在配置3个经纪人的Kafka群集。 群集使用3个节点的Zookeeper群集。如果Zookeeper群集中的节点死亡,则Kafka群集不可用

使用泊坞,这是我开始了我的3个动物园管理员节点:

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个卡夫卡节点:

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 

的动物园管理员和卡夫卡集群表现良好时,独立测试。

我的意思是,我可以连接到动物园管理员的一个节点(比如zoo1),并创建一个Z序节点。之后我可以停止节点(例如,停靠站停靠站点zoo1),我仍然可以从Zookeeper集群中的任何其他节点查询znode

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

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

例如,如果我停止动物园管理员节点(例如,码头工人停止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节点的计算机烧毁。 我如何才能达到这种韧性?

回答

0

正如例外所述,主机名称可能无法从运行创建主题命令的位置解析。尝试ping到zoo1,zoo2,zoo3以检查他们是否正在解决纠正IP。

我不认为这是一个卡夫卡问题。但Zookeeper主机名称解析可能不会正确发生。我建议首先检查Zookeeper集成是否正常工作,当你关闭其中一个时创建一个新的znode并读取之前创建的znode。另外,请尝试在kafka-topics.sh命令中传递Zookeeper IP地址来代替主机名。

当你重新启动docker实例(比如说zoo1)时,它可能会以一个新的IP开始。 zoo1的主机名仍然可以从zoo2和zoo3解析?

+0

嗨。我知道一个动物园管理员主机的异常点不可解析。当然,我可以在任何动物园主持人都活着的时候连线,如果我明确地杀了他们,我就不能再打他们了。由于我正在测试弹性,我需要的是,即使其中一个动物园管理员节点从网络中消失(因此它的主机名或IP都不可解析),kafka群集仍会继续工作。只要Zookeeper节点的法定数量保持不变,我希望这能够工作。 Zookeeper整体工作正常,否则,我按照你的建议做了一个创建znode的测试。 – Sergio

+0

我认为只要Zookeeper quorum可用,Kafka集群就会正常工作。大多数情况下,kaka-topics.sh工具可能存在一些问题,它只能在内部调用某些Java类。我们可能会手动检查zookeeper znodes,例如/ brokers,/ consumers,/ controller等,以检查Kafka集群是否正常运行。 –