zookeeper-docker版

Zookeeper-docker版

1 zookeeper概述

1.1 什么是zookeeper

Zookeeper是一个分布式的、高性能的、开源的分布式系统的协调(Coordination)服务,它是一个为分布式应用提供一致性服务的软件。

1.2 zookeeper应用场景

zookeeper是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能,高可用,且具有严格属性访问控制能力的分布式协调存储服务。

1、维护配置信息

java编程经常会遇到配置项,比如数据库的url,schema,user和password等。通常这些配置项我们会放置在配置文件中,在将配置文件放置在服务器上当需要更改配置的时,需要去服务器上修改对应的配置信息文件。但是随着分布式系统的兴起,由于许多服务都需要使用到该配置文件,必须保证该配置服务的高可用性和各台服务器上配置数据的一致性。因此,通常会将配置文件部署在一个集群上,然而一个集群动辄上前台服务器,此时如果在一台一台服务器逐个的修改配置文件将是非常繁琐的一个操作。因此就需要一种服务,能够高效快速且可靠的完成配置项的更新等操作,并能够保证各个配置项在每一台服务器上的数据一致性。

zookeeper就可以提供这样一种服务,其使用Zab这种一致性协议来保证一致性。现在有很多开源项目使用zookeeper来维护配置,比如hhase中,客户端就是连接一个zookeeper,获得必要hbase集群的配置信息然后才可以进一步操作。还有开源的消息队列kafka中,也是用zookeeper来维护broker的信息。

2、分布式锁服务

一个集群是一个分布式系统,有多台服务器组成。为了提高并发度和可靠性,多台服务器运行着同一种服务。当多个服务在运行时就需要协调各服务的进度,有时候需要保证当某个服务在进行某个操作时,其他的服务都不能进行该操作,即对该操作进行加锁,如果当前机器挂掉后,并释放fail over到其他的机器继续执行该服务。

3、集群管理

一个集群优势会因为各种软硬件故障或者网络故障,出现某种服务器挂掉而被移除集群,而某些服务器加入到集群中的情况,zookeeper会将这些服务器加入/移出的情况下通知给集群汇总的其他正常工作的服务器,以及时调用存储和计算等任务的分配和执行等。此外zookeeper还会对故障的服务器做出诊断并尝试修复。

4、生成分布式唯一ID

在过去的单库单表型系统中,通常可以使用数据库字段自带的auto_increment属性来自动为每条记录生成一个唯一的ID。但是分库分表后,就无法再依靠数据库的auto_increatment属性来唯一标识一条记录了,此时我们就可以用zookeeper在分布式环境下生成全局唯一ID。做法如下:每一个生成一个新ID时,创建一个持久顺序节点,创建操作返回的节点序号,然后把比自己节点小的删除即可。

1.3 zookeeper的设计目标

zookeeper致力于为分布式应用提供一个高性能,高可用,具有严格顺序访问控制能力的分布式协调服务。

1、高性能

zookeeper将全量数据存储在内存中,并直接服务与客户端的所有非事务请求,尤其适合用于以读为主的应用场景。

2、高可用

zookeeper一般以集群的范式对外提供服务,一般3-5台机器就可以组成一个可用的zookeeper集群,每一台机器都会在内存中维护当前的服务器状态,并且每台机器之间都相互保持着通信。只要集群中超过一台的机器都在工作,那么这个集群就能够正常对外服务;

3、严格访问数据

对于客户端的每一个更新请求,Zookeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序。

2 Zookeeper的数据模型

2.1 zookeeper数据结构

Zookeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一颗树,每一个节点称做一个ZNode。每一个Znode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。

如何来描述一个ZNode呢?一个znode大体上分为3部分:

(1)节点的数据:即znode data(节点path,节点data的关系)就像是java map中(key,value)的关系。

(2)节点的子节点children

(2)节点的状态stat:用来描述当前节点的创建,修改记录,包括czxid、ctime等。

2.2 zookeeper节点类型

zookeeper中的节点有两种类型,一种是临时节点和永久节点。节点类型在创建是即被确定,并且不能改变。

(1)临时节点:该节点的生命周期依赖于创建他们的会话。一旦会话(Session)结束,临时节点将会被自动删除,当然可以手动的进行删除。虽然每个临时的ZNode都会绑定到一个客户端会话,但他们对所有的客户端还是可见的。另外,Zookeeper的临时节点不允许拥有子节点。

