- 浏览: 1598170 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
jsrgzhangzhiyong:
关于null值的转换还是感觉不太友好,就像 mapstruct ...
我也造了个轮子:BeanMapping(属性拷贝) -
he037:
a417930422 写道引用使用EPHEMERAL会引出一个 ...
基于zookeeper的分布式lock实现 -
seancheer:
<div class="quote_title ...
zookeeper学习记录三(session,watcher,persit机制) -
雪夜归人:
您好,我想咨询一下,开源的canal都能支持mysql的哪些版 ...
Canal BinlogChange(mysql5.6) -
zhoudengyun:
copy 一份做记录,后续学习,请知悉
阿里巴巴开源项目: 基于mysql数据库binlog的增量订阅&消费
背景
继续前面的zookeeper学习的专题,这次主要是结合项目中遇到的一些问题,进一步学习了下zookeeper的一些内部机制。
针对以下几个问题:
1. zk是否可以保证watcher事件不丢失?
2. zk的EPHEMERAL节点的自动过期时间?
3. zk的如何保证节点数据不丢失?
如果你已经非常清楚这以上的几个问题,看官们可以不用往下看了。
persit机制
zookeeper中的persit机制主要是通过本地disk进行持久化,在本地disk上会有个memory数据对象保持同步。
持久化实现:
ZKDatabase
- DataTree (内存树)
- FileTxnSnapLog (disk持久化)
- committedLog (FileTxnSnapLog的一份内存数据cache,默认存储500条变更记录)
DataTree(内存树)
zookeeper本身的数据结构就是一个树结构
数据模型(DataTree):
- DataNode (1:n)
- data WatchManager (1:1,处理node节点的CRUD的变更事件,发送Watcher事件)
- child WatchManager (1:1, 处理node子节点的变更事件,发送Watcher事件)
- sessions (ephemerals)
- parent
- data byte[]
- acl(安全)
- stat(审计信息)
- children
FileTxnSnapLog (disk持久化)
持久化数据分两类:
- TxnLog (类似于mysql/oracle的binlog/redolog)
- SnapShot (DataTree的数据镜像)
- 首先节点启动后,尝试读取本地的SnapShot log数据(zkDb.loadDataBase()),反序列化为DataTree对象,并获取last zxid。
- follower启动后会向leader发送自己的last zxid
- leader收到zxid后,对比自己当前的ZKDatabase中的last zxid
如果当前follower的zxid在内存committedLog中,直接将内存中的committedLog提取出来进行发送,否则将当前的DataTree直接发送给follower.(不再是发送变更记录)
- 数据同步完成后,follower会开始接收request请求
一致性机制
整个zk集群在处理数据变更过程中,会是先append变更信息到Txnlog中(此时会触发take snap操作),最后在FinalRequestProcessor中更新内存中的DataTree信息。
触发take snap的条件:
if (logCount > (snapCount / 2 + randRoll)) { randRoll = r.nextInt(snapCount/2);
snapCount可以通过jvm参数zookeeper.snapCount指定,默认为100000。 这里zookeeper很巧妙的加两个随机处理,避免zk机器在同一时间点进行take snap处理,影响性能。
session机制
zookeeper会为每个client分配一个session,类似于web服务器一样。针对session可以有保存一些关联数据,zookeeper里针对session的一些关联数据主要就是EPHEMERAL节点。
EPHEMERAL的翻译为短命的,技术上理解就是session关闭后,其节点即消失,和session保持相同的生命周期。
创建EPHEMERAL节点:
zookeeper.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
我们能用EPHEMERAL节点做啥?
- 分布式集群是否存活监控. (每个节点启动后,注册一个EPHEMERAL节点到zookeeper中,注册一个Watcher获取EPHEMERAL节点的存在情况,消失即可代表集群节点dead)
- 分布式lock (每个锁竞争者,排队时都在zookeeper中注册一个EPHEMERAL节点,排队过程中有节点dead了,zookeeper可以自动将其剔除队列,避免出现deadlock)
- 替代web服务器的session,实现一个集中式session, session数据中的setAttribute都创建为EPHEMERAL节点,session关闭后即可自动删除,不会造成java中的"内存泄漏"
- zookeeper server挂了,对应的session是否会丢失?
- zookeeper client发生了failover后(出现了Connection Loss异常),对应的session是否会丢失?
- 在服务端,zookeeper中session的存储是有进行持久化的, 具体可见perist机制的描述。 一个新节点启动后,会从leader中同步对应的session数据
- 在客户端,zookeeper在每次出现failover后(出现了Connection Loss异常),会重新带上sessionId,sessionPasswd发起一次链接请求。接收到该请求的server,会返回内存中的session信息
session expired机制
zookeeper中session expired机制和node数据一致性的保证原理类似,对应的follower都是受控于leader。
- follower接收到客户端链接请求,就会向leader发送一次createSession的操作请求,leader收到后进行广播通知给所有的follower/observer节点createSession
- leader会通过内存版的(SessionTrackerImpl),定期扫描过期的session,发送一次closeSession的请求给所有的客户端
- 在2发送过程中,如果有follower接收到过期session的请求,会提交给leader进行仲裁,leader会直接返回session expired。
session expired几个参数:
- 服务端: minSessionTimeout (默认值为:tickTime * 2) , maxSessionTimeout (默认值为 : tickTime * 20) , ticktime的默认值为3000ms。所以session范围为6s ~ 60s
- 客户端: sessionTimeout, 无默认值,创建实例时必填。
一个误区: 很多人会按照hadoop文档中的建议,创建zookeeper客户端时设置了sessionTimeout为90s,而没有改变server端的配置,默认是不会生效的。
原因: 客户端的zookeeper实例在创建连接时,将sessionTimeout参数发送给了服务端,服务端会根据对应的minSessionTimeout/maxSessionTimeout的设置,强制修改sessionTimeout参数,也就是修改为6s~60s返回的参数。所以服务端不一定会以客户端的sessionTImeout做为session expire管理的时间。
int minSessionTimeout = zk.getMinSessionTimeout();
if (sessionTimeout < minSessionTimeout) {
sessionTimeout = minSessionTimeout;
}
int maxSessionTimeout = zk.getMaxSessionTimeout();
if (sessionTimeout > maxSessionTimeout) {
sessionTimeout = maxSessionTimeout;
}
int minSessionTimeout = zk.getMinSessionTimeout();
if (sessionTimeout < minSessionTimeout) {
sessionTimeout = minSessionTimeout;
}
int maxSessionTimeout = zk.getMaxSessionTimeout();
if (sessionTimeout > maxSessionTimeout) {
sessionTimeout = maxSessionTimeout;
}
Watcher机制
watcher是zookeeper实现分布式lock一个很重要的feature,在写分布式lock时一定要对其有所了解。
就会冒出如下问题:
- 什么情况下,会触发什么类型的watcher?
- watcher信息出现failover是否会丢失?
- watcher信息出现session expired是否会丢失?
- exists方法: 设置watcher时,如果对应服务端已经不存在node时,watcher是不会留在服务端,下次不会被触发。针对这种情况需要判断返回的stat == null来进行处理
- getChildren方法: 和exist一样,需要处理节点不存在时watcher不会被记录。 还有一个点,当前的父node发生delete变化时,也可以得到触发
- getData方法: 和exist一样,需要处理节点不存在时watcher不会被记录
- Watcher是一个本地jvm的callback,在和服务端交互过程中是不会进行传递的。只是会将是否有watcher的boolean变量传递给server端
- 在服务端,在FinalRequestProcessor处理对应的node操作时,会根据客户端传递的watcher变量,添加到对应的zkDataBase中进行持久化存储,同时将自己NIOServerCnxn做为一个Watcher callback,监听服务端事件变化
- leader通过投票通过了某次node变化请求后,通知给对应的follower,follower根据自己内存中的zkDataBase信息,发送notification信息给zookeeper 客户端
- zookeeper客户端接收到notification信息后,找到对应变化path的watcher列表,挨个进行触发回调。
zookeeper异常处理
官方文档:http://wiki.apache. org/hadoop/ZooKeeper/FAQ
主要处理两个系统异常:
- KeeperException.ConnectionLossException (client与其中的一台server socket链接出现异常)
- KeeperException.SessionExpiredException (client的session超过sessionTimeout为进行任何操作)
最后
思路可能写的有点乱,文中所有的内容均通过阅读源码所得,如有不对的地方,尽情拍砖。
评论
服务重启的时候,应该是TnxLog配合SnapShot 一起,完成数据刷新吧?
因为有些节点的变化在SnapShot 是没有的。
是的,从snapshot中取出最大的zxid后,会结合tnxLog中的值来刷新最大的zxid,并回放tnxLog中的操作
//根据snapshot获取的最大的zxid来读取txnLog文件,txnLog的命名方式是前缀为log的文件 TxnIterator itr = txnLog.read(dt.lastProcessedZxid+1); long highestZxid = dt.lastProcessedZxid; //从snapshot文件中获取到的当前节点最大的zxid TxnHeader hdr; try { while (true) { // iterator points to // the first valid txn when initialized hdr = itr.getHeader(); if (hdr == null) { //empty logs return dt.lastProcessedZxid; } if (hdr.getZxid() < highestZxid && highestZxid != 0) { LOG.error("{}(higestZxid) > {}(next log) for type {}", new Object[] { highestZxid, hdr.getZxid(), hdr.getType() }); } else { highestZxid = hdr.getZxid(); // ATTENTION!!! 从这里可以看出来,结合txnLog,取最大的zxid } try { processTransaction(hdr,dt,sessions, itr.getTxn()); }
服务重启的时候,应该是TnxLog配合SnapShot 一起,完成数据刷新吧?
因为有些节点的变化在SnapShot 是没有的。
发表评论
-
yugong QuickStart
2016-03-05 01:52 0几点说明 a. 数据迁移的方案可参见设计文档,oracl ... -
阿里巴巴开源项目: 阿里巴巴去Oracle数据迁移同步工具
2016-03-05 18:29 6551背景 08年左右,阿里巴巴开始尝试MySQL的相关 ... -
愚公performance
2016-03-02 17:29 0性能测试 全量测试 场景1 (单主键, ... -
yugong AdminGuide
2016-03-02 16:40 0环境要求 操作系统 数据库 迁移方案 部署 ... -
Tddl_hint
2014-01-27 13:52 0背景 工作原理 Hint格式 direct模 ... -
tddl5分库规则
2014-01-26 14:41 0背景 工作原理 构建语法树 元数据 基于 ... -
tddl5优化器
2014-01-22 15:12 0背景 工作原理 构建语法树 元数据 抽象语 ... -
Canal BinlogChange(mariadb5/10)
2014-01-20 17:25 4633背景 先前开源了一个 ... -
asynload quickstart
2013-10-08 22:49 0几点说明: 1. asyncload是做为一个j ... -
映射规则配置
2013-09-26 11:25 0背景 因为alibaba的特殊业务,比如: 同 ... -
网友文档贡献
2013-09-18 15:50 01. Otter源代码解析系列 链接:http://e ... -
Manager配置介绍
2013-09-16 13:00 0通道配置说明 多种同步方式配置 a. 单向同步 ... -
canal&otter FAQ
2013-09-05 17:30 0常见问题 1. canal和 ... -
阿里巴巴开源项目:分布式数据库同步系统otter(解决中美异地机房)
2013-08-22 16:48 40479项目背景 阿里巴巴B2B公司,因为业务的特性 ... -
Otter AdminGuide
2013-08-19 11:06 0几点说明 otter系统自带了manager,所以简化了一 ... -
Otter高可用性
2013-08-17 23:41 0基本需求 网络不可靠,异地机房尤为明显. man ... -
Otter数据一致性
2013-08-17 23:39 0技术选型分析 需要处理一致性的业务场景: 多地修改 ( ... -
Otter扩展性
2013-08-17 22:20 0扩展性定义 按照实现不同,可分为两类: 数据处理自定 ... -
Otter双向回环控制
2013-08-17 21:37 0基本需求 支持mysql/oracle的异构数据库的双 ... -
Otter调度模型
2013-08-17 20:13 0背景 在介绍调度模型之前,首先了解一下otter系统要解 ...
相关推荐
- **设置watcher**:每个服务器节点在Zookeeper上设置watcher,监听session Znode的变化。 - **session同步**:当session Znode发生变化(如新增、删除或更新),watcher被触发,服务器节点接收到通知后更新本地...
- **登录认证:** 用户登录时,在ZooKeeper中创建一个临时节点,用于记录用户的Session信息。 - **会话保持:** 用户在不同服务器之间切换时,通过查询ZooKeeper中的Session信息来维持会话状态。 - **异常处理:** ...
标题 "基于ZooKeeper的分布式Session实现" 涉及的是在分布式系统中如何利用Apache ZooKeeper来管理和共享Session信息。ZooKeeper是一款开源的分布式协调服务,它为分布式应用程序提供了一个简单一致的接口,用于处理...
### Zookeeper 学习笔记 #### 一、Zookeeper 简介与安装配置 **Zookeeper** 是一个分布式协调服务框架,它提供了一种高效可靠的机制来维护集群中的配置信息、命名服务以及提供分布式锁等功能,使得开发人员能够...
【Zookeeper学习笔记】 Zookeeper是一个分布式协调服务,它的核心目标是简化分布式环境下的数据管理与系统协调。作为Apache Hadoop和HBase的重要组件,Zookeeper提供了简单的原语集,支持分布式应用程序之间的通信...
本文将深入探讨Zookeeper的Watcher机制,并通过一个简单的实例来展示其用法。 **一、Watcher原理** Watcher是Zookeeper的核心机制之一,它是一种事件触发模型。当Zookeeper服务器端的数据状态发生变化时,会主动...
### ZooKeeper会话超时及重连机制详解 #### 一、ZooKeeper会话超时机制 在分布式系统中,ZooKeeper作为一款流行的协调服务框架,为开发者提供了高效且可靠的协调服务。其中,会话管理是ZooKeeper的重要组成部分之...
ZooKeeper 学习笔记 ZooKeeper 是一个开源的分布式协调服务,由 Hadoop 的创始人 Doug Cutting 等人开发。它为分布式应用提供了一个高效、可靠的协调机制,帮助开发者快速构建高可用、可扩展的分布式系统。 ...
此外,Watch机制是Zookeeper的关键特性,客户端可以对节点设置Watch,当节点状态改变时,Zookeeper会向客户端发送一次性通知,从而实现事件驱动的通信。 Zookeeper的时间管理是通过Zxid(事务ID)来实现的,每个...
该项目为基于Java语言的Zookeeper学习笔记设计源码,总计包含20个文件,具体构成包括15个Java源文件、3个PNG图片文件以及1个Markdown文件。此外,项目还包含1个XML配置文件,适用于学习和实践Zookeeper相关知识。
本文适合但不限于软件开发人员阅读。本文档能够使阅读者对zookeeper有一个宏观且全面的了解,内容主要包含zookeeper架构、数据模型、读写及工作原理、典型应用场景、指令汇总等,
Zookeeper的核心概念主要包括节点(Znode)、会话(Session)、观察者模式(Watcher)等。Znode是Zookeeper数据存储的基本单元,具有版本号、ACL权限控制和临时/持久两种类型。会话是客户端与Zookeeper服务器之间的...
总的来说,尚硅谷2021年的ZooKeeper笔记提供了一套全面的学习资源,帮助开发者深入了解ZooKeeper的工作原理及其在分布式系统中的关键作用。通过深入学习和实践,可以提升在分布式协调领域的技术水平。
- **选举机制**:ZooKeeper集群中包含多个服务器节点,其中有一个领导者(Leader)和多个跟随者(Follower)。当集群启动时或领导者宕机时,所有跟随者会参与选举过程,最终选出新的领导者。 - **数据一致性**:领导...
ZooKeeper提供了一种树形的数据结构,每个节点称为ZNode,存储数据并支持监视器(watcher)机制,使得客户端可以监听ZNode的变化。 在ZooKeeper中,主要有以下几个关键组件和概念: 1. **ZNode**:ZooKeeper数据...
接下来,我们将深入学习ZooKeeper的API,包括创建、读取、更新和删除(znode)的操作,以及watcher机制。Watcher是ZooKeeper的一个重要特性,它允许客户端注册监听特定节点的变化,一旦发生变化,ZooKeeper会立即通知...
3. **集群同步**:Zookeeper通过watcher机制,实现了节点数据变化的实时推送,这对于保持分布式系统中各个节点的数据一致性至关重要。当一个节点的数据发生变化,所有关注这个节点的watcher都会收到通知,从而触发...
在IT行业中,ZooKeeper是一个广泛使用的分布式协调服务,它为分布式应用提供了高效且可靠的命名服务、配置管理、集群同步等。本篇文章将专注于ZooKeeper的客户端——Curator,这是一个由Apache提供的Java库,旨在...