zookeeper 与 lease
在zookeeper中,follower节点是可以提供read
服务的,但是follower节点并不是leader,无法保证时刻与leader节点的数据保持一致。
那么zookeeper是如何做到这种操作的呢?
- leader提供
write
服务与read
服务。 - follower可以提供
read
服务,并且保证client从可用的的follower读取的数据与从leader读取的数据是一致的结果。
zookeeper在实现follower可读的功能的时候主要使用的一个为lease(租约)
的概念。
lease(租约):lease可以很容易的理解,就是某个节点或者某个服务向另一个节点请求可以服务的时间。在lease有效的时间内,这个节点是可以对外提供服务的。这个概念在GFS中是有的(但是并没有在HDFS中出现)
lease在zookeeper中的使用
我们知道zookeeper是一个distributed service。那么zookeeper中一定使用了多副本,那么一定会遇到多副本在分布式系统中实现的问题——副本一致性。zookeeper在实现副本一致性的方法是基于Paxos改进的(这里不详细叙述)。这里简单的说下原理:
zookeeper集群中选举出来一个leader,剩下都为follower
zookeeper的leader在进行
write
服务的时候,需要把write
操作的command 复制到其他follower节点,并且command的顺序要与leader一致。
那么按照这个原理,zookeeper的follower节点是有可能落后于leader的command的。
lease在zookeeper中是如何使用的:
follower节点在对外进行read服务的时候,其节点的lease应该是有效的(lease没有过期)。
follower节点的lease如果过期,或者将要过期,follower节点需要向leader节点申请。
leader节点在收到follower节点的申请的时候,需要对比follower节点commited的command的数量是否与leader节点相同,也就是比较follower节点与leader节点的状态或者副本是否一致。如果一致,那么leader就会向follower续这个租约。
如果leader节点发生了
write
操作,这些command被replicated到其他follower节点上,那么follower节点在收到这些command需要commit的时候会自动失效。如果follower因为网络deley,网络 partition等原因无法及时与leader进行通信,那么其lease会过期,自然follower节点就无法对外提供
read
服务。当leader节点有
write
command的时候leader并不是,每一条都直接replicated到follower节点,而是通过 batch+time的方式(一次batch一批command以及定时执行一次)。所以可以知道zookeeper的写入性能并不会太高,因为如果写入频率太快。
问题:
某个follower拿到了10s的lease,但是在运行到3s的时候与leader的网络发生了partition,无法与leader进行通信,但是这个时候这个follower还可以对外提供read
服务,但是这个时候系统的状态可能在3s-10s期间发生了变化,那么client从这个follower读取的数据还是旧的。 这个问题应该是lease机制的通用问题,那么这个问题应该如何改变?
解决:
- follower无法提供
read
功能,read
和write
都只能由leader提供服务。