(2)持久化节点:该节点的生命周期不依赖于会话,并且只有在客户点显示执行删除操作的时候,他们才能被删除。

3 docker部署Zookeeper

3.1 部署准备

1、下载镜像

[root@hadoop104 ~]# docker pull zookeeper:3.5.8

2、创建局域网

在集群部署在同一个局域网中。

[root@hadoop104 ~]# docker network create --subnet=192.168.10.0/24 zk_net

3、创建节点挂载目录

(1)集群规划,集群部署3台机器:

集群编号ZOO_MY_ID名称映射本地端口ip存储路径
1zk12181192.168.10.101/usr/local zookeeper/zk1
2zk22182192.168.10.102/usr/local zookeeper/zk2
3zk32183192.168.10.103/usr/local zookeeper/zk3

(2)创建节点挂载目录

[root@hadoop104 ~]# cd /usr/local

#创建 zookeeper节点配置存放目录

[root@hadoop104 local]# mkdir -p zookeeper/zk1/conf zookeeper/zk2/conf zookeeper/zk3/conf

#创建 zookeeper节点数据存放目录

[root@hadoop104 local]# mkdir -p zookeeper/zk1/data zookeeper/zk2/data zookeeper/zk3/data

#创建 zookeeper节点数据日志存放目录

[root@hadoop104 local]# mkdir -p zookeeper/zk1/datalog zookeeper/zk2/datalog zookeeper/zk3/datalog

#创建 zookeeper节点日志存放目录

[root@hadoop104 local]# mkdir -p zookeeper/zk1/logs zookeeper/zk2/logs zookeeper/zk3/logs

4、创建配置文件

(1)在第1个节点挂载目录zookeeper/zk1/conf下分别创建配置文件zoo.cfg

[root@hadoop104 local]# vim zookeeper/zk1/conf/zoo.cfg

内容如下:

#Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这个目录里

dataDir=/data

#事务日志存储地点,如果没提供的话使用的则是 dataDir

dataLogDir=/datalog

#服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。tickTime以毫秒为单位

tickTime=2000

#集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)

initLimit=5

#集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)

syncLimit=2

#默认值为3,不支持以系统属性方式配置。用于配置Zookeeper在自动清理的时候需要保留的快照数据文件数量和对应的事务日志文件。此参数的最小值为3,如果配置的值小于3会自动调整到3

autopurge.snapRetainCount=3

#默认值为0,单位为小时,不支持以系统属性方式配置。用于配置Zookeeper进行历史文件自动清理的频率。如果配置为0或负数,表示不需要开启定时清理功能

autopurge.purgeInterval=0

#默认为60,不支持以系统属性方式配置。从Socket层面限制单个客户端与单台服务器之间的并发连接数,即以ip地址来进行连接数的限制。

#如果设置为0,表示不做任何限制。仅仅是单台客户端与单个Zookeeper服务器连接数的限制,不能控制所有客户端的连接数总和

maxClientCnxns=60

#3.5.0中的新功能:当设置为false时,可以在复制模式下启动单个服务器,单个参与者可以使用观察者运行,并且群集可以重新配置为一个节点,并且从一个节点。

#对于向后兼容性,默认值为true。可以使用QuorumPeerConfig的setStandaloneEnabled方法或通过将“standaloneEnabled = false”或“standaloneEnabled = true”添加到服务器的配置文件来设置它。

standaloneEnabled=false

#内嵌的管理控制台,停用这个服务

admin.enableServer=false

#开启四字命令,将所有命令添加到白名单中

4lw.commands.whitelist=*

#集群中服务的列表,ip设置为局域网zk_net的网段

server.1=192.168.10.101:2888:3888;2181

server.2=192.168.10.102:2888:3888;2181

server.3=192.168.10.103:2888:3888;2181

zoo.cfg配置文件中参数的说明 解释说明:

