【Free Style】ZooKeeper總結材料分享(四)
5.1.4????????共享鎖
共享鎖在同一個進程中很容易實現,但是在跨進程或者在不同?Server?之間就不好實現了。Zookeeper?卻很容易實現這個功能,實現方式也是需要獲得鎖的?Server?創建一個?EPHEMERAL_SEQUENTIAL?目錄節點,然后調用?getChildren方法獲取當前的目錄節點列表中最小的目錄節點是不是就是自己創建的目錄節點,如果正是自己創建的,那么它就獲得了這個鎖,如果不是那么它就調用?exists(String?path, boolean?watch)?方法并監控?Zookeeper?上目錄節點列表的變化,一直到自己創建的節點是列表中最小編號的目錄節點,從而獲得鎖,釋放鎖很簡單,只要刪除前面它自己所創建的目錄節點就行了。
5.2?????????典型應用場景二
利用Zookeeper實現某些分布式應用所必需的高級功能。所有功能均可以在客戶端按固定的模式實現,不需要?Zookeeper的特殊支持,也希望?Zookeeper?社區能將這些具有固定實現模式的功能集成到?Zookeeper?客戶端的程序庫中,可以簡化?Zookeeper?的使用并且還能使某些功能的實現標準化。
即便?Zookeeper?本身使用異步通知(asyn*** ous notifications),但卻可以基于此構建同步的(syn*** ous)一致性原語,如隊列和鎖。你將看到?Zookeeper?實現這些功能是完全可能的,因為?Zookeeper?提供了強制的全序更新,并對外提供了保序接口。
注意下面的程序段試圖采取最佳的編程實踐,尤其是避免使用輪詢(polling),定時器(timers)和其他任何可能造成“羊群效應(herd effect)”機制(“羊群效應”一般會帶來網絡流量的突增,限制系統的可擴展性)。
除了本文所列舉的功能,我們還可以想象出其他很多實用的功能,比如可撤銷的讀寫優先鎖。本文提到的某些構建方式——比如鎖,比較詳細的闡述了使用?Zookepper?的關鍵點,其實你可以找到其他的例子,如事件處理和隊列,但是,本節中的例子只是模擬相關的功能,在具體實踐中需要考慮其他方面的因素。
指定的目錄。
6.2.7????????數據文件管理
1.??數據目錄
ZK的數據目錄包含兩類文件:
l??myid –?這個文件只包含一個數字,和server id對應。
l??snapshot. –?按zxid先后順序的生成的數據快照。
集群中的每臺ZK server都會有一個用于惟一標識自己的id,有兩個地方會使用到這個id:myid文件和zoo.cfg文件中。myid文件存儲在dataDir目錄中,指定了當前server的server id。在zoo.cfg文件中,根據server id,配置了每個server的ip和相應端口。Zookeeper啟動的時候,讀取myid文件中的server id,然后去zoo.cfg?中查找對應的配置。
zookeeper在進行數據快照過程中,會生成?snapshot文件,存儲在dataDir目錄中。文件后綴是zxid,也就是事務id。(這個zxid代表了zk觸發快照那個瞬間,提交的最后一個事務id)。注意,一個快照文件中的數據內容和提交第zxid個事務時內存中數據近似相同。僅管如此,由于更新操作的冪等性,ZK還是能夠從快照文件中恢復數據。數據恢復過程中,將事務日志和快照文件中的數據對應起來,就能夠恢復最后一次更新后的數據了。
2.??事務日志目錄
dataLogDir目錄是ZK的事務日志目錄,包含了所有ZK的事務日志。正常運行過程中,針對所有更新操作,在返回客戶端“更新成功”的響應前,ZK會確保已經將本次更新操作的事務日志寫到磁盤上,只有這樣,整個更新操作才會生效。每觸發一次數據快照,就會生成一個新的事務日志。事務日志的文件名是log.,zxid是寫入這個文件的第一個事務id。
3.??文件管理
不同的zookeeper server生成的snapshot文件和事務日志文件的格式都是一致的(無論是什么環境,或是什么樣的zoo.cfg?配置)。因此,如果某一天生產環境中出現一些古怪的問題,你就可以把這些文件下載到開發環境的zookeeper中加載起來,便于調試發現問題,而不會影響生產運行。另外,使用這些較舊的snapshot和事務日志,我們還能夠方便的讓ZK回滾到一個歷史狀態。
另外,ZK提供的工具類LogFormatter能夠幫助可視化ZK的事務日志,幫助我們排查問題,關于事務日志的可以化,請查看這個文章《可視化zookeeper的事務日志》.
需要注意的一點是,zookeeper在運行過程中,不斷地生成snapshot文件和事務日志,但是不會自動清理它們,需要管理員來處理。(ZK本身只需要使用最新的snapshot和事務日志即可)關于如何清理文件,上面章節“日常運維”有提到。
6.2.8????????注意事項
1.??保持server事務列表一致
·?????????客戶端使用的server地址列表必須和集群所有server的地址列表一致。(如果客戶端配置了集群機器列表的子集的話,也是沒有問題的,只是少了客戶端的容災。)
·?????????集群中每個server的zoo.cfg中配置機器列表必須一致。
2.??獨立的事務日志輸出
對于每個更新操作,ZK都會在確保事務日志已經寫到磁盤后,才會返回客戶端響應。因此事務日志的輸出性能在很大程度上影響ZK的整體吞吐性能。強烈建議是給事務日志的輸出分配一個單獨的磁盤。
3.??配置合理的JVM堆大小
一個合理的JVM堆大小,如果設置太大,會讓內存與磁盤進行交換,這將使ZK的性能大打折扣。例如一個4G內存的機器的,如果你把JVM的堆大小設置為4G或更大,那么會使頻繁發生內存與磁盤空間的交換,通常設置成3G就可以了。當然,為了獲得一個最好的堆大小值,在特定的使用場景下進行一些壓力測試。
7??????配置參數
參數名
說明
clientPort?(配置文件中必須要有)
客戶端連接server的端口,即對外服務端口,一般設置為2181。
dataDir(配置文件中必須要有)
存儲快照文件snapshot的目錄。默認情況下,事務日志也會存儲在這里。建議同時配置參數dataLogDir,事務日志的寫性能直接影響zk性能。
tickTime(配置文件中必須要有)
ZK中的一個時間單元。ZK中所有時間都是以這個時間單元為基礎,進行整數倍配置的。例如,session的最小超時時間是2*tickTime。
dataLogDir
事務日志輸出目錄。盡量給事務日志的輸出配置單獨的磁盤或是掛載點,這將極大的提升ZK性能。(No Java system property)
globalOutstandingLimit
最大請求堆積數。默認是1000。ZK運行的時候,?盡管server已經沒有空閑來處理更多的客戶端請求了,但是還是允許客戶端將請求提交到服務器上來,以提高吞吐性能。當然,為了防止Server內存溢出,這個請求堆積數還是需要限制下的。
(Java system property:zookeeper.globalOutstandingLimit.)
preAllocSize
預先開辟磁盤空間,用于后續寫入事務日志。默認是64M,每個事務日志大小就是64M。如果ZK的快照頻率較大的話,建議適當減小這個參數。(Java system property:zookeeper.preAllocSize)
snapCount
每進行snapCount次事務日志輸出后,觸發一次快照(snapshot),?此時,ZK會生成一個snapshot.*文件,同時創建一個新的事務日志文件log.*。默認是100000.(真正的代碼實現中,會進行一定的隨機數處理,以避免所有服務器在同一時間進行快照而影響性能)(Java system property:zookeeper.snapCount)
traceFile
用于記錄所有請求的log,一般調試過程中可以使用,但是生產環境不建議使用,會嚴重影響性能。(Java system property:?requestTraceFile)
maxClientCnxns
單個客戶端與單臺服務器之間的連接數的限制,是ip級別的,默認是60,如果設置為0,那么表明不作任何限制。請注意這個限制的使用范圍,僅僅是單臺客戶端機器與單臺ZK服務器之間的連接數限制,不是針對指定客戶端IP,也不是ZK集群的連接數限制,也不是單臺ZK對所有客戶端的連接數限制。指定客戶端IP的限制策略,這里有一個patch,可以嘗試一下:(No Java system property)
clientPortAddress
對于多網卡的機器,可以為每個IP指定不同的監聽端口。默認情況是所有IP都監聽clientPort指定的端口。New in 3.3.0
minSessionTimeoutmaxSessionTimeout
Session超時時間限制,如果客戶端設置的超時時間不在這個范圍,那么會被強制設置為最大或最小時間。默認的Session超時時間是在2 *?tickTime ~ 20 * tickTime這個范圍?New in 3.3.0
fsync.warningthresholdms
事務日志輸出時,如果調用fsync方法超過指定的超時時間,那么會在日志中輸出警告信息。默認是1000ms。(Java system property:fsync.warningthresholdms)New in 3.3.4
autopurge.purgeInterval
在上文中已經提到,3.4.0及之后版本,ZK提供了自動清理事務日志和快照文件的功能,這個參數指定了清理頻率,單位是小時,需要配置一個1或更大的整數,默認是0,表示不開啟自動清理功能。(No Java system property)?New in 3.4.0
autopurge.snapRetainCount
這個參數和上面的參數搭配使用,這個參數指定了需要保留的文件數目。默認是保留3個。(No Java system property)New in 3.4.0
electionAlg
在之前的版本中,?這個參數配置是允許我們選擇leader選舉算法,但是由于在以后的版本中,只會留下一種“TCP-based version of fast leader election”算法,所以這個參數目前看來沒有用了,這里也不詳細展開說了。(No Java system property)
initLimit
Follower在啟動過程中,會從Leader同步所有最新數據,然后確定自己能夠對外服務的起始狀態。Leader允許F在initLimit時間內完成這個工作。通常情況下,我們不用太在意這個參數的設置。如果ZK集群的數據量確實很大了,F在啟動的時候,從Leader上同步數據的時間也會相應變長,因此在這種情況下,有必要適當調大這個參數了。(No Java system property)
syncLimit
在運行過程中,Leader負責與ZK集群中所有機器進行通信,例如通過一些心跳檢測機制,來檢測機器的存活狀態。如果L發出心跳包在syncLimit之后,還沒有從F那里收到響應,那么就認為這個F已經不在線了。注意:不要把這個參數設置得過大,否則可能會掩蓋一些問題。(No Java system property)
leaderServes
默認情況下,Leader是會接受客戶端連接,并提供正常的讀寫服務。但是,如果你想讓Leader專注于集群中機器的協調,那么可以將這個參數設置為no,這樣一來,會大大提高寫操作的性能。(Java system property: zookeeper.leaderServes)。
server.x=[hostname]:nnnnn[:nnnnn]
這里的x是一個數字,與myid文件中的id是一致的。右邊可以配置兩個端口,第一個端口用于F和L之間的數據同步和其它通信,第二個端口用于Leader選舉過程中投票通信。
(No Java system property)
group.x=nnnnn[:nnnnn]weight.x=nnnnn
對機器分組和權重設置,可以?參見這里(No Java system property)
cnxTimeout
Leader選舉過程中,打開一次連接的超時時間,默認是5s。(Java system property: zookeeper.cnxTimeout)
zookeeper.DigestAuthenticationProvider
.superDigest
ZK權限設置相關,具體參見《使用super身份對有權限的節點進行操作》?和?《ZooKeeper權限控制》
skipACL
對所有客戶端請求都不作ACL檢查。如果之前節點上設置有權限限制,一旦服務器上打開這個開頭,那么也將失效。(Java system property:zookeeper.skipACL)
forceSync
這個參數確定了是否需要在事務日志提交的時候調用FileChannel.force來保證數據完全同步到磁盤。(Java system property:zookeeper.forceSync)
jute.maxbuffer
每個節點最大數據量,是默認是1M。這個限制必須在server和client端都進行設置才會生效。(Java system property:jute.maxbuffer)
8??????常用的四字指令
參數名
說明
conf
輸出server的詳細配置信息。New in 3.3.0
$>echo conf|nc localhost 2181
clientPort=2181
dataDir=/home/test/taokeeper/zk_data/version-2
dataLogDir=/test/admin/taokeeper/zk_log/version-2
tickTime=2000
maxClientCnxns=1000
minSessionTimeout=4000
maxSessionTimeout=40000
serverId=2
initLimit=10
syncLimit=5
electionAlg=3
electionPort=3888
quorumPort=2888
peerType=0
cons
輸出指定server上所有客戶端連接的詳細信息,包括客戶端IP,會話ID等。
New in 3.3.0類似于這樣的信息:
$>echo cons|nc localhost 2181
/1.2.3.4:43527[1](queued=0,recved=152802,sent=152806,sid=0x2389e662b98c424,lop=PING,
est=1350385542196,to=6000,lcxid=0×114,lzxid=0xffffffffffffffff,lresp=1350690663308,
llat=0,minlat=0,avglat=0,maxlat=483)
……
crst
功能性命令。重置所有連接的統計信息。New in 3.3.0
dump
這個命令針對Leader執行,用于輸出所有等待隊列中的會話和臨時節點的信息。
envi
用于輸出server的環境變量。包括操作系統環境和Java環境。
ruok
用于測試server是否處于無錯狀態。如果正常,則返回“imok”,否則沒有任何響應。
注意:ruok不是一個特別有用的命令,它不能反映一個server是否處于正常工作?!皊tat”命令更靠譜。
stat
輸出server簡要狀態和連接的客戶端信息。
srvr
和stat類似,New in 3.3.0
$>echo stat|nc localhost 2181
Zookeeper version: 3.3.5-1301095, built on 03/15/2012 19:48 GMT
Clients:
/10.2.3.4:59179[1](queued=0,recved=44845,sent=44845)
Latency min/avg/max: 0/0/1036
Received: 2274602238
Sent: 2277795620
Outstanding: 0
Zxid: 0xa1b3503dd
Mode: leader
Node count: 37473
$>echo srvr|nc localhost 2181
Zookeeper version: 3.3.5-1301095, built on 03/15/2012 19:48 GMT
Latency min/avg/max: 0/0/980
Received: 2592698547
Sent: 2597713974
Outstanding: 0
Zxid: 0xa1b356b5b
Mode: follower
Node count: 37473
srst
重置server的統計信息。
wchs
列出所有watcher信息概要信息,數量等:New in 3.3.0
$>echo wchs|nc localhost 2181
3890 connections watching 537 paths
Total watches:6909
wchc
列出所有watcher信息,以watcher的session為歸組單元排列,列出該會話訂閱了哪些path:New in 3.3.0
$>echo wchc|nc localhost 2181
0x2389e662b97917f
/mytest/test/path1/node1
0x3389e65c83cd790
/mytest/test/path1/node2
0x1389e65c7ef6313
/mytest/test/path1/node3
/mytest/test/path1/node1
wchp
列出所有watcher信息,以watcher的path為歸組單元排列,列出該path被哪些會話訂閱著:New in 3.3.0
$>echo wchp|nc localhost 2181
/mytest/test/path1/node
0x1389e65c7eea4f5
0x1389e65c7ee2f68
/mytest/test/path1/node2
0x2389e662b967c29
/mytest/test/path1/node3
0x3389e65c83dd2e0
0x1389e65c7f0c37c
0x1389e65c7f0c364
注意,wchc和wchp這兩個命令執行的輸出結果都是針對session的,對于運維人員來說可視化效果并不理想,可以嘗試將cons命令執行輸出的信息整合起來,就可以用客戶端IP來代替會話ID了,具體可以看這個實現:http://rdc.taobao.com/team/jm/archives/1450
mntr
輸出一些ZK運行時信息,通過對這些返回結果的解析,可以達到監控的效果。New in 3.4.0
$ echo mntr | nc localhost 2185
zk_version 3.4.0
zk_avg_latency 0
zk_max_latency 0
zk_min_latency 0
zk_packets_received 70
zk_packets_sent 69
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count 4
zk_watch_count 0
zk_ephemerals_count 0
zk_approximate_data_size 27
zk_followers 4 – only exposed by the Leader
zk_synced_followers 4 – only exposed by the Leader
zk_pending_syncs 0 – only exposed by the Leader
zk_open_file_descriptor_count 23 – only available on Unix platforms
zk_max_file_descriptor_count 1024 – only available on Unix platforms
9??????其它博文
9.1?????????ZooKeeper----Client端
http://www.cnblogs.com/ggjucheng/p/3376548.html
9.2?????????ZooKeeper?通信模型
http://www.cnblogs.com/ggjucheng/p/3376568.html
10??常見錯誤
&?問題1??通過shell腳本在每個機器上啟動zookeeper的時候,可能會顯示以下錯誤信息”
Can
not open channel to X at election address”J?答案?這是由于zoo.cfg文件中指定的其它zookeeper服務找不到所導致,所有機器的
zookeeper
服務啟動后改錯誤信息提示將會消失
&?問題2??當一個節點啟動zkServer.sh start
后,如果馬上查詢狀態,會提示
”Error contacting service. It is probably not running.”
J?答案??是由于zoo.cfg文件中指定的其它zookeeper服務找不到所導致,所有機器的zookeeper服務啟動后改錯誤信息提示將會消失
,
所有節點都起來后在查詢就正常了
&?問題3??當一個節點啟動zkServer.sh start
后,如果馬上查詢狀態,會提示
”Error contacting service. It is probably not running.”
J
答案
&?問題4??./zkServer.sh start?在3個節點中多已經啟動,但用./zkServer.sh status查詢時servers之間一直沒有建立通訊,當然用./zkCli.sh –server IP:PORT
連接時也連不上J
答案???可能是因為java的權限導致,我試了下用root可以啟動成功。最后用當前賬號安裝的jdk
,啟動就成功了。
JVM ZooKeeper
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。