Stereo 2013-04-14
8. snapshot原理:
ZK Snapshot主要意义就是将当前Database + Memory中数据的状态,直接序列化到文件,以方便在故障时可以迅速恢复.snapshot是fuzzy的(非严格意义的snapshot),snapshot所涉及到的类有SyncRequestProcessor(同步请求处理器,处理请求的log同步到disk)/ZKDatabase(ZK内存数据库)/TxnLog(事物日志)/SnapLog等。
Snapshot的流程比较简单,源码(SyncRequestProcessor)复述如下:
注意:ZK是基于JVM,且为高内存消耗进程,所以对JVM的heap大小有一定的要求,如果heap过小,将会造成内存数据的多次swap,带来性能隐患。在高性能高可用cluster环境中,建议将ZK server部署在单独物理服务器上。
9. ZK Session:[Session原理详解]
Zk客户端通过使用语言绑定(language binding)创建一个service的handle,来和zk service建立session。一旦创建,此handle初始为CONNECTING状态,然后client将会尝试与zk service中的一台server建立链接,链接成功后,状态将会被转换为CONNECTED。在一般情况下,session会是这两个状态中的一种。不过,当发生不可恢复时,例如session过期或者验证失败,或者应用明确的关闭了handle,那么此session的handle将会被变更为CLOSED状态。下图为session状态转换(来自apache zookeeper官网)
当client从zk service中获取一个handle(句柄)之后,zk将会为client创建一个session,sessionID为一个64位的数字。如果client链接到了其他的server上,它(client)将会把session id作为“握手”链接的一部分发送给server。因为安全的因素,server还为session id创建了一个password,以便任何ZK server都能够验证。当session创建成功后,session id和password都将会发送给client。无论client和哪个server建立链接,它都必须将session id和password一同发送给需要建立链接的server。
当client连接失效后,它将会检索指定的server列表,并与其中一个server重新建立链接,session的状态被再次转换为CONNECTED(在session timeout有效期内),或者将会被转换成“EXPIRED”状态(session timeout之后,建立了链接)。不建议在链接失效后,创建新的session(Zookeeper实例),ZK client将会为你处理重链接。此外,ZK内置的一些机制来处理类似“羊群效应”等等。当client被通知session过期,只需要创建一个新的session即可。
A)’CONNECTED‘:session已经被创建,并且client正在和cluster通信。
B)Client的信息将被Cluster所维持,并成为Cluster环境数据的一部分.
C)’DISCONNECTED‘:client失去server的链接
D)...一段时间后,即在“timeout”期间之后,cluster使session过期(移除session句柄),此时客户端并不能获取任何信息和通知,因为它仍没有和cluster server建立链接
E)...一段时候后,client再此和server建立了链接,连接时将会把session id一并发送给server.
F)'EXPIRED':如果session过期,client此时获取一个“过期”的通知。(session 过期后,ZK句柄的所有数据需要重建,及需要重新实例化zookeeper)
Client与Server持续通讯时,也意味着Session是"活跃"的(sessionId将会伴随每次请求交付给server),如果session空闲一段时间,这将会导致过期,所以client会发送一种PING类型的请求来保持session的alive,PING请求不仅可以让server知道client仍然存活,而且它也能够验证当前zk server是否alive。
关于SessionMovedException:这是个内部异常,客户端将不会看到它。发生的原因是,一个请求的发送给server,但是因为网络的原因,此请求packet被延迟了,所以client链接超时后重新链接了其他的server,不过被延迟的packet最终到达了server,不过此旧server检测到此session已经被“moved”(即client所对应的session的"维护者"变成了其他server),就关闭了链接。所以客户端是无法获得此异常,因为旧链接已经被关闭而无法读取数据。。
(源码所涉及到的类: Zookeeper(单机模式下)/LeaderZookeeperServer(分布式模式下),SendThread,SessionTrackImpl.run)大概意思:zookeeperServer启动后(如果是分布式模式,将有LeaderZookeeper负责Session过期控制),都会创建一个SessionTrackImpl,tracker就是跟踪session的,其中一个属性为sessionSets,它是一个map,保持了tick(过期时间)与session,此tick为下一次过期的时间点(计算很有意思,是(当前系统时间/配置文件中的tick + 1)* tick),此时间点为tick间隔的整数倍,并且会不断被延迟。sessionTrack本身就是个线程,此线程会不断轮询,删除那些在过期时间点上的session,删除后,并有leader向集群中其他Followers发送closeSession请求。。线程执行时会检测tick和当前时间的关系,如果大于当前时间,就wait,直到时间点,执行之后,从新计算tick。