背景
项目中使用了zookeeper进行的类似工作流引擎的工作流转,将一次工作请求拆分了4个节点(S/E/T/L)。S阶段做完后,通过zk的watcher触发下一个E节点进行处理,S和E可能为不同的jvm上,所以需要走一个分布式的消息进行通知。
思路
基于zookeeper做持久化watcher,项目中直接使用zookeeper官方api,大致的工作模型:
private synchronized void initNodes(List<String> nodes) {
// 根据zk节点,判断是否需要处理
}
private void syncNodes() {
try {
List<String> nodes = zookeeper.getChildren(ArbitrateConstants.NODE_NID_ROOT, new AsyncWatcher() {
public void asyncProcess(WatchedEvent event) {
syncNodes();// 继续关注node节点变化
}
});
initNodes(nodes);
} catch (KeeperException e) {
syncNodes();
} catch (InterruptedException e) {
// ignore
}
}
- 有两个方法initNodes 和 syncNodes, syncNodes主要是监听zookeeper的节点变化
- syncNodes会通过级联方式,在每次watcher被触发后,就会再挂一次watcher。完成了一个类似链式触发的功能
遇到的问题
系统上线运行后,跑了几天时间,跑出了一个OutOfMemory的问题,jmap dump了下对应的内存数据文件,发现了一个zk使用上的问题.
a. 通过mat分析查看了下jvm中占用内存最大的对象,居然是zookeeper中的一个waitingEvents.:
b. waitingEvents中的WatcherSetEventPair对象中,包含了一个待响应的watchers和对应的响应event事件对象,对应的watchers数量居然有300W个
问题分析:
分析了下WatcherSetEventPair中的处理机制。
Event响应中对应EventType的枚举类型:(存在一个特殊的None类型)
- None (-1),
- NodeCreated (1),
- NodeDeleted (2),
- NodeDataChanged (3),
- NodeChildrenChanged (4);
查了下代码,None类型会在Session expired / connection loss/ auth failed得到对应的触发,对应的触发path为null
代码:
eventThread.queueEvent(new WatchedEvent(
Watcher.Event.EventType.None,
Watcher.Event.KeeperState.Expired, null));
针对None类型,在获取对应的watcher响应时:
public Set<Watcher> materialize(Watcher.Event.KeeperState state,
Watcher.Event.EventType type,
String clientPath)
{
Set<Watcher> result = new HashSet<Watcher>();
switch (type) {
case None:
result.add(defaultWatcher);
for(Set<Watcher> ws: dataWatches.values()) {
result.addAll(ws);
}
for(Set<Watcher> ws: existWatches.values()) {
result.addAll(ws);
}
for(Set<Watcher> ws: childWatches.values()) {
result.addAll(ws);
}
// clear the watches if auto watch reset is not enabled
if (ClientCnxn.getDisableAutoResetWatch() &&
state != Watcher.Event.KeeperState.SyncConnected)
{
synchronized(dataWatches) {
dataWatches.clear();
}
synchronized(existWatches) {
existWatches.clear();
}
synchronized(childWatches) {
childWatches.clear();
}
}
return result;
针对出现None的类型,会将所有的watcher进行触发,同时并不会移除watcher,所以,watcher会在下一次reconnect成功后再次触发,除非设置DisableAutoResetWatch
总结
a. 需要明确watcher的触发条件和触发case场景。特别注意,None类型可能会引起触发2次watcher调用
(截取了淘宝同学的blog : http://rdc.taobao.com/team/jm/archives/1047)
event For “/path”
defaultWatcher
exists
(“/path”)
getData
(“/path”)
getChildren
(“/path”)
EventType.None |
√ |
√ |
√ |
√ |
EventType.NodeCreated |
|
√ |
√ |
|
EventType.NodeDeleted |
|
√ |
√ |
|
EventType.NodeDataChanged |
|
√ |
√ |
|
EventType.NodeChildrenChanged |
|
|
|
√
|
b. 出现session expired,需要重建zookeeper connector,对应的watcher会失效。因为watcher在client的存储是和对应的zookeeper client绑定,不同的client有不同的watcher列表。
- 大小: 64.4 KB
- 大小: 168.6 KB
分享到:
相关推荐
为了更好地理解Watcher的使用,下面我们将通过一个简单的Java程序来创建一个Watcher并监听Zookeeper上的数据节点。 首先,我们需要在`pom.xml`中引入Zookeeper的依赖: ```xml <groupId>org.apache.zookeeper ...
### ZooKeeper典型使用场景详解 #### 一、概述 ZooKeeper是一款开源的分布式协调服务框架,主要用于解决分布式系统中的数据一致性问题。它基于Paxos算法实现,确保了即使在网络分区的情况下,也能保证分布式环境下...
本文将详细介绍 ZooKeeper 客户端的使用和集群特性,包括客户端简介、客户端连接参数说明、客户端 CRUD、客户端监听、集群架构说明、集群配置及参数说明、选举投票机制、主从复制机制等知识点。 一、客户端 API ...
在实际使用中,ZooKeeper提供了丰富的API,如创建、删除、更新和读取ZNode,以及设置和触发Watcher。例如,`Demo1.java`和`Demo2.java`可能包含这样的示例代码: ```java import org.apache.zookeeper.*; public ...
zookeeper-watcher-demo zookeeper wather demo 示例说明:zookeeper server端,client端每100毫秒写入数据,另一个client端watch节点数据变化 监听的结果是得到的数值是连续的、和数据生成端是一致的,并没有出现...
通过学习和理解这些知识点,开发者和系统管理员能够更好地掌握Zookeeper的使用,从而在分布式系统中实现高效、可靠的协调和管理。无论你是初学者还是经验丰富的专业人士,这份"Zookeeper 使用指导"都将是你宝贵的...
3. **事件通知**:Zookeeper提供watcher机制,允许客户端设置监听某个节点的变化,当节点状态发生变化时,Zookeeper会立即通知相关客户端,实现快速响应。 4. **会话管理**:Zookeeper维护客户端的会话状态,如果...
在本文中,我们将深入探讨Zookeeper中的Watcher原理,这是一个关键特性,它允许客户端对Zookeeper中的数据变化进行实时监控。Watcher机制是Zookeeper提供的一种事件通知模型,它使得客户端能够及时响应Zookeeper中...
- **Watcher 事件监听**:Zookeeper 支持 Watcher 机制,允许客户端注册监听特定节点的变化,当节点发生变化时,Zookeeper 会触发回调通知客户端。 ### 2. ZooKeeper 的功能 - **命名服务**:为分布式组件提供唯一...
- **Watcher**:Watcher 是 ZooKeeper 中的一种通知机制,可以注册在 ZNode 上,当 ZNode 发生变化时,Watcher 将接收到通知事件。 ### 4. ZooKeeper 的一致性保证 ZooKeeper 提供了强一致性模型,确保数据在同一...
在IT行业中,Zookeeper和Java API的结合使用是分布式系统管理的重要组成部分。Zookeeper是由Apache软件基金会开发的一个开源项目,它提供了一种高效且可靠的分布式协调服务,常用于配置管理、命名服务、集群管理和...
5. **ZookeeperWatcher的使用** - **安装与启动**: 解压ZookeeperWatcher压缩包,按照官方文档或README文件进行配置和启动。 - **连接Zookeeper**: 输入Zookeeper服务器的连接地址和端口,建立连接。 - **操作...
对于学习 Zookeeper 的学生或部署的工作人员,了解以下知识点至关重要: 1. 安装与配置:如何正确地安装 Zookeeper,包括修改配置文件、设置环境变量等。 2. 集群部署:如何配置多台机器组成 Zookeeper 集群,包括...
- 使用Watcher时要注意避免死循环和资源耗尽的问题。 8. **Zookeeper的未来发展趋势**: - 随着微服务和云原生架构的发展,Zookeeper将在服务治理、分布式事务等领域发挥更大作用。 - 可能与Kubernetes等现代...
2. Client:Zookeeper客户端,提供了丰富的API供应用使用,如创建、删除、更新、查询ZNode等操作。 3. ZNode:Zookeeper的数据模型,类似于文件系统的目录结构,每个节点称为ZNode,包含了数据、元数据和ACL(访问...
在解决Zookeeper使用中的常见问题时,例如关于Zookeeper init函数的使用、session失效问题、watcher设置和获取等,都需要对Zookeeper内部工作原理和API有充分的了解。在进行Zookeeper安装和配置时,应该参考官方文档...
这个“Zookeeper中文开发指南”是针对开发人员和系统管理员的一份宝贵的资源,它涵盖了从基础概念到高级应用的所有关键知识点。 **一、Zookeeper基本概念** 1. **节点(Znode)**: ZooKeeper 的数据存储结构基于树...
本文将深入探讨ZooKeeper客户端API的使用方法和核心概念。 ### 1. 连接ZooKeeper 在使用ZooKeeper客户端API之前,首先需要建立与ZooKeeper服务器的连接。这通常通过`ZooKeeper`类的构造函数完成,传入服务器地址...
### VIP-02 Zookeeper客户端使用与集群特性(1) #### Curator介绍 Curator是Netflix公司开源的一个针对ZooKeeper的高级Java客户端框架。它不仅简化了ZooKeeper的使用,还提供了丰富的抽象和工具类,使得开发者能够...
在使用Zookeeper时,需要注意监控Zookeeper的服务状态,定期备份数据,以及定期升级以获取最新的安全修复和功能增强。此外,对于高可用性需求,通常会部署多个Zookeeper节点构成一个集群,以确保服务的连续性和数据...