tickTime
以毫秒为单位的基本时间单位。用来测试心跳;最小的会话超时时间是tickTime的两倍。 dataDir
内存数据库快照的存放位置以及事务日志的默认存放位置(除非指定了其他位置)。 clientPort
监听客户端连接的端口 initLimit
集群中的Server连接到Leader的超时时间。 syncLimit
集群中的Server可以脱离Leader的最长时间。 3、单节点部署注意事项
不一致的服务器列表
客户端使用的ZooKeeper服务器列表必须和每个ZooKeeper服务器配置的列表一致。如果客户端的列表是真实列表的子集,可能还可以正常工作;但是如果客户端列表是不同ZooKeeper集群的服务器时,就会有很多奇怪的现象。并且,集群中每个服务器的配置文件中的服务器列表也应该彼此相同。
不正确的事务日志存放
ZooKeeper影响性能最大的地方是事务日志。ZooKeeper在返回响应之前需要同步事务到磁盘中。一个专用的事务日志存放设备是获取高性能必不可少的。
不正确的Java堆大小
设置Java最大堆内存时要特别小心。应该避免出现ZooKeeper交换至磁盘的情况。一切都是有序的,所以如果某个正在处理的请求被交换至磁盘,那么队列中的所有请求可能都要这么多。所以DON’T SWAP。
估算的时候应该持保守态度:4G RAM,不要设置Java最大堆内存到6G甚至4G。举例来说,对于一个4G机器你可以使用3G的堆内存,因为操作系统和缓存也需要内存。估算堆大小最好也是推荐的方式是进行测试。 4、Zookeeper以及调度管理中心升级
全部停掉升级或轮流停止升级。
Zookeeper集群(3台)在停掉两台机器后,是无法提供服务的,只允许停掉一台机器;调度管理中心只要保证一台机器正常,即可提供调度服务。 二、集成zookeeper二次开发 1、调度管理中心的选举算法
目的:选择调度管理中心的Leader,使用zookeeper提供的接口。
角色:调度管理中心作为zookeeper集群的客户端。
避免:羊群效应;事件发生后,唤醒了大量在其上监听的客户端,而实际上只有部分客户端能够处理该事件(盲目唤醒了不必要的客户端);避免方法,不是所有节点都监视leader是否死亡,而是监视前一个比sequence自己小的客户端。 2、节点故障处理机制 2.1 连接丢失
CONNECTION_LOSS:表示客户端和服务器之间的连接断开。它不能代表请求失败了(例如,create请求到达server之后,server成功创建节点,但是在返回响应前连接断开)。zookeeper无法区分请求没有发出还是响应没有收到的情况,因此它统一返回CONNECTION_LOSS;应用程序需要负责检测这种情况。
处理方法:
①请求管理:程序应该判断请求是成功还是需要重试,通常通过应用程序相关的方式。例如查看要创建的节点是否已经存在或者检查要修改的节点值。
②连接管理:当客户端的连接状态变为CONNECTION_LOSS后,会查找指定的服务器列表(构造zookeeper对象时传入的connectString)进行重连。在会话超时之前重连成功,该客户端的连接状态变为CONNECTED;在会话超时之后重连成功,状态变为SESSION_EXPIRED。
结论:只有在收到会话超时的通知后,才去创建一个新的连接。 2.2 会话超时
定义及现象:会话超时发生在集群在指定的会话超时周期内没有收到客户端的回复(即无心跳)。会话超时后,集群删除该会话的所有临时节点,并且立即通知所有在这些znodes上监听的已经连接的客户端。此时会话超时的客户端和集群仍然是断开的,它不会被通知会话超时,除非它能够和集群重新建立连接(可见这个消息已经不是实时的了)。
SESSION_EXPIRED:会使zookeeper自动关闭连接。一个正确操作的集群,永远不应该看到SESSION_EXPIRED错误。他表示客户端离开zookeeper超过会话超时时间,并且zookeeper确定它已经死亡。由于zookeeper服务是稳定的,这个时候客户端应该认为自己已经死了,并且准备恢复。
处理方法:如果客户端只是从zookeeper读取状态,那恢复只是意味着重新连接;但是在复杂的应用程序中,恢复可能还意味着重新创建临时节点,争夺领导角色,重新构造发布状态等。 2.3 Server关闭
考虑下面的场景:客户端以5秒的会话超时时间连接到ZK,管理员为了升级关闭了整个ZK集群,集群停机几分钟后重启。
在这种情况下,客户端可以重新连接并刷新它的会话。因为会话超时是由Leader跟踪的,当集群重启后,会话会重新进行倒计时。因此,只要客户端在Leader选举后的第一个5秒内连接就不会超时,并且它之前拥有的临时节点也不会消失。
对于Leader挂掉,重新选举Leader的情况是一样的,会话超时计时器会重置。 2.4 zookeeper.close
一旦zookeeper对象关闭或者接收到一个致命事件(SESSION_EXPIRED、AUTH_FAILED),zookeeper对象变成不可用。此时,客户端的IO线程和Event线程关闭,后续的请求是未定义行为并且会被忽略(any further access on zookeeper handle is undefined behavior and should be avoided)。 3、一致性保证
不保证:zookeeper并不保证在任何时候,两个不同的客户端看到的zookeeper数据是一样的。由于某些因素如网络延迟,一个客户端更新数据可能比另外一个客户端得到
变更通知要早。考虑两个客户端A和B的情况,如果客户端A更改znode /a从0变到1;然后客户端B读取/a,那么客户端B可能读取到的是旧值0,取决于B所连接的server。如果客户端A和客户端B看到的数据一致非常重要,客户端B应该在调用read方法之前,调用同步方法sync。
也就是说,zookeeper本身不保证任何时候,任何server的数据是一致的,但是提供了有用的客户端同步机制。 4、认证
认证方式是可扩展的,实现AuthenticationProvider 可提供自己的认证方式。
zookeeper内置两种认证插件:ip and digest. 三、性能
在读操作比写操作频繁的应用中,zookeeper性能更佳(写操作涉及到所有server的同步)。分布式应用中,通常情况下读操作比写操作频繁。
测试条件:
Zookeeper版本: ZooKeeper release 3.2
主机:双核2Ghz Xeon处理器
磁盘:SATA 15K RPM
部署方式:其中一个磁盘作为zookeeper事务日志专用设备,快照写入到操作系统磁盘。
测试方式:写操作和读操作数据大小1K;大约30台服务器模拟客户端;zookeeper集群设置为领导者不接受客户端的连接。 四、可靠性
常规配置:同上
集群规模:7台主机组成
写操作占所有操作的30%(请求里面有30%是要求写数据的)
测试步骤:
Failure and recovery of a follower 重启一个follower
Failure and recovery of a different follower 重启另外一个不同的follower
Failure of the leader 挂掉Leader
Failure and recovery of two followers 同时重启两个follower
Failure of another leader 挂掉另外一个Leader(重新选举出来的那个)
从图中可以得出几个重要的点:
1、如果跟随者宕机并很快恢复,zookeeper能够维持一个很高的吞吐量。
2、Leader选举算法可以保证系统快速恢复以阻止吞吐量的大幅下降。上图中zookeeper花费不到200ms选举一个新的Leader。
3、一旦跟随者开始处理请求,zookeeper能够重新提高吞吐量。 五、客户端API
1、public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher)
会话建立的过程是异步的。该构造函数初始化到server的连接,并且立即返回(通常比会话完全建立要早)。
参数Watcher指定当发生状态变化时被通知的watcher。该通知可能在任何时候到达(构造函数返回之前或之后都有可能)。
主机选择是随机从connectString挑选的。
2、public String create(final String path, byte data[], List<ACL> acl, CreateMode createMode)
CreateMode.PERSISTENT:不会被zookeeper自动移除
CreateMode.EPHEMERAL:当创建节点关联的会话失效时,临时节点会被zookeeper自动移除
节点数据最大是1MB,超过会抛出KeeperException。
触发监控:exists() of current node and getChildren() of parent node。
3、public void delete(final String path, int version)
触发监控:exists() of current node and getChildren() of parent node。
4、public synchronized void close()
触发监控:The watches left on those nodes (and on their parents) will be triggered.
5、public Stat setData(final String path, byte data[], int version)
触发监控:getData() of current node. 六、Watcher丢失
只有一种情况会出现watch丢失:监控一个还没有创建的znode是否存在的watch,如果在断开连接的过程中该znode被创建并且又被删除了,这时重新连接后该watch会丢失。
正常情况下,重新连接后会话没有超时,此时会从Leader进行同步,watch不会丢失。
当然,如果重新连接过久导致会话超时,这时需要新建一个zookeeper,属于另外一个连接,原来连接上面的watch需要重新注册。 七、重新选举Leader的延迟
第四章-可靠性章节中显示,在有七台主机组成的集群中,一次Leader选举只花费不到200ms的时间。
如果对此仍然需要考虑的话,那么和第二章-第2节节点故障处理机制中列出的4点故障一起考虑,有两种方式处理:
对于发送不成功的请求进行缓存和重试一定次数之后,就将请求丢弃。 八、常用功能
1、配置管理:
数据存放在某个节点,所有其他节点到该节点读取数据getData(true),并监听;数据变更之后,其他节点收到变更通知,调用getData(true)获取新数据并进行下次变更监听。