zookeeper集群特性
1 集群的目的
zookeeper集群是为了保证系统的性能,能够承载更多的客户端连接。通过集群(主从模式可以实现以下功能:
- 读写分离:提高承载,为更多的客户端提供连接,并保障性能。
- 主从自动切换:提高服务容错性,部分节点故障不会影响整个服务集群。
2 半数以上运行机制说明
集群至少需要三台服务器,并且强烈建议使用奇数个服务器。
因为zookeeper 通过判断大多数节点的存活来判断整个服务是否可用。比如3个节点,挂掉了2个表示整个集群挂掉,而用偶数4个,挂掉了2个也表示其并不是大部分存活,因此也会挂掉。
3 集群部署
配置语法:
server.<节点ID>=<ip>:<数据同步端口>:<选举端口>
- 节点ID:服务id手动指定1至125之间的数字,并写到对应服务节点的 {dataDir}/myid 文件中。
- IP地址:节点的远程IP地址,可以相同。但生产环境就不能这么做了,因为在同一台机器就无法达到容错的目的。所以这种称作为伪集群。
- 数据同步端口:主从同时数据复制端口,(做伪集群时端口号不能重复)。
- 远举端口:主从节点选举端口,(做伪集群时端口号不能重复)。
配置文件示例:
1 |
|
集群配置流程:
- 分别创建3个data目录用于存储各节点数据
1 |
|
- 编写myid文件
1 |
|
1 |
|
3、编写配置文件
vim conf/zoo1.cfg
1 |
|
vim conf/zoo2.cfg
1 |
|
vim conf/zoo3.cfg
1 |
|
4.分别启动
1 |
|
5.分别查看状态
1 |
|
- 进入客户端,在server1中创建节点,server 3查看节点是否同步
1 |
|
1 |
|
4 集群角色说明
zookeeper 集群中总共有三种角色,分别是leader(主节点)follower(子节点) observer(次级子节点)
角色 | 描述 |
---|---|
leader | 主节点,又名领导者。用于写入数据,通过选举产生,如果宕机将会选举新的主节点。 |
follower | 子节点,又名追随者。用于实现数据的读取。同时他也是主节点的备选节点,并用拥有投票权。 |
observer | 次级子节点,又名观察者。用于读取数据,与fllower区别在于没有投票权,不能选为主节点。并且在计算集群可用状态时不会将observer计算入内。 |
observer配置:
只要在集群配置中加上observer后缀即可,示例如下:
1 |
|
5 集群选举机制
通过 ./bin/zkServer.sh status <zoo配置文件> 命令可以查看到节点状态,可以发现中间的2182 是leader状态
1 |
|
5.1 投票机制说明
第一轮投票全部投给自己
第二轮投票给myid比自己大的相邻节点,
如果得票超过半数,选举结束。
其选举机制如下图:
5.2 选举触发:
当集群中的服务器出现已下两种情况时会进行Leader的选举
- 服务节点初始化启动。当节点初始起动时会在集群中寻找Leader节点,如果找到则与Leader建立连接,其自身状态变化follower或observer。如果没有找到Leader,当前节点状态将变化LOOKING,进入选举流程。
- 半数以上的节点无法和Leader建立连接。在集群运行其间如果有follower或observer节点宕机只要不超过半数并不会影响整个集群服务的正常运行。但如果leader宕机,将暂停对外服务,所有follower将进入LOOKING 状态,进入选举流程。
5.3 数据同步机制
zookeeper 的数据同步是为了保证各节点中数据的一至性,同步时涉及两个流程,一个是正常的客户端数据提交,另一个是集群某个节点宕机在恢复后的数据同步。
5.3.1 客户端写入请求
当我们使用zookeeper客户端向Zookeeper 集群的某一个 Server 发送事务请求时,也就是对 Znode 节点的增删改操作时。
- 如果该server不是leader,则会将该写请求转发给leader server,leader将请求事务以proposal(建议)形式分发给follower;
- 当follower收到收到leader的proposal时,根据接收的先后顺序处理proposal;
- 当Leader收到follower针对某个proposal过半的ack后,(即follower过半都已经同步完成)则发起事务提交,重新发起一个commit的proposal
- Follower收到commit的proposal后,记录事务提交,并把数据更新到内存数据库;
- 当写成功后,反馈给client。
5.3.2 服务节点初始化同步
在集群运行过程当中如果有一个follower节点宕机,由于宕机节点没过半,集群仍然能正常服务。
当leader 收到新的客户端请求,此时无法同步给宕机的节点。造成数据不一致。为了解决这个问题,当节点启动时,第一件事情就是找当前的Leader,比对数据是否一致。不一致则开始同步,同步完成之后在进行对外提供服务。故在节点同步数据期间,该节点不会对外提供服务。
Leader挂了后,选举leader的过程中,集群不可以对外提供服务。
6 四字运维命令
ZooKeeper响应少量命令。每个命令由四个字母组成。可通过telnet或nc向ZooKeeper发出命令。
这些命令默认是关闭的,需要配置4lw.commands.whitelist来打开,可打开部分或全部示例如下:
1 |
|
1 |
|
ZXID说明
如何比对Leader的数据版本呢,这里通过ZXID事物ID来确认。比Leader小就需要同步。
ZXID是一个长度64位的数字,其中低32位是按照数字递增,任何数据的变更都会导致低32位的数字加1。
高32位是leader周期编号,每当选举出一个新的leader时,新的leader就从本地事物日志中取出ZXID,然后解析出高32位的周期编号,进行加1,再将低32位的全部设置为0。这样就保证了每次新选举的leader后,保证了ZXID的唯一性而且是保证递增的。
eg1: 节点数据的变更
Eg2: 某个节点挂掉重新选举
思考题:
如果leader 节点宕机,在恢复后它还能被选为leader吗?
不会,因为它的数据不是最新的。