zookeeper集群原理与概述
zookeeper集群原理
zookeeper的leader选举
zookeeper服务端状态
looking: 寻找leader状态,当服务器处于该状态时,它会认为当前集群中没有leader,因此需要进入leader选举状态。
leading: 领导者状态,表明当前服务器角色时leader。
following: 跟随着状态,表明当前服务器角色时follower。
observing: 观察者状态,表明当前服务器角色时observer。
zookeeper集群启动时期的leader选举
在集群初始化节点,当有一台服务器zk101启动时,其单独无法进行和完成leader选举,当第二台服务器zk102启动时,此时两台机器就可以相互通信,每台机器都试图找到leader,于是进入leader选举过程。
zookeeper集群启动时期的leader选举过程如下所示:
- 每个server发出一个投票,由于初始情况,zk101和zk102都会将自己作为leader服务器来进行投票,每次投票会包含所推举的服务器myid和zxid,使用(myid,zxid)来表示,此时zk101投票为(101,0),zk102的投票为(102,0),然后各自将跟这个投票发给集群的其它机器;
myid: 表示当前zookeeper server的server id。
zxid: 表示zookeeper transaction id,即zookeeper事务ID。 - 集群中每台服务器接收来自集群中各个服务器的投票;
- 处理投票,针对每一个投票,服务器都需要将别人的的投票和自己的投票进行pk,pk的规则如下:
(1)优先检查zxid,zxid比较大的服务器优先作为leader;
(2)如果zxid相同,那么就比较myid,myid较大的服务器作为leader服务器;
综上所述,我们可以针对zk101和zk102选举的过程如下:
对于zk101而言,它的投票是"(101,0)",接收zk102的投票为"(102,0)",首先会比较两者的zxid,均为0,再比较myid,此时zk102的myid最大,于是zk101节点需要更新自己的投票为"(102,0)"。
对于zk102而言,它的投票是"(102,0)",接收zk101的投票为"(101,0)",很明显zk101的myid较小,因此zk102无需更新字节的投票,只是再次向集群中所有机器上发送一次投票信息即可; - 统计投票,每次投票后,服务器都会统计投票信息,判断是否已经有过半机器(如果集群只有3台,那么过半就是2台服务器)接收到相同的投票信息,对于zk101和zk102而言,都统计出集群中已经有两台机器接收了(102,0)的投票信息,此时认为已经选出来leader;
- 改变服务器状态,一旦确定了leader,每个zookeeper服务器就会更新自己的状态,如果是follower,那么就变更为following,如果是leader,就变更为leading。
判断是否已经有过半机器接收到相同的投票信息:
假设集群可参与投票的服务器数量为N,那么过半机器数量计算方式为: (N / 2 + 1)。我们的集群只有3台,那么过半就是2台服务器。
zookeeper集群运行时期的leader选举
在zookeeper运行期间,leader与非leader服务器各司其职,即便当有非leader服务器宕机或新加入,此时也不会影响leader。
但是一旦leader服务器挂了,那么这个集群将暂停对外服务,当剩余节点数大于原集群半数节点时,则zookeeper集群可以进入新一轮leader选举,其过程和启动时期的leader选举过程基本一致。
假设正在运行的有zk101,zk102,zk103这三台服务器,当leader是zk102,若某一时刻leader挂了,此时便开始leader选举,其过程如下:
- 变更状态,leader挂后,余下的服务器都会将自己的服务器状态变更为looking,然后开始进入leader选举过程;
- 每个server会发出一个投票,在运行期间,每个服务器上的zxid可能不同,此时假定zk101的zxid为"996",zk103的zxid为"965",在第一轮投票中,zk101和zk103都会投自己,产生投票(101,996),(103,965),然后各自将投票发送给集群中所有机器;
- 接收来自各个服务器的投票,与启动时过程相同;
- 处理投票,与启动过程相同,此时zk101将会成为leader;
- 统计投票,与启动时过程相同;
- 改变服务器的状态,与启动时过程相同;
zookeeper原子广播协议
zookeeper集群的角色
leader(领导者): 领导者负责进行投票的发起和决议,更新系统状态。
follower(跟随者): 用于接收客户请求并向客户端返回结果,将写请求转发给leader节点。在选主过程中参与投票。
obServer(观察者): 可以接收客户端连接,将写请求转发给leader节点。这是集群的可选组件。obServer不参加投票过程,只同步leader的状态。obServer的目的是为了扩展系统,提高读取速度。
client(客户端): 向zookeeper集群发起连接请求的一方。
zab协议的工作原理(写数据流程介绍)
zab协议的全称是"Zookeeper Atomic Broadcast"(zookeeper原子广播)。zookeeper是通过zab协议来保证分布式事务的最终一致性。zab是基于广播模式工作的,通过类似两阶段提交协议的方式解决数据一致性。
如下图所示,zab其工作原理如下:
- leader从客户端收到一个写请求;
- leader生成一个新的事务并为这个事务生成一个唯一的ZXID;
- leader将这个事务提议(propose)发送给所有的follows节点;
- follower节点收到的事务请求加入到历史队列(history queue)中,并发送ack给leader;
- 当leader收到大多数follower(集群中半数以上节点)的ack消息后,leader会发送commit请求;
- 当follower收到commit请求时,从历史队列中将事务请求commit;
zookeeper集群部署
部署zookeeper服务(三台都操作)
关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
vim /etc/selinux/config
SELINUX=disabled
安装JDK并配置环境变量
tar -xf jdk-8u401-linux-x64.tar.gz -C /usr/local/
cd /usr/local/
mv jdk1.8.0_401/ jdk
vim /etc/profile
JAVA_HOME=/usr/local/jdk
PATH=$JAVA_HOME/bin:$PATH
source /etc/profile
java -version
安装zookeeper并配置环境变量
tar -xf apache-zookeeper-3.7.0-bin.tar.gz -C /usr/local/
cd /usr/local/
mv apache-zookeeper-3.7.0-bin/ zookeeper
vim /etc/profile
PATH=/usr/local/zookeeper/bin:$PATH
source /etc/profile
部署集群的时间同步服务器
yum install -y ntpdate
ntpdate ntp.aliyun.com
zookeeper集群构建
修改zookeeper的配置文件
# 三台机器拷贝复制配置文件
cd /usr/local/zookeeper/conf/
cp zoo_sample.cfg zoo.cfg
# 修改10.0.0.123节点的配置文件
egrep -v "^#|^$" /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
clientPortAddress=10.0.0.123
server.01=10.0.0.123:2888:3888
server.02=10.0.0.124:2888:3888
server.03=10.0.0.125:2888:3888
# 修改10.0.0.124节点的配置文件
egrep -v "^#|^$" /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
clientPortAddress=10.0.0.124
server.01=10.0.0.123:2888:3888
server.02=10.0.0.124:2888:3888
server.03=10.0.0.125:2888:3888
# 修改10.0.0.125节点的配置文件
egrep -v "^#|^$" /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
clientPortAddress=10.0.0.125
server.01=10.0.0.123:2888:3888
server.02=10.0.0.124:2888:3888
server.03=10.0.0.125:2888:3888
# 三个节点创建数据目录
mkdir /data/zookeeper -p
配置zookeeper的堆内存配置文件
# 三个节点都配置:
vim /usr/local/zookeeper/conf/java.env
#!/bin/bash
#指定JDK的安装路径
export JAVA_HOME=/usr/local/jdk
#指定zookeeper的heap内存大小
export JVMFLAGS="-Xms256m -Xmx256m $JVMFLAGS"
创建myid文件并写入服务器编号
echo 01 > /data/zookeeper/myid
echo 02 > /data/zookeeper/myid
echo 03 > /data/zookeeper/myid
启动连接zookeeper服务
# 三个节点同时启动:
zkServer.sh start
# 查看状态:
zkServer.sh status
# 连接zookeeper集群
zkCli.sh -server 10.0.0.123:2181,10.0.0.124:2181,10.0.0.125:2181
Connecting to 10.0.0.123:2181,10.0.0.124:2181,10.0.0.125:2181
2025-07-17 12:12:10,404 [myid:] - INFO [main:Environment@98] - Client environment:zookeeper.version=3.7.0-e3704b390a6697bfdf4b0bef79e3da7a4f6bac4b, built on 2021-03-17 09:46 UTC
2025-07-17 12:12:10,407 [myid:] - INFO [main:Environment@98] - Client environment:host.name=iZuf62y6ofk4qtcldqm37mZ
2025-07-17 12:12:10,407 [myid:] - INFO [main:Environment@98] - Client environment:java.version=1.8.0_401
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:java.vendor=Oracle Corporation
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:java.home=/usr/local/jdk/jre
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:java.class.path=/usr/local/zookeeper/bin/../zookeeper-server/target/classes:/usr/local/zookeeper/bin/../build/classes:/usr/local/zookeeper/bin/../zookeeper-server/target/lib/*.jar:/usr/local/zookeeper/bin/../build/lib/*.jar:/usr/local/zookeeper/bin/../lib/zookeeper-prometheus-metrics-3.7.0.jar:/usr/local/zookeeper/bin/../lib/zookeeper-jute-3.7.0.jar:/usr/local/zookeeper/bin/../lib/zookeeper-3.7.0.jar:/usr/local/zookeeper/bin/../lib/snappy-java-1.1.7.7.jar:/usr/local/zookeeper/bin/../lib/slf4j-log4j12-1.7.30.jar:/usr/local/zookeeper/bin/../lib/slf4j-api-1.7.30.jar:/usr/local/zookeeper/bin/../lib/simpleclient_servlet-0.9.0.jar:/usr/local/zookeeper/bin/../lib/simpleclient_hotspot-0.9.0.jar:/usr/local/zookeeper/bin/../lib/simpleclient_common-0.9.0.jar:/usr/local/zookeeper/bin/../lib/simpleclient-0.9.0.jar:/usr/local/zookeeper/bin/../lib/netty-transport-native-unix-common-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-transport-native-epoll-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-transport-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-resolver-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-handler-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-common-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-codec-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-buffer-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/metrics-core-4.1.12.1.jar:/usr/local/zookeeper/bin/../lib/log4j-1.2.17.jar:/usr/local/zookeeper/bin/../lib/jline-2.14.6.jar:/usr/local/zookeeper/bin/../lib/jetty-util-ajax-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-util-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-servlet-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-server-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-security-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-io-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-http-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/javax.servlet-api-3.1.0.jar:/usr/local/zookeeper/bin/../lib/jackson-databind-2.10.5.1.jar:/usr/local/zookeeper/bin/../lib/jackson-core-2.10.5.jar:/usr/local/zookeeper/bin/../lib/jackson-annotations-2.10.5.jar:/usr/local/zookeeper/bin/../lib/commons-cli-1.4.jar:/usr/local/zookeeper/bin/../lib/audience-annotations-0.12.0.jar:/usr/local/zookeeper/bin/../zookeeper-*.jar:/usr/local/zookeeper/bin/../zookeeper-server/src/main/resources/lib/*.jar:/usr/local/zookeeper/bin/../conf:
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:java.io.tmpdir=/tmp
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:java.compiler=<NA>
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:os.name=Linux
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:os.arch=amd64
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:os.version=3.10.0-1160.119.1.el7.x86_64
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:user.name=root
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:user.home=/root
2025-07-17 12:12:10,409 [myid:] - INFO [main:Environment@98] - Client environment:user.dir=/root
2025-07-17 12:12:10,410 [myid:] - INFO [main:Environment@98] - Client environment:os.memory.free=237MB
2025-07-17 12:12:10,411 [myid:] - INFO [main:Environment@98] - Client environment:os.memory.max=247MB
2025-07-17 12:12:10,411 [myid:] - INFO [main:Environment@98] - Client environment:os.memory.total=247MB
2025-07-17 12:12:10,415 [myid:] - INFO [main:ZooKeeper@637] - Initiating client connection, connectString=10.0.0.123:2181,10.0.0.124:2181,10.0.0.125:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@768debd
2025-07-17 12:12:10,420 [myid:] - INFO [main:X509Util@77] - Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation
2025-07-17 12:12:10,424 [myid:] - INFO [main:ClientCnxnSocket@239] - jute.maxbuffer value is 1048575 Bytes
2025-07-17 12:12:10,433 [myid:] - INFO [main:ClientCnxn@1726] - zookeeper.request.timeout value is 0. feature enabled=false
Welcome to ZooKeeper!
2025-07-17 12:12:10,438 [myid:10.0.0.123:2181] - INFO [main-SendThread(10.0.0.123:2181):ClientCnxn$SendThread@1171] - Opening socket connection to server iZuf62y6ofk4qtcldqm37mZ/10.0.0.123:2181.
2025-07-17 12:12:10,438 [myid:10.0.0.123:2181] - INFO [main-SendThread(10.0.0.123:2181):ClientCnxn$SendThread@1173] - SASL config status: Will not attempt to authenticate using SASL (unknown error)
2025-07-17 12:12:10,443 [myid:10.0.0.123:2181] - INFO [main-SendThread(10.0.0.123:2181):ClientCnxn$SendThread@1005] - Socket connection established, initiating session, client: /10.0.0.123:37814, server: iZuf62y6ofk4qtcldqm37mZ/10.0.0.123:2181
JLine support is enabled
2025-07-17 12:12:10,491 [myid:10.0.0.123:2181] - INFO [main-SendThread(10.0.0.123:2181):ClientCnxn$SendThread@1438] - Session establishment complete on server iZuf62y6ofk4qtcldqm37mZ/10.0.0.123:2181, session id = 0x100001595aa0000, negotiated timeout = 30000
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: 10.0.0.123:2181,10.0.0.124:2181,10.0.0.125:2181(CONNECTED) 0] ls /
[zookeeper]
observer角色及其配置
observer角色特点
- 不参与集群的leader选举;
- 不参与集群中写数据时的ack反馈;
修改配置文件
egrep -v "^#|^$" /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
clientPortAddress=10.0.0.123
server.01=10.0.0.123:2888:3888:observer
server.02=10.0.0.124:2888:3888
server.03=10.0.0.125:2888:3888
egrep -v "^#|^$" /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
clientPortAddress=10.0.0.124
server.01=10.0.0.123:2888:3888:observer
server.02=10.0.0.124:2888:3888
server.03=10.0.0.125:2888:3888
egrep -v "^#|^$" /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
clientPortAddress=10.0.0.125
server.01=10.0.0.123:2888:3888:observer
server.02=10.0.0.124:2888:3888
server.03=10.0.0.125:2888:3888
重启并连接集群
# 三个节点都需要重启
zkServer.sh restart
# 查看集群状态
zkServer.sh status
# 连接observer节点
zkCli.sh -server 10.0.0.123:2181
Connecting to 10.0.0.123:2181
2025-07-17 12:16:29,108 [myid:] - INFO [main:Environment@98] - Client environment:zookeeper.version=3.7.0-e3704b390a6697bfdf4b0bef79e3da7a4f6bac4b, built on 2021-03-17 09:46 UTC
2025-07-17 12:16:29,111 [myid:] - INFO [main:Environment@98] - Client environment:host.name=iZuf62y6ofk4qtcldqm37mZ
2025-07-17 12:16:29,111 [myid:] - INFO [main:Environment@98] - Client environment:java.version=1.8.0_401
2025-07-17 12:16:29,112 [myid:] - INFO [main:Environment@98] - Client environment:java.vendor=Oracle Corporation
2025-07-17 12:16:29,112 [myid:] - INFO [main:Environment@98] - Client environment:java.home=/usr/local/jdk/jre
2025-07-17 12:16:29,112 [myid:] - INFO [main:Environment@98] - Client environment:java.class.path=/usr/local/zookeeper/bin/../zookeeper-server/target/classes:/usr/local/zookeeper/bin/../build/classes:/usr/local/zookeeper/bin/../zookeeper-server/target/lib/*.jar:/usr/local/zookeeper/bin/../build/lib/*.jar:/usr/local/zookeeper/bin/../lib/zookeeper-prometheus-metrics-3.7.0.jar:/usr/local/zookeeper/bin/../lib/zookeeper-jute-3.7.0.jar:/usr/local/zookeeper/bin/../lib/zookeeper-3.7.0.jar:/usr/local/zookeeper/bin/../lib/snappy-java-1.1.7.7.jar:/usr/local/zookeeper/bin/../lib/slf4j-log4j12-1.7.30.jar:/usr/local/zookeeper/bin/../lib/slf4j-api-1.7.30.jar:/usr/local/zookeeper/bin/../lib/simpleclient_servlet-0.9.0.jar:/usr/local/zookeeper/bin/../lib/simpleclient_hotspot-0.9.0.jar:/usr/local/zookeeper/bin/../lib/simpleclient_common-0.9.0.jar:/usr/local/zookeeper/bin/../lib/simpleclient-0.9.0.jar:/usr/local/zookeeper/bin/../lib/netty-transport-native-unix-common-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-transport-native-epoll-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-transport-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-resolver-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-handler-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-common-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-codec-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/netty-buffer-4.1.59.Final.jar:/usr/local/zookeeper/bin/../lib/metrics-core-4.1.12.1.jar:/usr/local/zookeeper/bin/../lib/log4j-1.2.17.jar:/usr/local/zookeeper/bin/../lib/jline-2.14.6.jar:/usr/local/zookeeper/bin/../lib/jetty-util-ajax-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-util-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-servlet-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-server-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-security-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-io-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/jetty-http-9.4.38.v20210224.jar:/usr/local/zookeeper/bin/../lib/javax.servlet-api-3.1.0.jar:/usr/local/zookeeper/bin/../lib/jackson-databind-2.10.5.1.jar:/usr/local/zookeeper/bin/../lib/jackson-core-2.10.5.jar:/usr/local/zookeeper/bin/../lib/jackson-annotations-2.10.5.jar:/usr/local/zookeeper/bin/../lib/commons-cli-1.4.jar:/usr/local/zookeeper/bin/../lib/audience-annotations-0.12.0.jar:/usr/local/zookeeper/bin/../zookeeper-*.jar:/usr/local/zookeeper/bin/../zookeeper-server/src/main/resources/lib/*.jar:/usr/local/zookeeper/bin/../conf:
2025-07-17 12:16:29,112 [myid:] - INFO [main:Environment@98] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2025-07-17 12:16:29,112 [myid:] - INFO [main:Environment@98] - Client environment:java.io.tmpdir=/tmp
2025-07-17 12:16:29,112 [myid:] - INFO [main:Environment@98] - Client environment:java.compiler=<NA>
2025-07-17 12:16:29,112 [myid:] - INFO [main:Environment@98] - Client environment:os.name=Linux
2025-07-17 12:16:29,112 [myid:] - INFO [main:Environment@98] - Client environment:os.arch=amd64
2025-07-17 12:16:29,113 [myid:] - INFO [main:Environment@98] - Client environment:os.version=3.10.0-1160.119.1.el7.x86_64
2025-07-17 12:16:29,113 [myid:] - INFO [main:Environment@98] - Client environment:user.name=root
2025-07-17 12:16:29,113 [myid:] - INFO [main:Environment@98] - Client environment:user.home=/root
2025-07-17 12:16:29,113 [myid:] - INFO [main:Environment@98] - Client environment:user.dir=/root
2025-07-17 12:16:29,113 [myid:] - INFO [main:Environment@98] - Client environment:os.memory.free=237MB
2025-07-17 12:16:29,114 [myid:] - INFO [main:Environment@98] - Client environment:os.memory.max=247MB
2025-07-17 12:16:29,114 [myid:] - INFO [main:Environment@98] - Client environment:os.memory.total=247MB
2025-07-17 12:16:29,117 [myid:] - INFO [main:ZooKeeper@637] - Initiating client connection, connectString=10.0.0.123:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@768debd
2025-07-17 12:16:29,121 [myid:] - INFO [main:X509Util@77] - Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation
2025-07-17 12:16:29,125 [myid:] - INFO [main:ClientCnxnSocket@239] - jute.maxbuffer value is 1048575 Bytes
2025-07-17 12:16:29,133 [myid:] - INFO [main:ClientCnxn@1726] - zookeeper.request.timeout value is 0. feature enabled=false
2025-07-17 12:16:29,139 [myid:10.0.0.123:2181] - INFO [main-SendThread(10.0.0.123:2181):ClientCnxn$SendThread@1171] - Opening socket connection to server iZuf62y6ofk4qtcldqm37mZ/10.0.0.123:2181.
2025-07-17 12:16:29,139 [myid:10.0.0.123:2181] - INFO [main-SendThread(10.0.0.123:2181):ClientCnxn$SendThread@1173] - SASL config status: Will not attempt to authenticate using SASL (unknown error)
Welcome to ZooKeeper!
2025-07-17 12:16:29,143 [myid:10.0.0.123:2181] - INFO [main-SendThread(10.0.0.123:2181):ClientCnxn$SendThread@1005] - Socket connection established, initiating session, client: /10.0.0.123:37874, server: iZuf62y6ofk4qtcldqm37mZ/10.0.0.123:2181
JLine support is enabled
2025-07-17 12:16:29,181 [myid:10.0.0.123:2181] - INFO [main-SendThread(10.0.0.123:2181):ClientCnxn$SendThread@1438] - Session establishment complete on server iZuf62y6ofk4qtcldqm37mZ/10.0.0.123:2181, session id = 0x10000462ce80000, negotiated timeout = 30000
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: 10.0.0.123:2181(CONNECTED) 0] ls /
[zookeeper]
如上所示,我们可以连接观察者(observer)节点并写入数据,但我们要知道真正负责写入的是leader节点,写请求被observer转发给leader节点了。