tickTime=2000zookeeper里面最小的时间单位为2000ms
initLimit=10Follower在启动过程中,会从Leader同步所有最新数据,然后确定自己能够对外服务的起始状态。Leader允许F在 initLimit 时间内完成这个工作。通常情况下,我们不用太在意这个参数的设置。如果ZK集群的数据量确实很大了,F在启动的时候,从Leader上同步数据的时间也会相应变长,因此在这种情况下,有必要适当调大这个参数了
syncLimit=5在运行过程中,Leader负责与ZK集群中所有机器进行通信,例如通过一些心跳检测机制,来检测机器的存活状态。如果L发出心跳包在syncLimit之后,还没有从F那里收到响应,那么就认为这个F已经不在线了。注意:不要把这个参数设置得过大,否则可能会掩盖一些问题
dataDir存储快照文件snapshot的目录。默认情况下,事务日志也会存储在这里。建议同时配置参数dataLogDir, 事务日志的写性能直接影响zk性能
dataLogDir事务日志输出目录。尽量给事务日志的输出配置单独的磁盘或是挂载点,这将极大的提升ZK性能
clientPort客户端连接server的端口,即对外服务端口 ,默认是2181
server.1配置集群节点
192.168.10.100:2888:3888主机名, 心跳端口、数据端口 的格式

(2)分别创建第2,3个节点的配置文件

[root@hadoop104 local]# cp zookeeper/zk1/conf/zoo.cfg zookeeper/zk2/conf

[root@hadoop104 local]# cp zookeeper/zk1/conf/zoo.cfg zookeeper/zk3/conf

3.2 部署节点

(1)安装并启动第1个节点

[root@hadoop104 ~]# docker run -d --restart always --name zk1 --network zk_net --ip 192.168.10.101 -p 2181:2181 -e ZOO_MY_ID=1 -v /usr/local/zookeeper/zk1/data:/data -v /usr/local/zookeeper/zk1/datalog:/datalog -v /usr/local/zookeeper/zk1/logs:/logs -v /usr/local/zookeeper/zk1/conf/zoo.cfg:/conf/zoo.cfg zookeeper:3.5.8

(2)安装并启动第2个节点

[root@hadoop104 ~]# docker run -d --restart always --name zk2 --network zk_net --ip 192.168.10.102 -p 2182:2181 -e ZOO_MY_ID=2 -v /usr/local/zookeeper/zk2/data:/data -v /usr/local/zookeeper/zk2/datalog:/datalog -v /usr/local/zookeeper/zk2/logs:/logs -v /usr/local/zookeeper/zk2/conf/zoo.cfg:/conf/zoo.cfg zookeeper:3.5.8

(3)安装并启动第3个节点

[root@hadoop104 ~]# docker run -d --restart always --name zk3 --network zk_net --ip 192.168.10.103 -p 2183:2181 -e ZOO_MY_ID=3 -v /usr/local/zookeeper/zk3/data:/data -v /usr/local/zookeeper/zk3/datalog:/datalog -v /usr/local/zookeeper/zk3/logs:/logs -v /usr/local/zookeeper/zk3/conf/zoo.cfg:/conf/zoo.cfg zookeeper:3.5.8

(4)查看节点状态

集群中3个节点,只有一个是leader,其它节点都为flower。

#第1个节点状态

[root@hadoop104 ~]# docker exec -it zk1 /bin/bash

root@245b7b533b30:/apache-zookeeper-3.5.8-bin# zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /conf/zoo.cfg

Client port found: 2181. Client address: localhost.

Mode: follower

#第2个节点状态

[root@hadoop104 ~]# docker exec -it zk2 /bin/bash

root@36d3223cc495:/apache-zookeeper-3.5.8-bin# zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /conf/zoo.cfg

Client port found: 2181. Client address: localhost.

Mode: leader

#第2个节点状态

[root@hadoop104 ~]# docker exec -it zk3 /bin/bash

root@450e6cf10d4f:/apache-zookeeper-3.5.8-bin# zkServer.sh status

ZooKeeper JMX enabled by default

Using config: /conf/zoo.cfg

Client port found: 2181. Client address: localhost.

Mode: follower

3个节点状态正常,集群搭建完成。

4 Zookeeper常用的Shell命令

4.1 基本操作

(1)连接ZooKeeper服务端:zkCli.sh –server ip:port

[root@hadoop104 ~]# docker exec -it zk1 /bin/bash

root@245b7b533b30:/apache-zookeeper-3.5.8-bin# zkCli.sh

[zk: localhost:2181(CONNECTED) 0]

