1. 准备工作

首先确保服务器已安装JDK:

java -version

如未安装,请执行:

sudo apt-get update
sudo apt-get install openjdk-8-jdk   # Ubuntu/Debian
# 或
sudo yum install java-1.8.0-openjdk  # CentOS/RHEL

2. 下载ZooKeeper 3.8.4

# 创建安装目录
mkdir -p /opt/zookeeper

# 下载ZooKeeper 3.8.4
cd /opt
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz

# 解压
tar -zxf apache-zookeeper-3.8.4-bin.tar.gz -C /opt/zookeeper

3. 创建伪集群目录结构

在单台服务器上创建三个独立的ZooKeeper实例:

# 创建三个实例的数据和日志目录
mkdir -p /opt/zookeeper/zk1/data
mkdir -p /opt/zookeeper/zk1/logs
mkdir -p /opt/zookeeper/zk2/data
mkdir -p /opt/zookeeper/zk2/logs
mkdir -p /opt/zookeeper/zk3/data
mkdir -p /opt/zookeeper/zk3/logs

# 复制配置文件
cp /opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg /opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo1.cfg
cp /opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg /opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo2.cfg
cp /opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo_sample.cfg /opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo3.cfg

4. 配置三个ZooKeeper实例

配置第一个实例 (zoo1.cfg)

vi /opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo1.cfg

内容如下:

# 基本配置
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/zookeeper/zk1/data
dataLogDir=/opt/zookeeper/zk1/logs
clientPort=2181
admin.serverPort=8081

# 集群配置
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890

# 开启四字命令
4lw.commands.whitelist=*

配置第二个实例 (zoo2.cfg)

vi /opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo2.cfg

内容如下:

# 基本配置
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/zookeeper/zk2/data
dataLogDir=/opt/zookeeper/zk2/logs
clientPort=2182
admin.serverPort=8082

# 集群配置
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890

# 开启四字命令
4lw.commands.whitelist=*

配置第三个实例 (zoo3.cfg)

vi /opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo3.cfg

内容如下:

# 基本配置
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/zookeeper/zk3/data
dataLogDir=/opt/zookeeper/zk3/logs
clientPort=2183
admin.serverPort=8083

# 集群配置
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890

# 开启四字命令
4lw.commands.whitelist=*

5. 创建myid文件

为每个实例创建myid文件:

# 实例1
echo "1" > /opt/zookeeper/zk1/data/myid

# 实例2
echo "2" > /opt/zookeeper/zk2/data/myid

# 实例3
echo "3" > /opt/zookeeper/zk3/data/myid

6. 创建启动和停止脚本

创建启动脚本

vi /opt/zookeeper/start-zk-cluster.sh

内容如下:

#!/bin/bash

ZK_HOME="/opt/zookeeper/apache-zookeeper-3.8.4-bin"

# 启动第一个实例
$ZK_HOME/bin/zkServer.sh start $ZK_HOME/conf/zoo1.cfg
sleep 2

# 启动第二个实例
$ZK_HOME/bin/zkServer.sh start $ZK_HOME/conf/zoo2.cfg
sleep 2

# 启动第三个实例
$ZK_HOME/bin/zkServer.sh start $ZK_HOME/conf/zoo3.cfg

echo "ZooKeeper集群已启动"

创建停止脚本

vi /opt/zookeeper/stop-zk-cluster.sh

内容如下:

#!/bin/bash

ZK_HOME="/opt/zookeeper/apache-zookeeper-3.8.4-bin"

# 停止三个实例
$ZK_HOME/bin/zkServer.sh stop $ZK_HOME/conf/zoo1.cfg
$ZK_HOME/bin/zkServer.sh stop $ZK_HOME/conf/zoo2.cfg
$ZK_HOME/bin/zkServer.sh stop $ZK_HOME/conf/zoo3.cfg

echo "ZooKeeper集群已停止"

创建状态检查脚本

vi /opt/zookeeper/status-zk-cluster.sh

内容如下:

#!/bin/bash

ZK_HOME="/opt/zookeeper/apache-zookeeper-3.8.4-bin"

echo "===== ZooKeeper实例1状态 ====="
$ZK_HOME/bin/zkServer.sh status $ZK_HOME/conf/zoo1.cfg
echo ""

