> 技术文档 > zookeeper基础操作--zookeeper的下载、安装,以及基本命令和简单实例操作

zookeeper基础操作--zookeeper的下载、安装,以及基本命令和简单实例操作


一、Zookeeper 简介、应用场景与常用功能

1. Zookeeper 简介

Zookeeper 是一个分布式协调服务,由 Apache 开源,主要用于解决分布式系统中的一致性问题。
核心特点

  • 采用树形文件系统结构(ZNode)存储数据
  • 提供高可用性和顺序一致性
  • 基于 ZAB 协议(Zookeeper Atomic Broadcast)实现数据同步

2. 应用场景

2.1 典型场景

  • 分布式锁:实现互斥访问共享资源
  • 配置中心:集中管理集群配置信息
  • 服务注册与发现(如 Dubbo)
  • 集群选主(Leader Election)
  • 分布式队列

2.2 行业案例

  • Hadoop(YARN 资源管理)
  • Kafka(Broker 元数据管理)
  • HBase(RegionServer 状态跟踪)

3. 常用功能

3.1 基础功能

功能 描述 临时节点(Ephemeral) 客户端断开连接后自动删除 顺序节点(Sequential) 自动追加全局单调递增序号 Watcher 机制 监听节点变化的事件通知

3.2 高级特性

// Java API 示例:创建节点ZooKeeper zk = new ZooKeeper(\"localhost:2181\", 3000, null);zk.create(\"/test_node\", \"data\".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

注意事项

  1. 节点数据大小限制为 1MB
  2. 默认端口 2181(客户端通信)、2888(Leader 选举)、3888(集群通信)
  3. 推荐奇数台服务器组成集群(3/5/7台)

二、Zookeeper下载和安装

1. 下载Zookeeper

访问Apache Zookeeper官网下载页面:
https://zookeeper.apache.org/releases.html

选择稳定版本(例如3.7.1)下载:

https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.7.2/apache-zookeeper-3.7.2-bin.tar.gz
wget https://downloads.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz

2. 安装步骤

2.1 解压安装包

tar -zxvf apache-zookeeper-3.7.1-bin.tar.gzcd apache-zookeeper-3.7.1-bin

2.2 配置Zookeeper

复制示例配置文件并修改:

cp conf/zoo_sample.cfg conf/zoo.cfg

编辑conf/zoo.cfg(主要配置项):

dataDir=/tmp/zookeeperclientPort=2181

2.3 启动服务

bin/zkServer.sh start

2.4 验证运行状态

bin/zkServer.sh status

3. 常用命令

命令 作用 zkServer.sh start 启动服务 zkServer.sh stop 停止服务 zkCli.sh -server 连接客户端

注意:生产环境建议配置集群模式(至少3个节点)并设置dataLogDir

在这里插入图片描述

在这里插入图片描述

三、Zookeeper常用功能和原理

1、常用功能

1.1分布式协调服务

  • 提供分布式环境下的节点协调、状态同步等功能

1.2配置管理

  • 集中式配置存储和动态更新
  • 配置变更通知机制

1.3命名服务

  • 类似DNS的命名系统
  • 通过路径标识资源

1.4集群管理

  • 节点注册与监控
  • 领导者选举(Leader Election)

1.5分布式锁

  • 实现排他锁、共享锁等同步机制

1.6队列管理

  • 实现FIFO队列、屏障等数据结构

2、核心原理

2.1数据模型

  • 采用ZNode树形结构(类似文件系统)
  • 每个ZNode可存储少量数据(默认≤1MB)

2.2Watcher机制

  • 一次性触发的事件通知
  • 客户端可监听ZNode变化

2.3ZAB协议

  • ZooKeeper Atomic Broadcast协议
  • 保证分布式事务的顺序一致性

2.4会话(Session)

  • 客户端与服务端保持TCP长连接
  • 会话超时机制

2.5集群角色

  • Leader: 处理所有写请求
  • Follower: 处理读请求并参与选举
  • Observer: 仅处理读请求(不参与选举)

2.6数据一致性

  • 顺序一致性(Sequential Consistency)
  • 原子性(Atomicity)
  • 单一系统映像(Single System Image)

典型应用场景

  • 分布式锁服务
  • 分布式配置中心
  • 服务注册与发现
  • 分布式队列
  • 集群选主

四、简单实例

ZooKeeper 是一个分布式协调服务,常用于管理分布式系统中的配置信息、命名服务、分布式同步等。下面介绍其基本使用方法:

1. 安装与启动

单机模式

1.1下载并解压

