Zookeeper是一种用于分布式应用程序的分布式协调服务
Zookeeper提供了一些简单的原语操作(create,delete,exists,get data,set data,get children,sync),分布式程序可以使用这些原语,来实现更高级别的服务,实现同步,配置维护等等。(可以理解为Zookeeper本身比较简单,但复杂的分布式程序可以使用它的操作,封装出复杂的功能)。
在庞杂的集群中,要自己实现协调很容易出现死锁或资源竞争等问题,Zookeeper本是为此而生。
Zookeeper下每一个目录可理解为一个命名空间,Zookeeper使得分布式进程通过共享命名空间实现相互协调。
Zookeeper的数据保存在内存中,这意味着Zookeeper拥有高吞吐量和低延迟。
Zookeeper是复制集群模式,也是主从模式,这意味着客户端可以跟任何一个Zookeeper服务进行查询,但是只能跟leader做增删改。
Zookeeper集群只有一个leader,其余都是follower,所以leader存在单点故障。那么Zookeeper怎么解决这个问题?
实际上,当Zookeeper的leader故障之后,Zookeeper会进入不可用状态(此时无主),会采用一种技术极快的修复故障(官方压测在910个客户端40000+的并发请求下,恢复只需要低于200毫秒)
与标准的文件系统不同,Zookeeper命名空间中的节点(znode)及其子节点都可以存储数据(但是因为Zookeeper旨在协调服务不是存储数据,所以每个节点允许存储的数据量很小,最多1MB,所以千万不要把Zookeeper把数据库用)。
znode分为持久节点(persistent)和临时节点(ephemeral)。znode维护了一个stat结构,包含数据更改,访问控制列表,带时间戳的版本号,方便协调更新与验证。临时节点由客户端连接Zookeeper的一个session维护,session断开临时节点就被删除。
Zookeeper还有一些特点:
- 顺序一致性:来自客户端的更新请求都会按照顺序被应用(因为支持写操作的只有一个唯一的leader,由单机执行更新操作,不容易造成顺序错乱)
- 原子性:更新操作要么成功要么失败,不会产生多余的中间结果(然而事实上,更新操作在集群中,只要过半的机子成功了,就视为成功)
- 单系统映像:不论服务端连到集群的哪个机子,都看到同样的服务视图(因为集群是复制集群模式)
- 可靠性:一旦更新操作被集群应用了,产生的效果就一定会持续到客户端执行更新操作成功(就是说一旦相应了这个更新操作,则客户端那绝不会失败)
- 及时性:这实际上表示的是最终一致性
下面解析以下Zookeeper的配置文件
- tickTime:leader和follower之间维持心跳每次汇报的间隔时间
- initLimit:当一个follower想要追随一个leader时,leader最多忍受tickTime * initLimit,也就是默认20秒的初始延迟,超时将会连接失败
- syncLimit:当leader需要向follower同步操作时,如果超过tickTime * syncLimit,也就是默认10秒时,同步失败
- dataDir:Zookeeper持久化节点的目录
- clientPort:客户端连服务的端口号
- maxClientCnxns:当前Zookeeper节点允许连接的客户端最大值
最后配置集群的机器和端口 - 3888:当leader宕机或者还没有leader的时候,节点都通过3888这个端口进行通信,投票选主
- 2888:当选主完之后leader启2888端口,其他节点连leader的2888端口建立连接,后续在有leader节点的情况下,再有新的follower连接等行为都通过这个端口连接
- 选主过程实际上是一个节点谦让过程,根据server.X这个x与一个事务id共同考量,让值最大的直接当主,所以这个选主过程极快。假如我现在启动node02~04,根据谦让node04瞬间成为leader,如果只启动node02-03,那么node03瞬间成为leader