一、背景
场景:
1、 服务地址如何维护;
-- 服务启动的时候,注册到一个服务中;key,服务名 value 若干个http地址 ;
2、如何对目标服务负载均衡
-- 从注册服务中拿到目标服务地址列表,通过轮询或者随机算法得到一个地址;
3、服务 的动态感知(目标服务可能宕机)
-- 心跳机制;注册中心定期和客户端心跳,如果没有返回,就认为挂掉,注册中心再push或者客户端pull地址列表;
二、实现框架 zookeeper(其他的有Eureka/consul)
zookeeper的背景:
1、zk真正用意是 分布式协调组件; (基于google chubby 不是开源的, 解决分布式一致性问题, 分布式锁 ;几个客户端去 chubby申请一个key,第一个客户端成功得到就是master,原理类似分布式锁);后来 雅虎实现类似chubby的功能zookeeper,后来捐献给apache;zookeeper集群,带中心节点的集群(kafka,es),不带中心节点的集群(redis)
定义一种协议(paxos)
2、数据结构 ,树形结构,每个节点进行编号;
zookeeper的设计
1、解决单点问题,集群 master/salve leader/follower/observer
2、数据同步 (过半的节点成功,才进行数据提交 observer不参与投票)
3、leader选举算法(一致性算法)zab协议 observer不参与投票
4、2pc协议
zookeeper基本特性
节点就是一个数据Node(key-value)
1、创建节点 顺序节点 持久化 临时节点 同一级别不能重复 临时节点不能存在子节点 2、删除节点 3、修改节点
4、watcher 通过对get -w 进行监听,处理一次,就不再监听了,配合临时节点,可以做动态感知;
5、master节点 >>zookeeper节点,create lock后,使用完后,会释放该链接(临时节点的特性),这样剩下的节点来抢锁,会带来 惊群效应; 可以通过对客户端节点进行顺序保存,每个节点监控前一个节点;
6、ACL
操作权限,READ=1 WRITE=2...
SCHEMA 权限模式 IP/DIGEST/WORLD/SUPER
7、watcher 机制
针对数据节点进行监听,然后通知客户端;zookeeper new的时候就可以增加watch机制;
原理:客户端通过getData,或者 exists,或者getChildren注册通知事件到 outgoingQueue队列中,然后SendThread 将队列中的数据发送到 zk server (NIOServerCnxnFactory),注册watch事件,

zookeeper的应用
1、提供服务注册和发现; 利用节点特性 持久和临时节点特性 ;
2、给别的应用程序提供master选举;
会创建一组临时有序节点 ,最小的节点就是master,后面的监听前一节点;
场景:多节点的定时调度;
zookeeper本身也是分leader-follower的,基于zab协议;事务请求只能是leader节点;
zab协议:崩溃恢复,已经被丢弃的信息需要放弃,那就选举zxid是最大的; 原子广播; 重新选举后,epoch会增加;
3、提供实现分布式锁;
会创建一组临时有序节点 ,最小的节点获得锁,后面的监听前一节点;Interprocessmutx;和master选举一个原理,都是利用临时有序的最小节点;
zookeeper的一致性
顺序一致性:在zk服务器上时间上值一致的,通过【队列、zxid】实现顺序一致 性;
lead选举
myid(sid)/epoch(时钟周期)/选举状态(LOOKING|FOLLOWING|LEADING|OBSERVING)
选举流程:单个节点先选自己,然后把消息广播其他节点,各自进行比较,按照规则(先去比较epoch;zxid最大为leader;myid最大为leader)进行比较;进行下一轮(epoch会+1)的投票,再按少数服从多数的原则,选出leader;
QuorumPeerMain启动类,暴露2181端口后;开始leade选举;.FastLeaderElection负责leader逻辑的判断;QuorumCnxManager 负责通信;


代码 的执行流程:

缺点:选举的时候,服务不可用;写多读少的场景 leader有性能瓶颈;