文章目录
前言
在分布式系统中,安全访问控制和一致性保证是两大核心需求。本文将深入探讨Zookeeper的ACL权限控制机制和Zab协议的核心原理,帮助读者理解Zookeeper如何保障数据安全性和系统一致性。
一、ACL访问控制列表
ACL(Access Control Lists)是Zookeeper保护ZNode数据安全的关键机制,它定义了哪些用户可以执行哪些操作。
1. Scheme(验证方案):Scheme定义了认证方式,Zookeeper支持四种主要方案。
Scheme | 描述 | 使用场景 |
---|---|---|
world | 默认方案,所有用户都可访问 | 公共节点 |
auth | 已认证用户(无需显式凭证) | 会话级访问控制 |
digest | 用户名+密码认证 | 最常用的安全控制 |
ip | 客户端IP地址认证 | 网络级访问控制 |
2. Permissions(权限):每种Scheme可配置以下权限
权限 | 标识 | 描述 |
---|---|---|
CREATE | c | 创建子节点 |
READ | r | 读取节点数据及子节点列表 |
WRITE | w | 设置节点数据 |
DELETE | d | 删除子节点 |
ADMIN | a | 设置ACL权限 |
关键点:DELETE权限针对的是子节点,要删除当前节点需要父节点的DELETE权限。
3. ACL设置与验证实战
下面通过Java代码演示ACL的设置和验证:
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;
import java.util.ArrayList;
import java.util.List;
public class ZookeeperAclDemo {
private static final String CONNECT_STRING = "localhost:2181";
private static final int SESSION_TIMEOUT = 3000;
private ZooKeeper zooKeeper;
// 连接到Zookeeper服务器
public void connect() throws Exception {
zooKeeper = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, null);
System.out.println("连接Zookeeper成功");
}
// 创建带ACL的节点
public void createNodeWithAcl() throws Exception {
String path = "/secure-data";
byte[] data = "Sensitive Information".getBytes();
// 添加认证信息(用户名:admin,密码:admin123)
zooKeeper.addAuthInfo("digest", "admin:admin123".getBytes());
// 准备ACL列表:digest方案 + 所有权限
List<ACL> acls = new ArrayList<>();
String digest = DigestAuthenticationProvider.generateDigest("admin:admin123");
acls.add(new ACL(ZooDefs.Perms.ALL, new Id("digest", digest)));
// 创建持久节点
String createdPath = zooKeeper.create(path, data, acls, CreateMode.PERSISTENT);
System.out.println("带ACL节点创建成功: " + createdPath);
}
// 验证ACL访问控制
public void verifyAcl() throws Exception {
String path = "/secure-data";
try {
// 尝试无认证访问(应失败)
ZooKeeper noAuthZk = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, null);
System.out.println("无认证访问结果: " +
new String(noAuthZk.getData(path, false, null)));
} catch (KeeperException.NoAuthException e) {
System.out.println("无认证访问被拒绝: " + e.getMessage());
}
try {
// 尝试错误密码访问(应失败)
ZooKeeper wrongAuthZk = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, null);
wrongAuthZk.addAuthInfo("digest", "admin:wrongpass".getBytes());
System.out.println("错误密码访问结果: " +
new String(wrongAuthZk.getData(path, false, null)));
} catch (KeeperException.NoAuthException e) {
System.out.println("错误密码访问被拒绝: " + e.getMessage());
}
// 正确认证访问(应成功)
ZooKeeper correctAuthZk = new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, null);
correctAuthZk.addAuthInfo("digest", "admin:admin123".getBytes());
System.out.println("正确认证访问结果: " +
new String(correctAuthZk.getData(path, false, null)));
}
public static void main(String[] args) throws Exception {
ZookeeperAclDemo demo = new ZookeeperAclDemo();
demo.connect();
demo.createNodeWithAcl();
demo.verifyAcl();
}
}
代码执行结果:
连接Zookeeper成功
带ACL节点创建成功: /secure-data
无认证访问被拒绝: KeeperErrorCode = NoAuth for /secure-data
错误密码访问被拒绝: KeeperErrorCode = NoAuth for /secure-data
正确认证访问结果: Sensitive Information
4. ACL管理技巧
- 查看ACL:使用getAcl命令
getAcl /secure-data
- 添加认证:使用addauth命令
addauth digest admin:admin123
- 权限组合:使用cdrwa表示所有权限,rw表示读写权限
二、原子广播协议(Zab协议)
Zab协议是Zookeeper实现分布式一致性的核心算法,保证所有节点的状态一致性。
Zab协议核心概念
- 事务(Transaction):改变Zookeeper状态的操作
- 事务ID(zxid):64位全局唯一ID(高32位为epoch,低32位为计数器)
- 提案(Proposal):Leader提出的状态变更建议
- 仲裁(Quorum):集群多数节点(n/2+1)
Zab协议工作流程
Zab协议分为两个关键阶段:
阶段1:Leader选举(崩溃恢复阶段)
选举规则:
优先选择zxid最大的服务器。
zxid相同时选择serverId最大的服务器。
阶段2:消息广播(原子广播阶段)
关键流程:
1.Leader接收客户端请求,生成全局有序的zxid。
2.Leader发送PROPOSAL给所有Follower。
3.Follower将PROPOSAL写入事务日志并响应ACK。
4.Leader收到多数ACK后发送COMMIT。
5.Follower收到COMMIT后提交事务。
- Zab协议特性
- 可靠提交:提案一旦被提交,最终会被所有服务器提交。
- 全局有序:所有事务按zxid顺序处理。
- 因果有序:事务之间的依赖关系得到保持。
- 快速恢复:选举新Leader后能快速同步状态。
- zxid的作用
- epoch:Leader任期编号,每次选举后递增。
- 计数器:事务序列号,从0开始递增。
- 全局有序:通过比较zxid实现全序关系。
- 故障恢复:新Leader通过zxid确定同步点。
总结
Zookeeper 通过 ACL 权限控制(支持 world/auth/digest/ip 四种方案和 CRWDA 五种权限)实现节点访问安全,利用 Zab 协议(Leader 选举 + 原子广播两阶段)和全局有序的 zxid(epoch + 计数器)保障分布式一致性,二者共同构成 ZooKeeper 作为分布式协调服务的核心基石。