(2)断开连接:quit

(3)查看命令帮助:help

(4)显示指定目录下节点:ls 目录

[zk: localhost:2181(CONNECTED) 7] ls /

[zookeeper]

4.2 新增节点

create [-s] [-e] path data # 其中 -s 为有序节点, -e 临时节点

(1)创建持久化节点并写入数据:

[zk: localhost:2181(CONNECTED) 0] create /test “123456”

Created /test

(2)创建持久化有序节,此时创建的节点名为指定节点名+自增序号

[zk: localhost:2181(CONNECTED) 2] create -s /test/sn “a”

Created /test/sn0000000001

[zk: localhost:2181(CONNECTED) 3] create -s /test/sn “b”

Created /test/sn0000000002

(3)创建临时节点,临时节点会在会话过期后被删除

[zk: localhost:2181(CONNECTED) 4] create -e /tmp “tmp”

Created /tmp

(4)创建临时有序节点,临时节点会在会话过期后被删除

[zk: localhost:2181(CONNECTED) 11] create -s -e /tmpsn “a”

Created /tmpsn0000000002

[zk: localhost:2181(CONNECTED) 12] create -s -e /tmpsn “b”

Created /tmpsn0000000003

4.3 获取节点数据

get -s path 或 stat path

(1)获取节点数据

[zk: localhost:2181(CONNECTED) 13] get /test

123456

(2)获取子节点数据

[zk: localhost:2181(CONNECTED) 15] get /test/sn0000000001

a

(3)查看详细信息

[zk: localhost:2181(CONNECTED) 20] get -s /test

123456

cZxid = 0x100000001

ctime = Thu Sep 12 07:33:53 UTC 2024

mZxid = 0x10000000b

mtime = Thu Sep 12 07:47:49 UTC 2024

pZxid = 0x100000005

cversion = 0

dataVersion = 0

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 4

numChildren = 2

节点各个属性如下表。一个重要的概念是Zxid(ZooKeeper Transaction Id),ZooKeeper节点的每一个更改都具唯一的Zxid,如果Zxid1小于Zxid2,则Zxid1的更改发生在Zxid2更改之前。

状态属性节点说明
cZxid数据节点创建时的事务ID
ctime数据节点创建世的时间
mZxid数据节点最后一个更新是的事务ID
mtime数据节点最后一个跟新时的时间
pZxid数据节点的子节点最后一个被修改时的事务ID
cversion子节点的更改次数
dataVerion节点数据的更改次数
aclVersion节点ACL的更改次数
ephemeralOwner如果节点是临时节点,则表示创建该节点的会话的SeeesionID;如果是持久节点,则该属性值为0
dataLength数据内容的长度
numChildren数据节点当前的子节点个数

4.4 更新节点

set path data [version]

(1)使用set命令来更新节点

[zk: localhost:2181(CONNECTED) 16] set /test “7890”

[zk: localhost:2181(CONNECTED) 17] get /test

7890

(2)根据版本号来更新节点

[zk: localhost:2181(CONNECTED) 23] get -s /test

abcd

cZxid = 0x100000002

ctime = Thu Sep 12 07:33:53 UTC 2024

mZxid = 0x10000000c

mtime = Thu Sep 12 07:54:30 UTC 2024

pZxid = 0x100000005

cversion = 3

dataVersion = 2

aclVersion = 0

ephemeralOwner = 0x0

dataLength = 4

numChildren = 3

[zk: localhost:2181(CONNECTED) 24] set /test “abcd” 3

[zk: localhost:2181(CONNECTED) 25] get /test

abcd

也可以基于版本号来进行更改,此时类似于乐观锁机制,当你传入的数据版本号(dataVersion)和当前节点的数据版本号不符合时,zookeeper会拒绝本次修改:

4.5 删除节点

delete path [version]

和更新节点数据一样,也可以传入版本号,当你传入的数据版本号(dataVersion)和当前节点的数据版本号不符合时,zookeeper不会执行删除操作。

(1)删除节点

[zk: localhost:2181(CONNECTED) 27] delete /tmp

(2)要想删除某个节点及其所有后代节点,可以使用递归删除,命令为 rmr path 或 eleteall path。

[zk: localhost:2181(CONNECTED) 30] deleteall /test

4.6 监听器

get -w path或 stat -w path

