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 | 存储路径 |
---|---|---|---|---|
1 | zk1 | 2181 | 192.168.10.101 | /usr/local zookeeper/zk1 |
2 | zk2 | 2182 | 192.168.10.102 | /usr/local zookeeper/zk2 |
3 | zk3 | 2183 | 192.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=2000 | zookeeper里面最小的时间单位为2000ms |
---|---|
initLimit=10 | Follower在启动过程中,会从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
相关文章:
zookeeper-docker版
Zookeeper-docker版 1 zookeeper概述 1.1 什么是zookeeper Zookeeper是一个分布式的、高性能的、开源的分布式系统的协调(Coordination)服务,它是一个为分布式应用提供一致性服务的软件。 1.2 zookeeper应用场景 zookeeper是一个经典的分…...
华为手机自助维修的方法
测试环境:华为荣耀 (全文完)...
基于Springboot博物馆文博资源库系统【附源码】
基于Springboot博物馆文博资源库系统 效果如下: 系统登陆页面 文物信息管理页面 流动申请页面 文物报修页面 个人信息页面 文物保修管理页面 系统主页面 文物类型页面 研究背景 随着信息技术的飞速发展,博物馆文博资源的管理与利用日益受到重视。传统…...
辛格迪客户案例 | 祐儿医药科技GMP培训管理(TMS)项目
01 项目背景:顺应行业趋势,弥补管理短板 随着医药科技行业的快速发展,相关法规和标准不断更新,对企业的质量管理和人员培训提出了更高要求。祐儿医药科技有限公司(以下简称“祐儿医药”)作为一家专注于创新…...
Git 2.48.1 官方安装与配置全流程指南(Windows平台)
一、软件简介 Git 是 分布式版本控制系统 的标杆工具,由 Linus Torvalds 开发,广泛应用于代码版本管理、团队协作开发等场景。2.48.1 版本优化了文件系统监控性能,并修复了跨平台兼容性问题。 二、下载准备 1. 官方下载地址 访问 Git 官网…...
MATLAB中asManyOfPattern函数用法
目录 语法 说明 示例 匹配尽可能多的模式实例 指定要匹配的最小模式数 指定要匹配的最小和最大模式数 asManyOfPattern函数的功能是模式匹配次数尽可能多。 语法 newpat asManyOfPattern(pat) newpat asManyOfPattern(pat,minPattern) newpat asManyOfPattern(pat,m…...
大模型推理时的尺度扩展定律
大模型推理时的尺度扩展定律 FesianXu at 20250212 at Wechat Search Team 前言 大模型的尺度扩展定律告诉我们:『LLM的性能会随着模型的参数量、模型的训练量、模型的训练数据量的增加而增加』。训练存在尺度扩展定律,测试也存在尺度扩展定律ÿ…...
迷你世界脚本世界UI接口:UI
世界UI接口:UI 彼得兔 更新时间: 2023-10-25 10:40:44 具体函数名及描述如下: 序号 函数名 函数描述 1 setGBattleUI(...) 设置战斗总结UI 2 world2RadarPos(...) 世界坐标转换到小地图 3 world2RadarDist(...) 世界长度转换到小地图 4 …...
局域网自动识别机器名和MAC并生成文件的命令
更新版本:添加了MAC 地址 确定了设备唯一性 V1.1 局域网自动识别机器名和MAC并生成文件的批处理命令 echo off setlocal enabledelayedexpansionREM 设置输出文件 set outputFilenetwork_info.txtREM 清空或创建输出文件 echo Scanning network from 192.168.20.1…...
神经网络之词嵌入模型(基于torch api调用)
一、Word Embedding(词嵌入)简介 Word Embedding(词嵌入): 词嵌入技术是自然语言处理(NLP)领域的一项重大创新,它极大地推动了计算机理解和处理人类语言的能力。 通过将单词、句子甚…...
微服务即时通信系统---(七)文件管理子服务
目录 功能设计 模块划分 业务接口/功能示意图 服务实现流程 服务代码实现 封装文件操作模块(utils.hpp) 获取唯一标识ID 文件读操作 文件写操作 编写proto文件 文件元信息 文件管理proto 单文件上传 多文件上传 单文件下载 多文件下载 RPC调用 服务端创建子…...
鸿蒙5.0实战案例:基于原生能力获取视频缩略图
往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录) ✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~ ✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ ✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景&#…...
《Canvas修仙传·第三重天金丹境(下集)》 ——量子烟花与物理宇宙的混沌法则
各位道友久候!上集我们炼就了《灵蛇奇谭》的元神,今日将开启Canvas修仙路上最绚丽的篇章——掌控微观粒子的创世之力!(ノ≧∀≦)ノ 章前黑话词典 🔍 量子境术语表: 对象池(Object Po…...
Hutool - POI:让 Excel 与 Word 操作变得轻而易举
各位开发者们,在日常的 Java 开发工作里,处理 Excel 和 Word 文件是相当常见的需求。无论是从 Excel 里读取数据进行分析,还是将数据写入 Excel 生成报表,亦或是对 Word 文档进行内容编辑,传统的 Apache POI 库虽然功能…...
请谈谈 Node.js 中的流(Stream)模块,如何使用流进行数据处理?
1. Node.js中的流(Stream)模块 流的基本概念: 流是 Node.js 中用于处理流式数据的抽象接口。 它是一种高效的数据处理机制,适合处理大文件或高数据吞吐量的场景。 流主要有四种类型: Readable:可读流&am…...
DeepSeek 202502 开源周合集
DeepSeek 本周的开源项目体现了其在 AI 技术栈中的深厚积累,从硬件协同优化(FlashMLA)、通信库(DeepEP)、核心计算(DeepGEMM)到推理模型(DeepSeek-R1),覆盖了…...
《从0到1:用Python在鸿蒙系统开发安防图像分类AI功能》
在人工智能与移动应用深度融合的当下,类目标签AI功能成为众多行业提升效率和用户体验的关键技术。本文聚焦于HarmonyOS NEXT API 12及以上版本,以图像分类在智能家居安防领域的应用为例,为开发者详细阐述如何利用Python开发类目标签AI功能,助力鸿蒙技术在该领域的创新应用。…...
【机器学习chp10】降维——(核化)PCA + MDS + lsomap + 拉普拉斯特征映射 + t-NSE + UMAP
目录 一、降维的意义与本质 1、意义 2、本质 3、常见降维方法 (1)线性降维 (2)非线性降维 二、基于重构的降维 1、PCA 2、核化PCA (1)实现过程 步骤一:数据映射与核函数定义 步骤二…...
Visual Studio 2022 常用快捷键
1. 格式化代码:ctrl K,ctrl f 2. 向下插入一行:ctrl shift 回车 3. 全部变成大写:ctrl shift U 4. 全部变成小写:ctrl U 5. 查找: ctrl f 6. 删除当前行: ctrl shi…...
JavaWeb——CSS
一、什么是CSS CSS(Cascading Style Sheet):层叠样式表,是一种用于描述网页内容外观和样式的语言,主要用于控制网页的布局、颜色、字体、间距、动画等视觉效果。 CSS基本语法: CSS基本语法十分简单,基本由以下几个部分…...
Oracle 数据库基础入门(四):分组与联表查询的深度探索(下)
在 Oracle 数据库的操作中,联合查询与子查询是获取复杂数据的关键手段。当单表数据无法满足业务需求时,联合查询允许我们从多张表中提取关联信息,而子查询则能以嵌套的方式实现更灵活的数据筛选。对于 Java 全栈开发者而言,掌握这…...
【欢迎来到Git世界】Github入门
241227 241227 241227 Hello World 参考:Hello World - GitHub 文档. 1.创建存储库 r e p o s i t o r y repository repository(含README.md) 仓库名需与用户名一致。 选择公共。 选择使用Readme初始化此仓库。 2.何时用分支…...
从矩阵乘法探秘Transformer
目录 前言1. transformer背景1.1 回顾线性代数的知识1.1.1 矩阵和行向量1.1.2 矩阵相乘和算子作用1.1.3 从分块矩阵的乘法来看 Q K T V QK^TV QKTV 1.2 encoder-decoder1.3 低阶到高阶语义向量的转换1.4 核心的问题 2. transformer网络结构2.1 基于KV查询的相似性计算2.2 在一个…...
【前端基础】Day 3 CSS-2
目录 1. Emmet语法 1.1 快速生成HTML结构语法 1.2 快速生成CSS样式语法 2. CSS的复合选择器 2.1 后代选择器 2.2 子选择器 2.3 并集选择器 2.4 伪类选择器 2.4.1 链接伪类选择器 2.4.2 focus伪类选择器 2.5 复合选择器总结 3. CSS的元素显示模式 3.1 什么是元素显示…...
Difyにboto3を変更したカスタムDockerイメージの構築手順
Difyにboto3を変更したカスタムDockerイメージの構築手順 はじめに1. Dockerfileの作成2. Dockerイメージのビルド3. docker-compose.yamlの更新変更点: 4. コンテナの再起動注意事項まとめ はじめに DifyのDockerイメージに特定バージョンのboto3を変更する手順を…...
C++ 类和对象(上)
Hello!!!大家早上中午晚上好!!!今天我们来复习C中最重要的内容之一:类和对象!! 一、类的定义 1.1语法 类定义关键字class 类名 {//括号体类定义成员变量或成员函数}&…...
虚拟机快照与linux的目录结构
虚拟机快照是对虚拟机某一时刻状态的完整捕获,包括内存、磁盘、配置及虚拟硬件状态等,保存为独立文件。 其作用主要有数据备份恢复、方便系统测试实验、用于灾难恢复以及数据对比分析。具有快速创建和恢复、占用空间小、可多个快照并存的特点。在管理维…...
代码随想录算法训练营第三十天 | 卡码网46.携带研究材料(二维解法)、卡码网46.携带研究材料(滚动数组)、LeetCode416.分割等和子集
代码随想录算法训练营第三十天 | 卡码网46.携带研究材料(二维解法)、卡码网46.携带研究材料(滚动数组)、LeetCode416.分割等和子集 01-1 卡码网46.携带研究材料(二维) 相关资源 题目链接:46. 携…...
计算机基础:二进制基础03,二进制数的位基和位权
专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏,故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 (一)WIn32 专栏导航 上一篇:计算机基础:二进制基础02,用二进制来计数…...
知识库技术选型:主流Embedding模型特性对比
知识库技术选型:主流Embedding模型特性对比 1. 知识库与大模型结合的背景 知识库是存储和管理结构化知识的系统,广泛应用于问答系统、推荐系统和搜索引擎等领域。随着大语言模型(LLM)的发展,知识库与大模型的结合成为…...
鸿蒙开发第4篇__关于在鸿蒙应用中使用Java语言进行设计
本博文对于鸿蒙APP程序员来说,很重要 HarmonyOS从 API8 开始不再支持使用Java作为开发语言,未来的新功能将在ArkTS中实现. API 8对应的是HarmonyOS 3.0.0版本, 2022年7月27日, 华为发布了HarmonyOS 3.0。 请看下图: 因此&#…...
监控视频流web端播放
最近在弄一个视频监测系统,核心功能之一就是视频监控查看。选择的方案是FFMPEGRTSP2web组合。 1、环境搭建&前期准备: 准备好软件,(ffmpeg网上很多,大家自己去下载吧,rtsp-server已上传,方…...
Java中的泛型类 --为集合的学习做准备
学习目标 ● 掌握在集合中正确使用泛型 ● 了解泛型类、泛型接口、泛型方法 ● 了解泛型上下限 ● 了解基本的使用场景 1.有关泛型 1.1泛型的概念 泛型(Generics)是Java中引入的参数化类型机制,允许在定义类、接口或方法时使用类型参数&a…...
【MySQL】表的基本操作
??表的基本操作 文章目录: 表的基本操作 创建查看表 创建表 查看表结构 表的修改 表的重命名 表的添加与修改 删除表结构 总结 前言: 在数据库中,数据表是存储和组织数据的基本单位,对于数据表的操作是每个程序员需要烂熟…...
横向移动靶场-Tr0ll: 3
Tr0ll: 3来自 <Tr0ll: 3 ~ VulnHub> 1,将两台虚拟机网络连接都改为NAT模式 2,攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.182,靶场IP192.168.23.187 3,对靶机进行端口服务探测 …...
房屋租赁|房屋租赁系统|基于Springboot的房屋租赁系统设计与实现(源码+数据库+文档)
房屋租赁系统目录 目录 基于Springboot的房屋租赁系统设计与实现 一、前言 二、系统功能设计 三、系统实现 管理员功能模块 房主功能模块 用户功能模块 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取:…...
自然语言处理:词频-逆文档频率
介绍 大家好,博主又来给大家分享知识了。本来博主计划完成稠密向量表示的内容分享后,就开启自然语言处理中文本表示的讲解。可在整理分享资料的时候,博主发现还有个知识点,必须得单独拎出来好好说道说道。 这就是TF-IDF…...
Linux | 程序 / 进程调用库依赖关系查看
注:本文为 “Linux | 程序 / 进程调用库依赖” 相关文章合辑。 英文引文,机翻未校。 未整理去重。 How to Check Library Dependencies in Linux 如何在 Linux 系统中检查库依赖关系 Mohd Shakir Zakaria Programs on Linux often require external…...
3-4 WPS JS宏 工作表的新建、删除与错务内容处理(批量新建工作表)学习笔记
************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…...
泰勒公式详解与应用
前言 本文隶属于专栏《机器学习数学通关指南》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见《机器学习数学通关指南》 正文 📝 一句话总结 泰…...
计算机视觉(opencv-python)入门之图像的读取,显示,与保存
在计算机视觉领域,Python的cv2库是一个不可或缺的工具,它提供了丰富的图像处理功能。作为OpenCV的Python接口,cv2使得图像处理的实现变得简单而高效。 示例图片 目录 opencv获取方式 图像基本知识 颜色空间 RGB HSV 图像格式 BMP格式 …...
现代前端框架渲染机制深度解析:虚拟DOM到编译时优化
引言:前端框架的性能进化论 TikTok Web将React 18迁移至Vue 3后,点击响应延迟降低42%,内存占用减少35%。Shopify采用Svelte重构核心交互模块,首帧渲染速度提升580%。Discord在Next.js 14中启用React Server Components后…...
Selenium自动化测试:如何搭建自动化测试环境,搭建环境过程应该注意的问题
最近也有很多人私下问我,selenium学习难吗,基础入门的学习内容很多是3以前的版本资料,对于有基础的人来说,3到4的差别虽然有,但是不足以影响自己,但是对于没有学过的人来说,通过资料再到自己写的…...
Linux服务升级:Almalinux 升级 DeepSeek-R1
目录 一、实验 1.环境 2.Almalinux 部署 Ollama 3.Almalinux 升级 DeepSeek-R1 4.Almalinux 部署 docker 5. docker 部署 DeepSeek-R1 6.Almalinux 部署 Cpolar (内网穿透) 7.使用cpolar内网穿透 二、问题 1.构建容器失败 一、实验 1.环境 (1)…...
《HelloGitHub》第 107 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言 Python、…...
【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.3.2Kibana可视化初探
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 10分钟快速部署Kibana可视化平台1. Kibana与Elasticsearch关系解析1.1 架构关系示意图1.2 核心功能矩阵 2. 系统环境预检2.1 硬件资源配置2.2 软件依赖清单 3. Docker快速部…...
网络七层模型—OSI参考模型详解
网络七层模型:OSI参考模型详解 引言 在网络通信的世界中,OSI(Open Systems Interconnection)参考模型是一个基础且核心的概念。它由国际标准化组织(ISO)于1984年提出,旨在为不同厂商的设备和应…...
老旧android项目编译指南(持续更)
原因 编译了很多项目,找到了一些可观的解决办法 1. android studio里面的jdk版本切换 jdk版本切换在这里,一般安卓开发需要用到4个版本的jdk,jdk8, jdk11, jdk17, jdk21新版的android stuio是默认使用高版本的jdk,所以切换版本是很有必要的 2. 命令…...
测试金蝶云的OpenAPI
如何使用Postman测试K3Cloud的OpenAPI 1. 引言 在本篇博客中,我将带你逐步了解如何使用Postman测试和使用K3Cloud的OpenAPI。内容包括下载所需的SDK文件、配置文件、API调用及测试等步骤。让我们开始吧! 2. 下载所需的SDK文件 2.1 获取SDK 首先&…...
从零基础到通过考试
1. 学习资源与实践平台 使用Proving Grounds进行靶机练习 OSCP的备考过程中,实战练习占据了非常重要的地位。Proving Grounds(PG)是一个由Offensive Security提供的练习平台,拥有152个靶机,涵盖了从基础到进阶的多种…...