Zookeeper⾥边会有⼀个监控的信息,因为Zookeeper是有⼀个⼼跳监控机制存在的,⼀般都是每隔2秒就⼼跳⼀下来确认Controller是否还存活,如果不存在的话就会把资源节点让给其他的Controller,这个⼼跳检测机制是⽐较常⻅的,⽐如HDFS的NameNode和DataNode之间的⼼跳检测也是通过这个实现的,还有Yarn的ResourceManager的⾼可⽤也是通过这个实现的,还有Canal的HA也是通过这个分布式锁来实现的,当然这个分布式锁的实现⽅式也有很多种,⽐如:使⽤Zookeeper来实现,使⽤Redis实现,或者Mysql也可以实现。
通常我们都是采⽤Zookeeper实现的分布式锁,因为它实现的⽐较好,因为Zookeeper这个⼼跳检测机制的存在,它会每隔⼀段时间来监听⼀下确保被监控的服务是正常存活的状态。
Redis实现的话就需要设置过期时间同时有⼀个缺点也是很致命的,如果到了过期时间Key就会直接消失,它不会知道你是否已经⽤完了这个资源,所以不是很好控制,如果使⽤其他的数据库是没有这个⼼跳值的,只能⾃⼰实现⼀个类似轮询的功能不断的进⾏查询确认所以对⽐⼀下还是Zookeeper做的⽐较好
⾸先要有⼀个main()线程;在main线程中创建Zookeeper客户端,这时就会创建两个线程,⼀个负责⽹络连接通信 (connet),⼀个负责监听(listener);通过connect线程将注册的监听事件发送给Zookeeper。
在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程;listener线程内部调⽤了process()⽅法。
如果消费者设置的过多的话是没有效果的,因为他们之间的关系是⼀⼀对应的,多余的消费者线程就会产⽣空 转,如果消费者设置的过少就会导致⼀个消费者线程消费多个分区的数据,同时这里还有⼀个动态分区的机制存在,如果⼀个消费者消费的分区过多就会触发这个机制,每当新的消费者上线或者增加了新的分区就会重新的负载均衡此时消费者分区数就会产生变化,这⼀块如果对接SparkStreaming还需要⾃⼰来维护Offset,已达到精准⼀次消费的⽬的。