使用get path [watch] 注册的监听器能够在节点内容发生改变的时候,向客户点发出通知。需要注意的是zookeeper的触发器是一次性的(One-time trigger),触发一次后就会立即失效。

使用stat path [watch] 注册的监听器能够在节点抓哪个台发生改变的时候,向客户点发出通知。

(1)监听节点变化

客户端窗口1

[zk: localhost:2181(CONNECTED) 32] create /watch “123456”

[zk: localhost:2181(CONNECTED) 35] stat -w /watch

另开一个客户端窗口2

[root@hadoop104 ~]# docker exec -it zk2 /bin/bash

root@36d3223cc495:/apache-zookeeper-3.5.8-bin# zkCli

[zk: localhost:2181(CONNECTED) 0] set /watch “abcd”

在客户端窗口1,输出以下结果:

WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/watch

5 zookeeper事件监听机制

5.1 watcher概念

zookeeper提供了数据的发布/订阅功能,对个订阅者可同时监听某一特定主题对象,当该主题对象的自身状态发生变化时(例如节点内容改变,节点下的子节点列表改变等),会实时,主动通知所有订阅者;

zookeeper采用了watcher机制实现数据的发布/订阅功能。该机制在被订阅对象发生变化时会异步通知客户端,因此客户端不必在Watcher注册后轮询阻塞,从而减轻了客户点压力。

watcher机制实际上与观察者密室类似,也可以看作是一种观察者密室在分布式场景下的实现方式。

5.2 wathcer架构

Watcher实现由三个部分组成:

  • Zookeeper服务端
  • Zookeeper客户端
  • 客户端的ZKWatchManager对象

客户端首先将Watcher注册到服务端,同时将Watcher对象保存到客户端的Watch管理器中。当Zookeeper服务端监听的数据状态发生变化时,服务端会主动通知客户端,接着客户端的Watch管理器会触发相关Watcher来回调相应处理逻辑,从而完成整体的数据发布/订阅流程。

5.3 wahcher特性

(1)一次性:wathcer是一次性的,一旦被触发就会移除,再次使用时需要重新注册。

(2)客户端顺序回调:watcher回调是顺序串行化执行的,只有回调后客户端才能看到最新的数据状态。一个watcher回调逻辑不用太多,以免影响别的watcher执行。

(3)轻量级:wathcerEvent是最小的通信单元,结构上只包含通知状态,事件类型和节点路径,并不会告诉数据节点变化前后的具体内容。

(4)时效性:watcher只有在当前session彻底失效时才会无效,若session有效期内快速重连成功。则wacher依然存在,然后可接收到通知。

6 zookeeper应用场景

6.1 配置中心案例

工作中有这样一个场景:数据库用户名和密码信息放在一个配置文件中,应用读取该配置文件,配置文件信息放入缓存。 若数据库的用户名和密码改变时候,还需要重新加载缓存,比较麻烦,通过Zookeeper可以轻松完成,当数据库发生变化时自动完成缓存同步。

设计思路:

(1)连接zookeeper服务器。

(2)读取zookeeper中的配置信息,注册watcher监听器,存入本地变量。

(3)当zookeeper中的配置信息发生变化时,通过watcher的回调方法捕获数据变化事件。

(4)重新获取配置信息。

6.2 生成分布式唯一ID

在过去的单库单表型系统中,通常可以使用数据库字段自带的auto_increment属性来自动为每条记录生成一个唯一的ID。但是分库分表后,就无法再依靠数据库的auto_increment属性唯一标识一条记录了。此时我们就可以用zookeeper在分布式环境下生成全局唯一ID。

设计思路:

(1)连接zookeeper服务器

(2)指定路径下生成临时有序节点

(3)取序号及为分布式环境下的唯一ID

6.3 分布式锁

分布式锁有多重实现方式,比如通过数据库,redis都可以实现。作为分布式协同工具Zookeeper,当然也有着标准的实现方式。下面介绍在zookeeper中如何实现排它锁。

设计思路:

(1)每个客户端往/Locks下创建临时有序节点/Locks/Lock_,创建成功后/Locks下面会有每个客户端对应的节点。如/Locks/Lock_0000001

(2)客户端取得/Locks下子节点,并进行排序,判断排在最前面的是否为自己,如果自己的锁节点在第一位,代表获取锁成功。