echo "===== ZooKeeper实例2状态 ====="
$ZK_HOME/bin/zkServer.sh status $ZK_HOME/conf/zoo2.cfg
echo ""

echo "===== ZooKeeper实例3状态 ====="
$ZK_HOME/bin/zkServer.sh status $ZK_HOME/conf/zoo3.cfg

设置脚本执行权限

chmod +x /opt/zookeeper/start-zk-cluster.sh
chmod +x /opt/zookeeper/stop-zk-cluster.sh
chmod +x /opt/zookeeper/status-zk-cluster.sh

7. 启动ZooKeeper集群

/opt/zookeeper/start-zk-cluster.sh

8. 验证集群状态

/opt/zookeeper/status-zk-cluster.sh

正常情况下,一个节点应该是leader,其他两个是follower。

9. 测试集群连接

cd /opt/zookeeper/apache-zookeeper-3.8.4-bin/bin

# 连接到第一个实例
./zkCli.sh -server localhost:2181

# 在ZK客户端中创建节点
[zk: localhost:2181(CONNECTED) 0] create /test_node "Hello ZooKeeper"
[zk: localhost:2181(CONNECTED) 1] get /test_node

然后连接到其他实例验证数据同步(新启动一个终端):

# 连接到第二个实例
./zkCli.sh -server localhost:2182

# 验证节点是否同步
[zk: localhost:2182(CONNECTED) 0] get /test_node

10. 配置系统服务(可选)

为了让ZooKeeper集群随系统启动,可以创建systemd服务:

vi /etc/systemd/system/zookeeper-cluster.service

内容如下:

[Unit]
Description=ZooKeeper Cluster Service
After=network.target

[Service]
Type=forking
ExecStart=/opt/zookeeper/start-zk-cluster.sh
ExecStop=/opt/zookeeper/stop-zk-cluster.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target

启用服务:

systemctl daemon-reload
systemctl enable zookeeper-cluster.service
systemctl start zookeeper-cluster.service

11. 监控ZooKeeper集群

使用四字命令监控

# 查看服务器状态
echo stat | nc localhost 2181
echo mntr | nc localhost 2181

# 查看连接情况
echo cons | nc localhost 2181

# 查看服务器配置
echo conf | nc localhost 2181

配置JMX监控(可选)

编辑zkServer.sh脚本,添加JMX配置:

vi /opt/zookeeper/apache-zookeeper-3.8.4-bin/bin/zkServer.sh

在ZOOMAIN变量定义前添加:

# 为每个实例设置不同的JMX端口
if [ "x$ZOOCFG" = "x/opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo1.cfg" ]; then
  JMXPORT=9991
elif [ "x$ZOOCFG" = "x/opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo2.cfg" ]; then
  JMXPORT=9992
elif [ "x$ZOOCFG" = "x/opt/zookeeper/apache-zookeeper-3.8.4-bin/conf/zoo3.cfg" ]; then
  JMXPORT=9993
else
  JMXPORT=9999
fi

JMXLOCALONLY=false
JVMFLAGS="$JVMFLAGS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=$JMXLOCALONLY -Dcom.sun.management.jmxremote.port=$JMXPORT -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"

重启集群后,可以使用JConsole或VisualVM连接JMX端口进行监控。

12. 故障排除

日志查看

# 查看第一个实例的日志
tail -f /opt/zookeeper/zk1/logs/zookeeper*.out

# 查看第二个实例的日志
tail -f /opt/zookeeper/zk2/logs/zookeeper*.out

# 查看第三个实例的日志
tail -f /opt/zookeeper/zk3/logs/zookeeper*.out

常见问题解决

  1. 端口冲突:确保所有端口(2181-2183, 2888-2890, 3888-3890, 8081-8083)未被其他程序占用
       netstat -tulpn | grep <port>
  1. 无法启动:检查日志文件中的错误信息
       cat /opt/zookeeper/zk*/logs/zookeeper*.out
  1. 节点无法加入集群:检查myid文件和zoo.cfg配置是否正确
  1. 内存不足:调整JVM堆大小
       export ZK_SERVER_HEAP="512M"

这样,您就在单台Linux服务器上成功搭建了一个由三个节点组成的ZooKeeper 3.8.4伪集群。该集群可以提供高可用性,即使其中一个节点失败,集群仍然可以正常工作。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