Zookeeper是针对大型分布式系统的高可靠的协调系统,如dubbo里面的注册中心、分布式锁等,主要应用于分布式系统中。
组件 | 描述 |
---|---|
Client(客户端) | 客户端,我们的分布式应用集群中的一个节点,从服务器访问信息。对于特定的时间间隔,每个客户端向服务器发送消息以使服务器知道客户端是活跃的。 类似地,当客户端连接时,服务器发送确认码。如果连接的服务器没有响应,客户端会自动将消息重定向到另一个服务器。 |
Server(服务器) | 服务器,我们的ZooKeeper总体中的一个节点,为客户端提供所有的服务。向客户端发送确认码以告知服务器是活跃的。 |
Ensemble | ZooKeeper服务器组。形成ensemble所需的最小节点数为3。 |
Leader | 服务器节点,如果任何连接的节点失败,则执行自动恢复。Leader在服务启动时被选举。 |
Follower | 跟随leader指令的服务器节点。 |
监视是一种简单的机制,使客户端收到关于ZooKeeper集合中的更改的通知。客户端可以在读取特定znode时设置Watches。Watches会向注册的客户端发送任何znode(客户端注册表)更改的通知。Znode更改是与znode相关的数据的修改或znode的子项中的更改。只触发一次watches。如果客户端想要再次通知,则必须通过另一个读取操作来完成。当连接会话过期时,客户端将与服务器断开连接,相关的watches也将被删除。
发布与订阅即所谓的配置管理,顾名思义就是将数据发布到zk节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,地址列表等就非常适合使用。
ZooKeeper 中特有watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。使用方法通常是不同系统都对 ZK上同一个znode进行注册,监听znode的变化(包括znode本身内容及子节点的),其中一个系统update了znode,那么另一个系统能 够收到通知,并作出相应处理。
分布式锁,这个主要得益于ZooKeeper为我们保证了数据的强一致性,即用户只要完全相信每时每刻,zk集群中任意节点(一个zk server)上的相同znode的数据是一定是相同的。锁服务可以分为两类,一个是保持独占,另一个是控制时序。
1. czxid 创建该节点的事务ID 2. ctime 创建该节点的时间 3. mZxid 更新该节点的事务ID 4. mtime 更新该节点的时间 5. pZxid 操作当前节点的子节点列表的事物ID(包含增加子节点,删除子节点) 6. cversion 当前节点的子节点版本号 7. dataVersion 当前节点的数据版本号 aclVersion 当前节点的acl权限版本号 8. ephemeralowner 当前节点的如果是临时节点,该属性是临时节点的事物ID 9. dataLength 当前节点的数据长度 10. numchildren 当前节点的子节点个数
//创建节点 public static void createNode() throws Exception { ZooKeeper zk = new ZooKeeper("192.168.10.12:2181", 100000, null); String str = "真帅"; String result = zk.create("/testNode/test1", //路径 str.getBytes(), //获取数据的字节码 ZooDefs.Ids.OPEN_ACL_UNSAFE, //任何人都拥有所有权限 CreateMode.PERSISTENT);//永久节点 System.out.println(result);//返回当前已经创建的路径 zk.close(); } //获取节点 public static void getNode() throws Exception { ZooKeeper zk = new ZooKeeper("192.168.10.12:2181", 100000, null); // States stats = zk.getState();//获取状态-运行状态 // System.out.println(stats); //数据节点状态 Stat stat = new Stat(); byte[] data = zk.getData("/testNode/test1", null, stat); System.out.println(new String(data));//节点数据 System.out.println(stat.toString());//节点状态 zk.close(); } //修改节点 public static void setNode() throws Exception { ZooKeeper zk = new ZooKeeper("192.168.10.12:2181", 100000, null); Stat stat = zk.setData("/testNode/test1", "杨斌斌真帅!!!!".getBytes(), -1); System.out.println(stat.toString());//节点状态 zk.close(); } //删除节点 public static void removeNode() throws Exception { ZooKeeper zk = new ZooKeeper("192.168.10.12:2181", 100000, null); zk.delete("/testNode/test1", -1); zk.close(); }
private Semaphore sp = new Semaphore(1); //监听时,服务器要保证客户端一定能收到消息,反复不断的向客户端发送状态 private boolean flag = true;//加一个状态防止虚假提交 public synchronized void test() throws Exception { ZooKeeper zk = new ZooKeeper("192.168.10.102:21811", 100000, null); //信号量 while(true) { zk.getData("/testNode/test1", new Watcher() { public void process(WatchedEvent event) { if(!flag) {//每次注册之后,只接收一次数据 return; } System.out.println(event.getState().name());//节点状态 System.out.println(event.getType().name());//操作类型 System.out.println(event.getPath());//那个节点发生了变化 sp.release(1);//清空信号量 flag = false; } }, new Stat()); sp.acquire(1);//信号量加满,线程也就停下来了 flag = true; } }
API | 说明 | |
---|---|---|
getChildren | NodeChildrenChanged | 新建子节点【激活】 |
删除子节点【激活】 | ||
修改子节点【不激活】 | ||
getData | NodeDataChanged | 修改该节点 |
NodeDeleted | 删除该节点 | |
exists | NodeCreated | 新建该节点 |
NodeDataChanged | 修改该节点 | |
NodeDeleted | 删除该节点 |
权限 | 说明 |
---|---|
digest | Client端由用户名和密码验证,譬如user:password,digest的密码生成方式是Sha1摘要的base64形式 |
auth | 不使用任何id,代表任何已确认用户。 |
ip | Client端由IP地址验证,譬如172.2.0.0/24 |
world | 固定用户为anyone,为所有Client端开放权限 |
super | 在这种scheme情况下,对应的id拥有超级权限,可以做任何事情(cdrwa) |
注意: exists操作和getAcl操作并不受ACL许可控制,因此任何客户端可以查询节点的状态和节点的ACL。
权限 | 说明 |
---|---|
Create | 允许对子节点Create操作 |
Read | 允许对本节点GetChildren和GetData操作 |
Write | 允许对本节点SetData操作 |
Delete | 允许对子节点Delete操作 |
Admin | 允许对本节点setAcl操作 |
为了解决分布式环境下一致性的问题。多个节点并发操纵数据,如何保证在读写过程中数据的一致性,并且解决方案要能适应分布式环境下的不可靠性(系统如何就一个值达到统一)
1. 安全原则---保证不能做错的事:针对某个实例的表决只能有一个值被批准,不能出现一个被批准的值被另一个值覆盖的情况;(假设有一个值被多数Acceptor批准了,那么这个值就只能被学习)。每个节点只能学习到已经被批准的值,不能学习没有被批准的值。 2. 存活原则---只要有多数服务器存活并且彼此间可以通信,最终都要做到的下列事情: 最终会批准某个被提议的值;一个值被批准了,其他服务器最终会学习到这个值。
先后提议的场景
交叉场景
又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。这三个要素最多只能同时实现两点,不可能三者兼顾。