(3)如果自己的锁节点不在第一位,则监听自己前一位的锁节点。如果自己锁节点Lock_000002,那么则监听Lock_0000001。

(4)当前一位锁节点(Lock_000000001)对应的客户端执行完成,释放了锁,将会触发监听客户端(Lock_000002)的逻辑。

(5)监听客户端重新执行第2步逻辑,判断自己是否获得了锁。

7 zookeeper的leader选举

7.1一致性协议

zab协议的全称是Zookeeper Atomic Broadcast (zookeeper原子广播)。zookeeper是通过zab协议来保证分布式事务的最终一致性

基于zab协议,zookeeper集群中的角色主要有一下三类:

  • 领导者(leader):领导者负责进行投票的发起和决议,更新系统状态。
  • 学习者(Learner):
    • Follower:用于接受客户请求并向客户端返回结果,将写请求转发给leader节点,在选举过程中参与投票。
    • ObServer:用于接受客户请求并向客户端返回结果,但是ObServer不参加投票过程,只同步leader的状态。ObServer的目的是为了扩展系统,提高读取速度。
  • 客户端(Client) 请求发起方。

zab广播模式工作原理,通过类似两阶段提交协议的方式解决数据一致性:

(1)leader从客户端收到一个写请求。

(2)leader生成一个新的事务并为这个事务生成一个唯一的ZXID。

(3)leader将这个事务提交(propose)发送给所有的follows节点。

(4)follower节点将收到的事务请求加入到历史队列(history queue)中,并发送ack给leader当leader收到大多数follower(半数以上节点)的ack消息,leader会发送commit请求。当follower收到commit请求时,从历史队列中将事务请求commit。

7.2 zookeeper的leader选举

1、服务器状态

(1)looking:寻找leader状态。当服务器处于该状态时,它会认为当前集群中没有leader,因此需要进入leader选举状态。

(2)leading:领导者状态。表明当前服务器角色是leader。

(3)followin:跟随者状态。表明当前服务器角色是follower。

(4)observing:观察者状态。表明当前服务器角色是observer。

2、服务器启动时期的leader选举

在集群初始化阶段,当有一台服务器server启动时,其单独无法进行完成leader选举,当第二台服务器server2启动时,此时两台机器可以相互通信,每台机器都试图找到leader。于是进入leader选举过程。选举过程如下:

(1)每个server发出一个投票。由于是初始情况,server1和server2都会将自己作为leader服务器进行投票,投票会包含所推举的服务器的myid(服务器的编号)和zxid(事务ID),使用(myid,zxid)来表示,此时server1的投票为(1,0),server2的投票为(2,0),然后各自将这个投票发给集群中其他机器。

(2)集群中的每一台服务器接受来自集群中各个服务器的投票。

(3)处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行pk,pk规则如下:

①优先检查zxid。zxid比较大的服务器优先为leader。

②如果zxid相同,那么就比较myid。myid比较大的服务器作为leader服务器。

对于Server1而言,它的投票是(1,0),接受Server2的投票为(2,0),首先会比较两者的zxid,均为0,再比较myid,此时server2的myid最大,于是更新自己的投票为(2,0),然后重新投票,对于server2而言,其无须更新自己的投票,只是再次向集群中所有机器发出上一次的投票信息即可。

(4)统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于server1、server2而言,都统计出集群中已经有两台机器接受了(2,0)的投票信息,此时便认为已经选出了leader。

(5)改变服务状态。一旦确定了leader,每个服务器就会更新自己的状态,如果是follower,那么久变更为following,如果是leader,就变更为leading。

2、服务器运行时期的Leader选举

在zookeeper运行期间,leader与非leader服务器各司其职,即便当有非leader服务器宕机或新加入,此时也不会影响leader,但是一旦leader服务器挂了,那么这个集群将暂停对外服务,进入新一轮leader选举,其过程和启动时期的Leader选举过程基本一致。

假设正在运行的server1、server2、server3三台服务器,当前leader是server2,若某一时刻leader挂了、此时开始Leader选举。选举过程如下:

(1)变更状态。leader挂后,剩余的服务器都会将自己的服务状态变更为looking,然后开始进入leader选举过程。