wget https://archive.apache.org/dist/zookeeper/zookeeper-3.8.2/apache-zookeeper-3.8.2-bin.tar.gztar -zxvf apache-zookeeper-3.8.2-bin.tar.gzcd apache-zookeeper-3.8.2-bin

1.2配置

创建配置文件 conf/zoo.cfg

tickTime=2000dataDir=/path/to/dataclientPort=2181

1.3启动服务

bin/zkServer.sh start

2. 基本命令行操作

通过客户端连接 ZooKeeper:

bin/zkCli.sh -server localhost:2181

常用命令:

# 创建节点(-e 临时节点,-s 有序节点)create /my-node \"hello\"create -e /my-ephemeral \"temp\"# 查看节点ls /get /my-node# 更新节点set /my-node \"world\"# 删除节点delete /my-node

3. Java API 使用

依赖

Maven 项目添加依赖:

<dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.8.2</version></dependency>
示例代码
import org.apache.zookeeper.*;import java.io.IOException;public class ZooKeeperExample { private static final String CONNECT_STRING = \"localhost:2181\"; private static final int SESSION_TIMEOUT = 3000; public static void main(String[] args) throws IOException, InterruptedException, KeeperException { // 连接 ZooKeeper ZooKeeper zk = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, null); // 创建持久节点 String path = zk.create(\"/my-java-node\", \"data\".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); System.out.println(\"Created node: \" + path); // 获取节点数据 byte[] data = zk.getData(\"/my-java-node\", false, null); System.out.println(\"Data: \" + new String(data)); // 更新节点 zk.setData(\"/my-java-node\", \"new-data\".getBytes(), -1); // 删除节点 zk.delete(\"/my-java-node\", -1); // 关闭连接 zk.close(); }}

4. 分布式锁示例

利用 ZooKeeper 的有序节点和 watcher 机制实现分布式锁:

import org.apache.zookeeper.*;import java.io.IOException;import java.util.Collections;import java.util.List;public class DistributedLock { private final ZooKeeper zk; private final String lockPath; private String currentNode; public DistributedLock(String connectString, String lockPath) throws IOException { this.zk = new ZooKeeper(connectString, 3000, null); this.lockPath = lockPath; ensurePathExists(lockPath); } public void acquire() throws KeeperException, InterruptedException { // 创建临时有序节点 currentNode = zk.create(lockPath + \"/lock-\", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); // 获取所有子节点并排序 List<String> children = zk.getChildren(lockPath, false); Collections.sort(children); // 如果当前节点是第一个,则获取锁 if (currentNode.endsWith(children.get(0))) { return; } // 否则,监听前一个节点 String prevNode = children.get(children.indexOf(currentNode.substring(lockPath.length() + 1)) - 1); synchronized (this) { zk.exists(lockPath + \"/\" + prevNode, new Watcher() { @Override public void process(WatchedEvent event) {  synchronized (DistributedLock.this) { DistributedLock.this.notify();  } } }); this.wait(); } } public void release() throws KeeperException, InterruptedException { if (currentNode != null) { zk.delete(currentNode, -1); currentNode = null; } } private void ensurePathExists(String path) { try { if (zk.exists(path, false) == null) { zk.create(path, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } } catch (Exception e) { e.printStackTrace(); } }}

5. 集群配置

在多台机器上部署 ZooKeeper 集群,修改 zoo.cfg

tickTime=2000dataDir=/path/to/dataclientPort=2181initLimit=5syncLimit=2# 集群节点配置server.1=host1:2888:3888server.2=host2:2888:3888server.3=host3:2888:3888

在每台机器的 dataDir 目录下创建 myid 文件,内容为对应服务器的 ID(如 123)。

注意事项

  • 节点类型

    • 持久节点:创建后一直存在,除非手动删除。
    • 临时节点:会话结束后自动删除。
    • 有序节点:节点名后会自动添加递增编号。
  • Watcher 机制:监听节点变化,触发一次后失效,需重新注册。

  • 生产环境建议

    • 集群规模推荐奇数台(3、5、7 台)。
    • 避免频繁创建 / 删除节点,影响性能。
    • 监控 zkServer.sh status 查看集群状态。

配置\"log4j\"

在这里插入图片描述

# 设置根日志级别为INFO,输出到控制台log4j.rootLogger=INFO, stdout# 配置控制台输出log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

查看集群状态。

配置\"log4j\"

[外链图片转存中…(img-JG1ZxTmq-1751986721579)]

# 设置根日志级别为INFO,输出到控制台log4j.rootLogger=INFO, stdout# 配置控制台输出log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n