1. Zookeeper:协调其他组件运行。自己不提供具体服务。
2. 文件系统+通知机制。存数据,如果有关心一些数据的主机,这其中被关心的数据变化时,zookeeper会通知他们。
3. 没有文件夹文件的概念。每个节点称作一个ZNode,每个默认存储1MB的数据。
4. 全局一致性—》通过ZAB协议(Zookeeper Atomic Broadcast)zookeeper原子广播,保证全局一致性。
ZAB实现了Paxos算法。这个算法核心思想就是少数服从多数。注:P算法没有考虑数据在传输时进行了篡改。
ZAB主要包含两个部分:
(1)崩溃恢复:只要集群中没leader,就选leader。怎么选:zookeeper选举机制。
(2)正常执行:有leader就干活。
5. zookeeper服务器状态:(四个)
(1)looking(表示集群刚刚启动,寻找leader的状态,就处在崩溃恢复状态,处在这个状态的集群,zookeeper无法对外提供服务)
,(2)(3)flowing,leading,
(4)Observding:(观察者,只听命令,不投票,投票只能leader,follower,但是obersering可以对外提供读服务。)
注意:observing相比于follower只是没有投票权,其他的权利是有的,比如说从这个observing节点写操作。
Observing的好处:读性能提升,写性能不变,因为投票还是之前的follower和leader投的票,决定写成功这个过程它不参与。
Observding产生的原因:
Zookeeper集群随着集群的横向扩展
(1) 读操作的性能越来越好。因为zookeeper集群中,每台服务器的数据保持一致性,所以无论从哪个里面读都可以直接读到数据;
(2) 写的操作性能越来越差。因为写操作的过程是无论从集群中哪台服务器中写都必须先将写请求的数据转发给leader,然后leader再将写请求的数据装发给各个节点,各个节点进行投票才决定这个写请求能不能执行。
集群横向扩展,节点数增多,参与投票的节点就增多,决定到底执不执行这个写操作的节点就增多,过程也就越麻烦。
为了解决上面的过程,才有了observing。
Observing应用场景:一般跨数据中心的集群,用observing。比如:有三个数据中心,分别位于三个不同点地方,如果三个数据中心只有leader和follower,那么在写数据投票时,进行网络传输就会很慢,于是,采用follower和leader只在一个数据中心中,其他两个数据中心只有observing,只负责听命令写数据,不负责投票。
问题:根据上面所说的,是不是follower越少越好,越少就会使得投票的节点越少,也就使写数据时节点投票越简单?
答:不是,follower决定着容错率,zookeeper集群的特点:只要半数以上节点(只包括leader和follower,也就是只包括有投票权的节点)存活,zookeeper集群就能正常运行。举个例子,如果集群有三个节点,那么这个集群允许一个节点挂掉,容错率就是33%,如果有五个节点,容错率就是40%,也就是容错率随着follower的增加而增加,但也不适合多,多了写操作就会复杂,所以按实际情况而定。
6、选举机制:先比较zxid(写数据次数,表示数据新旧的程度,zxid越大,数据越新),如果zxid相同再比较myid’。
比较zxid是原因因为可能有的节点数据还没有同步,由于网络原因或者是服务器之前没启动,后来又启动了,这样,这些服务器中数据就比较旧,就不可能被选为leader。
7、有了leader,zookeeper才能对外提供服务。
8、读数据:无论从那个节点读都一样,因为全局一致性。
9、写数据:
问:是不是不是leader就没有写操作。
答:不是,如果不是leader,其他节点接收到写操作时,就转给leader,leader将数据分发给各个server(包括leader),【意思就是即使follow收到数据,他也要发给leader,等leader转消息给它】
写操作有可能成功有可能失败,成功分为两个情况,失败分为一种情况
写操作流程:
(1) leader将数据分发给各个server(包括leader和follower),【意思就是即使follow收到数据,他也要发给leader,等leader再转消息给它】,
(2) 每一个server将数据写到待写队列(list),
【写入待写队列的条件:比较zxid(操作的zxid与服务器目前的zxid比较,不是和代写队列的zxid比较的),如果写的数据zxid大于目前服务器中的zxid就将操作插入到待写序列。如果不大于就舍弃。】
【待写队列的作用:将等待执行的数据操作放在待写队列中,等集群节点投票决定是执行这个操作,还是不执行这个操作】,
(3) 如果插入待写队列成功,就向leader发送成功信息,
(4) 根据插入待写队列成功数分为三种情况如下:
a) 写操作成功所有节点都成功:如果所有节点(包括leader和follower)都成功插入到待写队列。那么leader就会向所有的节点发送提交信息,数据才真正执行了写操作。
b) 写操作成功半数以上节点成功:如果有五个节点,三个节点成功插入到了待写队列,两个节点没有插入。原因是因为此时节点数据的zxid比要插入数据的zxid大,这是有可能因为8,9两个zxid一起写的,由于网络延迟,这两个失败的先把9给写了,8还没写。这种情况下,这两个失败的节点数据就不和集群同步了,这两个失败的节点就会停止对外提供服务,然后从leader中按照zxid一条一条拉取数据,重置自己的数据,和leader数据保持一致。
c) 写操作失败半数以上节点失败:没放入待写队列的节点不用操作,放入了待写队列的节点,服务器将待写队列中的该条数据移除。
(5) 注意:如果写操作投票同意执行了,所有的节点(包括leader,follower)。
11、(4)中这三种就是Paxos在zookeeper的实现。再加上存储模型,就是zookeeper的实现,这些过程就是p算法的推演过程。Zxid是leader编写指定的。
12、回调函数:(只要回答出来sendTread和eventThread)
(1)不是主线程执行的回调函数
(2)在main线程中创建zookeeper客户端,这时就会创建两个线程,一个负责网络通信(connect:sendTread),一个负责监听(listener:eventThread)。
创建了两个新的子进程,【多线程的创建:继承Tread,然后Tread.start启动子线程】,sendTread就是zookeeper客户端向zookeeper发送信息的线程,eventThread就是zookeeper发生了变化通知客户端,这个线程进行接收。
综上:eventTread负责通过watcher.process调用process(回调函数)
13、面试问涉及zookeeper的时候,需要从zookeeper原理ZAB进行考虑。