(2)每个server会发出一个投票。在运行期间,每个服务器上的zxid可能不同,此时假设server1的ZXID为122,server3的zxid为122,在第一轮投票中,server1和server3都会投自己、产生投票(1,122),(3,122),然后各自将投票发送给集群中的所有机器。

(3)接受来自各个服务器的投票。与启动时过程相同。

(4)处理投票。与启动时过程相同,此时,server3将会成为leader。

(5)统计投票。与启动时过程相同。

(6)改变服务器的状态。与启动时过程相同。

7.3 observer角色及其配置

1、observer角色特点

(1)不参与集群的leader选举

(2)不参与集群中写数据时的ack反馈

2、配置observer

为了使用observer角色,在任何想变成observer角色的配置文件中加入如下配置:

peerType=observer

并在所有的server的配置文件中,配置成observer模式的server的哪行配置追加:observer。

例如:

server.3=192.168.10.103:2181:2183:observer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/26763.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】LRUCache|并查集

目录 一、LRUCache 1.概念 2.实现:哈希表双向链表 3.JDK中类似LRUCahe的数据结构LinkedHashMap 🔥4.OJ练习 二、并查集 1. 并查集原理 2.并查集代码实现 3.并查集OJ 一、LRUCache 1.概念 最近最少使用的,一直Cache替换算法 LRU是Least Recent…

AUTOSAR简介

目录 核心目标 架构分层 核心优势 经典AUTOSAR vs 自适应AUTOSAR 典型应用场景 挑战与未来发展 相关企业介绍 1. 传统汽车电子供应商(Tier1) 2. 软件服务商与工具链企业 3. 新兴科技公司与自动驾驶企业 4. 基础软件与工具链企业 5. 高校与研…

国产开源AI平台Cherry Studio详解:联网搜索升级与ChatBox对比指南

文章概述 Cherry Studio是一款功能强大的国产开源AI工具,支持本地部署、知识库管理、多模型聚合和联网搜索等特性。本文将详细介绍Cherry Studio的核心功能、1.0版本新特性及与ChatBox的对比分析,帮助用户选择最适合自己的AI助手工具。 Cherry Studio核…

【Python 初级函数详解】—— 参数沙漠与作用域丛林的求生指南

欢迎来到ZyyOvO的博客✨,一个关于探索技术的角落,记录学习的点滴📖,分享实用的技巧🛠️,偶尔还有一些奇思妙想💡 本文由ZyyOvO原创✍️,感谢支持❤️!请尊重原创&#x1…

【计算机网络入门】初学计算机网络(六)

目录 1.回忆数据链路层作用 2. 组帧 2.1 四种组帧方法 2.1.1 字符计数法 2.1.2 字节填充法 2.1.3 零比特填充法 2.1.4 违规编码法 3. 差错控制 3.1 检错编码 3.1.1 奇偶校验码 3.1.2 CRC(循环冗余校验)校验码 3.2 纠错编码 3.2.1 海明校验码…

二叉树的核心技术与C++实现:存储、遍历与递归应用

目录 一、二叉树基础概念与常见类型 1.1 二叉树核心概念 1.2 四种常见二叉树类型 类型1:满二叉树 类型2:完全二叉树 类型3:二叉搜索树(BST) 类型4:平衡二叉树(AVL) 类型5&…

《白帽子讲 Web 安全:点击劫持》

目录 摘要: 一、点击劫持概述 二、点击劫持的实现示例:诱导用户收藏指定淘宝商品 案例 构建恶意页面: 设置绝对定位和z - index: 控制透明度: 三、其他相关攻击技术 3.1图片覆盖攻击与 XSIO 3.2拖拽劫持与数据…

IDEA 使用codeGPT+deepseek

一、环境准备 1、IDEA 版本要求 安装之前确保 IDEA 处于 2023.x 及以上的较新版本。 2、Python 环境 安装 Python 3.8 或更高版本 为了确保 DeepSeek 助手能够顺利运行,您需要在操作系统中预先配置 Python 环境。具体来说,您需要安装 Python 3.8 或更高…

Linux:进程替换

目录 进程程序替换 替换原理 进程替换相关函数 环境变量与进程替换函数 命令行解释器(my_xshell) 进程程序替换 上一篇进程控制讲到,父进程创建子进程就是为了让子进程去做一些另外的事情,但是不管怎么说,子进程的部分代码也还是父进程…

