zookeeper中節(jié)點(diǎn)數(shù)量理論上僅受限于內(nèi)存,但一個(gè)節(jié)點(diǎn)下的子節(jié)點(diǎn)數(shù)量受限于request/response 1M數(shù)據(jù) (size of data / number of znodes)
zookeeper的watch機(jī)制用于數(shù)據(jù)變更時(shí)zookeeper的主動(dòng)通知。watch可以被附加到每一個(gè)節(jié)點(diǎn)上,那么如果一個(gè)應(yīng)用有10W個(gè)節(jié)點(diǎn),那zookeeper中就可能有10W個(gè)watch(甚至更多)。每一次在zookeeper完成改寫(xiě)節(jié)點(diǎn)的操作時(shí)就會(huì)檢測(cè)是否有對(duì)應(yīng)的watch,有的話則會(huì)通知到watch。Zookeeper-Watcher機(jī)制與異步調(diào)用原理
本文將關(guān)注以下內(nèi)容:
- zookeeper的性能是否會(huì)受節(jié)點(diǎn)數(shù)量的影響
- zookeeper的性能是否會(huì)受watch數(shù)量的影響
測(cè)試方法
在3臺(tái)機(jī)器上分別部署一個(gè)zookeeper,版本為3.4.3
,機(jī)器配置:
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)
大部分實(shí)驗(yàn)JVM堆大小使用默認(rèn),也就是1/4 RAM
:
java -XX:+PrintFlagsFinal -version | grep HeapSize
測(cè)試客戶端使用zk-smoketest,針對(duì)watch的測(cè)試則是我自己寫(xiě)的。基于zk-smoketest我寫(xiě)了些腳本可以自動(dòng)跑數(shù)據(jù)并提取結(jié)果,相關(guān)腳本可以在這里找到:https://github.com/kevinlynx/zk-benchmark
測(cè)試結(jié)果
節(jié)點(diǎn)數(shù)對(duì)讀寫(xiě)性能的影響
測(cè)試最大10W個(gè)節(jié)點(diǎn),度量1秒內(nèi)操作數(shù)(ops):

可見(jiàn)節(jié)點(diǎn)數(shù)的增加并不會(huì)對(duì)zookeeper讀寫(xiě)性能造成影響。
節(jié)點(diǎn)數(shù)據(jù)大小對(duì)讀寫(xiě)性能的影響
這個(gè)網(wǎng)上其實(shí)已經(jīng)有公認(rèn)的結(jié)論。本身單個(gè)節(jié)點(diǎn)數(shù)據(jù)越大,對(duì)網(wǎng)絡(luò)方面的吞吐就會(huì)造成影響,所以其數(shù)據(jù)越大讀寫(xiě)性能越低也在預(yù)料之中。

寫(xiě)數(shù)據(jù)會(huì)在zookeeper集群內(nèi)進(jìn)行同步,所以其速度整體會(huì)比讀數(shù)據(jù)更慢。該實(shí)驗(yàn)需要把超時(shí)時(shí)間進(jìn)行一定上調(diào),同時(shí)我也把JVM最大堆大小調(diào)整到8G。
測(cè)試結(jié)果很明顯,節(jié)點(diǎn)數(shù)據(jù)大小會(huì)嚴(yán)重影響zookeeper效率。
watch對(duì)讀寫(xiě)性能的影響
zk-smoketest自帶的latency測(cè)試有個(gè)參數(shù)--watch_multiple
用來(lái)指定watch的數(shù)量,但其實(shí)僅是指定客戶端的數(shù)量,在server端通過(guò)echo whcp | nc 127.0.0.1 4181
會(huì)發(fā)現(xiàn)實(shí)際每個(gè)節(jié)點(diǎn)還是只有一個(gè)watch。
在我寫(xiě)的測(cè)試中,則是通過(guò)創(chuàng)建多個(gè)客戶端來(lái)模擬單個(gè)節(jié)點(diǎn)上的多個(gè)watch。這也更符合實(shí)際應(yīng)用。同時(shí)對(duì)節(jié)點(diǎn)的寫(xiě)也是在另一個(gè)獨(dú)立的客戶端中,這樣可以避免zookeeper client的實(shí)現(xiàn)對(duì)測(cè)試帶來(lái)的干擾。
每一次完整的測(cè)試,首先是對(duì)每個(gè)節(jié)點(diǎn)添加節(jié)點(diǎn)數(shù)據(jù)的watch,然后在另一個(gè)客戶端中對(duì)這些節(jié)點(diǎn)進(jìn)行數(shù)據(jù)改寫(xiě),收集這些改寫(xiě)操作的耗時(shí),以確定添加的watch對(duì)這些寫(xiě)操作帶來(lái)了多大的影響。

圖中,0 watch
表示沒(méi)有對(duì)節(jié)點(diǎn)添加watch;1 watch
表示有一個(gè)客戶端對(duì)每個(gè)節(jié)點(diǎn)進(jìn)行了watch;3 watch
表示有其他3個(gè)客戶端對(duì)每個(gè)節(jié)點(diǎn)進(jìn)行了watch;依次類推。
可見(jiàn),watch對(duì)寫(xiě)操作還是有較大影響的,畢竟需要進(jìn)行網(wǎng)絡(luò)傳輸。同樣,這里也顯示出整個(gè)zookeeper的watch數(shù)量同節(jié)點(diǎn)數(shù)量一樣對(duì)整體性能沒(méi)有影響。
總體結(jié)論
- 對(duì)單個(gè)節(jié)點(diǎn)的操作并不會(huì)因?yàn)閦ookeeper中節(jié)點(diǎn)的總數(shù)而受到影響
- 數(shù)據(jù)大小對(duì)zookeeper的性能有較大影響,性能和內(nèi)存都會(huì)
- 單個(gè)節(jié)點(diǎn)上獨(dú)立session的watch數(shù)對(duì)性能有一定影響