1. 核心概念

  • 命名服务 (Naming Service):在分布式系统中,通过一个易记的名称(Name)来获取资源或服务的地址、元数据等信息。类似于 DNS 将域名解析为 IP,ZooKeeper 将服务名解析为服务地址列表。
  • 配置管理 (Configuration Management):集中管理集群中所有节点的配置信息,并确保当配置发生变更时,所有节点能实时感知并更新,实现“配置热更”。

2. 原理与实现

2.1 命名服务 (Naming Service)

ZooKeeper 的命名服务主要依赖其 树形分层结构(Hierarchical Namespace)

  • 实现方式
    • 通常在 /services 根节点下创建服务名节点,例如 /services/user-service
    • 服务提供者启动时,在 /services/user-service 下创建子节点(通常是临时节点),节点名为 IP:Port 或 UUID,节点数据包含具体的服务地址。
    • 服务消费者读取 /services/user-service 的所有子节点,获取可用服务列表。
  • 优势
    • 解耦:消费者只需知道服务名,无需硬编码 IP。
    • 动态性:利用临时节点,服务下线自动剔除。

2.2 配置管理 (Configuration Management)

ZooKeeper 的配置管理主要依赖其 数据存储Watch 机制

  • 实现方式
    1. 存储配置:将公共配置(如数据库连接串、开关配置)写入一个 ZNode,例如 /configs/db-config
    2. 获取配置:应用启动时,读取该 ZNode 的数据,并加载到内存中。
    3. 注册监听:应用在读取数据的同时,对该 ZNode 注册一个 DataChanged Watch
    4. 动态更新:当管理员修改了 /configs/db-config 的数据,ZooKeeper 服务端会向所有注册了 Watch 的客户端发送通知。
    5. 重新拉取:客户端收到通知后,再次读取 ZNode 的最新数据并更新本地配置。
  • 源码关键点
    • getData(path, watch):读取数据并注册监听。
    • process(WatchedEvent):回调接口,处理配置变更通知。

3. 性能与可靠性考量

  • 数据大小限制:ZooKeeper 的 ZNode 默认限制存储 1MB 数据。因此,它适合存储元数据关键配置,不适合存储大文件(如图片、大段文本)。如果配置过大,建议存储在数据库或对象存储中,ZK 只存版本号或索引地址。
  • 读多写少:配置管理是非常典型的“读多写少”场景,非常契合 ZooKeeper 的性能特性(Follower 处理读,Leader 处理写)。
  • 容灾:配置中心通常是单点依赖,ZooKeeper 集群的高可用性保证了配置服务不会轻易宕机。

4. 总结

面试官:什么是 ZooKeeper 的命名服务和配置管理?

候选人命名服务是利用 ZooKeeper 的树形目录结构,为分布式系统中的资源提供统一的名称标识。最典型的例子是 RPC 注册中心,服务提供者在 ZK 中创建节点,消费者通过节点路径获取服务地址,实现了服务地址的解耦和动态发现。

配置管理则是利用 ZooKeeper 的数据存储Watch 机制。我们将配置信息存储在 ZNode 中,所有客户端监听这个节点。一旦配置发生变更,ZK 会通知所有客户端,客户端收到通知后主动拉取最新配置,从而实现了配置的集中管理和动态热更新

需要注意的是,ZK 适合存储小量的关键配置(默认 1MB 上限),适用于读多写少的场景。