zookeeper中节点数量理论上仅受限于内存,但一个节点下的子节点数量受限于request/response 1M数据 (size of data / number of znodes)html
zookeeper的watch机制用于数据变动时zookeeper的主动通知。watch能够被附加到每个节点上,那么若是一个应用有10W个节点,那zookeeper中就可能有10W个watch(甚至更多)。每一次在zookeeper完成改写节点的操做时就会检测是否有对应的watch,有的话则会通知到watch。Zookeeper-Watcher机制与异步调用原理java
本文将关注如下内容:node
在3台机器上分别部署一个zookeeper,版本为3.4.3
,机器配置:git
Intel(R) Xeon(R) CPU E5-2430 0 @ 2.20GHz 16G java version "1.6.0_32" Java(TM) SE Runtime Environment (build 1.6.0_32-b05) OpenJDK (Taobao) 64-Bit Server VM (build 20.0-b12-internal, mixed mode)
大部分实验JVM堆大小使用默认,也就是1/4 RAM
:github
java -XX:+PrintFlagsFinal -version | grep HeapSize
测试客户端使用zk-smoketest,针对watch的测试则是我本身写的。基于zk-smoketest我写了些脚本能够自动跑数据并提取结果,相关脚本能够在这里找到:https://github.com/kevinlynx/zk-benchmarkweb
测试最大10W个节点,度量1秒内操做数(ops):网络
可见节点数的增长并不会对zookeeper读写性能形成影响。session
这个网上其实已经有公认的结论。自己单个节点数据越大,对网络方面的吞吐就会形成影响,因此其数据越大读写性能越低也在预料之中。异步
写数据会在zookeeper集群内进行同步,因此其速度总体会比读数据更慢。该实验须要把超时时间进行必定上调,同时我也把JVM最大堆大小调整到8G。性能
测试结果很明显,节点数据大小会严重影响zookeeper效率。
zk-smoketest自带的latency测试有个参数--watch_multiple
用来指定watch的数量,但其实仅是指定客户端的数量,在server端经过echo whcp | nc 127.0.0.1 4181
会发现实际每一个节点仍是只有一个watch。
在我写的测试中,则是经过建立多个客户端来模拟单个节点上的多个watch。这也更符合实际应用。同时对节点的写也是在另外一个独立的客户端中,这样能够避免zookeeper client的实现对测试带来的干扰。
每一次完整的测试,首先是对每一个节点添加节点数据的watch,而后在另外一个客户端中对这些节点进行数据改写,收集这些改写操做的耗时,以肯定添加的watch对这些写操做带来了多大的影响。
图中,0 watch
表示没有对节点添加watch;1 watch
表示有一个客户端对每一个节点进行了watch;3 watch
表示有其余3个客户端对每一个节点进行了watch;依次类推。
可见,watch对写操做仍是有较大影响的,毕竟须要进行网络传输。一样,这里也显示出整个zookeeper的watch数量同节点数量同样对总体性能没有影响。