Navicat连接虚拟机数据库详细教程

Navicat连接虚拟机数据库详细教程 以Windows主机 上的navicat 连接ubuntu虚拟机为例 确认虚拟机ip地址和主机ip地址 主机地址查询 cmd输入ipconfig 登录mysql 创建用户 CREATE USER newuserlocalhost IDENTIFIED BY password; CREATE USER newuser% IDENTIFIED BY passwor…

Java内存管理与性能优化实践

Java内存管理与性能优化实践 Java作为一种广泛使用的编程语言,其内存管理和性能优化是开发者在日常工作中需要深入了解的重要内容。Java的内存管理机制借助于垃圾回收(GC)来自动处理内存的分配和释放,但要实现高效的内存管理和优…

解码中国AI双雄突围:DeepSeek破壁与英伟达反攻背后的算力暗战

一、算力困局下的中国突围术 2024年夏季的科技界暗流涌动:北京中关村的服务器机房里,寒武纪最新MLU300X芯片正以每秒120万亿次运算支撑着自动驾驶系统的实时决策;上海张江的AI实验室中,DeepSeek团队通过神经元分块技术将模型参数压…

【Python · Pytorch】Conda介绍 DGL-cuda安装

本文仅涉及DGL库介绍与cuda配置,不包含神经网络及其训练测试。 起因:博主电脑安装了 CUDA 12.4 版本,但DGL疑似没有版本支持该CUDA版本。随即想到可利用Conda创建CUDA12.1版本的虚拟环境。 1. Conda环境 1.1 Conda环境简介 Conda&#xff1…

0x03 http协议和分层架构

HTTP协议 简介 Hyper Text Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则 http协议基于TCP协议:面向连接,安全基于请求-响应模型:一次请求对应一次响应HTTP协议是无状态的协议&#xff…

IDEAPyCharm安装ProxyAI(CodeGPT)插件连接DeepSeek-R1教程

背景:最近DeepSeek比较火嘛,然后在githup上也看到了GitHub Copilot,就想着现在AI的准确率已经可以提高工作效率了。所以从网上找了一些编程插件,发现Proxy支持的模型比较多,通用性和适配性比较好。所以本文记录一下pro…

qt-C++笔记之QToolButton和QPushButton的区别

qt-C笔记之QToolButton和QPushButton的区别 code review! 文章目录 qt-C笔记之QToolButton和QPushButton的区别1.运行2.main.cpp3.main.pro 1.运行 QToolButton 适用于工具栏或需要较紧凑、图标化显示的场合。通过 setAutoRaise(true) 与 setToolButtonStyle(Qt::ToolButtonTe…

css的元素显示模式

一.什么是元素显示模式 作用&#xff1a;网页的标签非常多&#xff0c;不同地方会用到不同类型的标签&#xff0c;了解他们的特点可以更好的布局我们的网页。 元素显示模式就是元素(标签)以什么方式进行显示&#xff0c;比如<div>自己占一行&#xff0c;比如一行可以放多…

MySQL整体架构

目录 1 客户端 2 服务端 2.1 Server层 2.1.1 连接器 2.1.2 查询缓存 2.1.3 词法器 2.1.4 优化器 2.1.5 执行器 2.2 存储引擎层 1 客户端 ● 客户端为连接MySQL服务端的工具或者驱动&#xff0c;比如JDCB&#xff0c;ODBC等等 ● 用于连接目前服务器&#xff0c;并且发送需要执行…

【踩坑随笔】`npm list axios echarts`查看npm依赖包报错

npm list axios echarts查看npm依赖包出现以下报错&#xff0c;原因就是包的版本匹配问题&#xff0c;按照提示降axios版本或者自己升找合适的got版本&#xff0c;我这里是选择了降版本。本文记录仅做解决思路参考不一定适配大家的实际情况。 weed-detection-system1.0.0 E:\P…

大唐杯——阶段二01

03 5G寻呼 UE&#xff08;User Equipment&#xff09; UE是用户设备&#xff08;User Equipment&#xff09;的缩写&#xff0c;指的是移动通信网络中的终端设备&#xff0c;例如手机、平板电脑、物联网传感器等。 AMF&#xff08;Access and Mobility Management Function&a…