zookeeper 運(yùn)維經(jīng)驗(yàn)

Zookeeper是一個(gè)分布式協(xié)調(diào)框架冬阳,有不錯(cuò)的性能,也經(jīng)過許多公司的驗(yàn)證获印,所以在很多場景都有使用。大家一般用Zookeeper來實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)(類似DNS)街州,配置管理蓬豁,分布式鎖,leader選舉等菇肃。在這些場景中,Zookeeper成為了一個(gè)被依賴的核心組件取募,Zookeeper的穩(wěn)定性是需要特別關(guān)注的琐谤。

去哪兒網(wǎng)也在很多場景依賴Zookeeper,所以我們也一直在摸索怎么更好的運(yùn)維穩(wěn)定的Zookeeper集群玩敏。在過去的幾年我們也踩過一些坑斗忌,也因?yàn)閆ookeeper導(dǎo)致了故障≈世瘢現(xiàn)在將我們運(yùn)維Zookeeper集群的一些經(jīng)驗(yàn)分享,也歡迎大家提供更好的建議织阳。

那么在打算運(yùn)維一套Zookeeper集群之前眶蕉,我們先了解一些Zookeeper的基本原理。

集群里分三種角色: Leader, Follower和Observer唧躲。Leader和Follower參與投票造挽,Observer只會『聽』投票的結(jié)果,不參與投票弄痹。

投票集群里的節(jié)點(diǎn)數(shù)要求是奇數(shù)

一個(gè)集群容忍掛掉的節(jié)點(diǎn)數(shù)的等式為 N = 2F + 1饭入,N為投票集群節(jié)點(diǎn)數(shù),F(xiàn)為能同時(shí)容忍失敗節(jié)點(diǎn)數(shù)肛真。比如一個(gè)三節(jié)點(diǎn)集群谐丢,可以掛掉一個(gè)節(jié)點(diǎn),5節(jié)點(diǎn)集群可以掛掉兩個(gè)...

一個(gè)寫操作需要半數(shù)以上的節(jié)點(diǎn)ack蚓让,所以集群節(jié)點(diǎn)數(shù)越多乾忱,整個(gè)集群可以抗掛點(diǎn)的節(jié)點(diǎn)數(shù)越多(越可靠),但是吞吐量越差历极。

Zookeeper里所有節(jié)點(diǎn)以及節(jié)點(diǎn)的數(shù)據(jù)都會放在內(nèi)存里窄瘟,形成一棵樹的數(shù)據(jù)結(jié)構(gòu)。并且定時(shí)的dump snapshot到磁盤执解。

Zookeeper的Client與Zookeeper之間維持的是長連接寞肖,并且保持心跳,Client會與Zookeeper之間協(xié)商出一個(gè)Session超時(shí)時(shí)間出來(其實(shí)就是Zookeeper Server里配置了最小值衰腌,最大值新蟆,如果client的值在這兩個(gè)值之間則采用client的,小于最小值就是最小值右蕊,大于最大值就用最大值)琼稻,如果在Session超時(shí)時(shí)間內(nèi)沒有收到心跳,則該Session過期饶囚。

Client可以watch Zookeeper那個(gè)樹形數(shù)據(jù)結(jié)構(gòu)里的某個(gè)節(jié)點(diǎn)或數(shù)據(jù)帕翻,當(dāng)有變化的時(shí)候會得到通知。

有了這些了解后萝风,那么我們心里其實(shí)有底了嘀掸。

1. 最小生產(chǎn)集群

要確保Zookeeper能夠穩(wěn)定運(yùn)行,那么就需要確保投票能夠正常進(jìn)行规惰,最好不要掛一個(gè)節(jié)點(diǎn)整個(gè)就不work了睬塌,所以我們一般要求最少5個(gè)節(jié)點(diǎn)部署。

2. 網(wǎng)絡(luò)

除了節(jié)點(diǎn)外,我們還要看不能一臺物理機(jī)器揩晴,一個(gè)機(jī)柜或一個(gè)交換機(jī)掛掉然后影響了整個(gè)集群勋陪,所以節(jié)點(diǎn)的網(wǎng)絡(luò)結(jié)構(gòu)也要考慮。這個(gè)可能就比很多應(yīng)用服務(wù)器的要求更加嚴(yán)格硫兰。

3. 分Group诅愚,保護(hù)核心Group

要確保Zookeeper整個(gè)集群可靠運(yùn)行,就是要確保投票集群可靠劫映。那在我們這里违孝,將一個(gè)Zookeeper集群劃分為多個(gè)小的Group,我們稱Leader+Follower為核心Group苏研,核心Group我們一般是不向外提供服務(wù)的等浊,然后我們會根據(jù)不同的業(yè)務(wù)再加一些Observer,比如一個(gè)Zookeeper集群為服務(wù)發(fā)現(xiàn)摹蘑,消息筹燕,定時(shí)任務(wù)三個(gè)不同的組件提供服務(wù),那么我們?yōu)榻⑷齻€(gè)Observer Group衅鹿,分別給這三個(gè)組件使用撒踪,而Client只會連接分配給它的Observer Group,不去連接核心Group大渤。這樣核心Group就不會給Client提供長連接服務(wù)制妄,也不負(fù)責(zé)長連接的心跳,這大大的減輕了核心Group的壓力泵三,因?yàn)樵趯?shí)際環(huán)境中耕捞,一個(gè)Zookeeper集群要為上萬臺機(jī)器提供服務(wù),維持長連接和心跳還是要消耗一定的資源的烫幕。因?yàn)镺bserver是不參與投票的所以加Observer并不會降低整體的吞吐量俺抽,而且Observer掛掉不會影響整個(gè)集群的健康。

但是這里要注意的是较曼,分Observer Group只能解決部分問題磷斧,因?yàn)楫吘顾械膶懭脒€是要交給核心Group來處理的,所以對于寫入量特別大的應(yīng)用來說捷犹,還是需要進(jìn)行集群上的隔離弛饭,比如Storm和Kafka就對Zookeeper壓力比較大,你就不能將其與服務(wù)發(fā)現(xiàn)的集群放在一起萍歉。

4. 內(nèi)存

因?yàn)閆ookeeper將所有數(shù)據(jù)都放在內(nèi)存里侣颂,所以對JVM以及機(jī)器的內(nèi)存也要預(yù)先計(jì)劃,如果出現(xiàn)Swap那將嚴(yán)重的影響Zookeeper集群的性能枪孩,所以我一般不怎么推薦將Zookeeper用作通用的配置管理服務(wù)横蜒。因?yàn)橐话闩渲脭?shù)據(jù)還是挺大的胳蛮,這些全部放在內(nèi)存里不太可控。

5. 日志清理

因?yàn)閆ookeeper要頻繁的寫txlog(Zookeeper寫的一種順序日志)以及定期dump內(nèi)存snapshot到磁盤丛晌,這樣磁盤占用就越來越大,所以Zookeeper提供了清理這些文件的機(jī)制斗幼,但是這種機(jī)制并不太合理澎蛛,它只能設(shè)置間隔多久清理,而不能設(shè)置具體的時(shí)間段蜕窿。那么就有可能碰到高峰期間清理谋逻,所以建議將其關(guān)閉:autopurge.purgeInterval=0。然后使用crontab等機(jī)制桐经,在業(yè)務(wù)低谷的時(shí)候清理毁兆。

6. 日志,jvm配置

從官網(wǎng)直接下載的包如果直接啟動(dòng)運(yùn)行是很糟糕的阴挣,這個(gè)包默認(rèn)的配置日志是不會輪轉(zhuǎn)的气堕,而且是直接輸出到終端。我們最開始并不了解這點(diǎn)畔咧,然后運(yùn)行一段時(shí)間后發(fā)現(xiàn)生成一個(gè)龐大的zookeeper.out的日志文件茎芭。除此之外,這個(gè)默認(rèn)配置還沒有設(shè)置任何jvm相關(guān)的參數(shù)(所以堆大小是個(gè)默認(rèn)值)誓沸,這也是不可取的梅桩。那么有的同學(xué)說那我去修改Zookeeper的啟動(dòng)腳本吧。最好不要這樣做拜隧,Zookeeper會加載conf文件夾下一個(gè)名為zookeeper-env.sh的腳本宿百,所以你可以將一些定制化的配置寫在這里,而不是直接去修改Zookeeper自帶的腳本洪添。

#!/usr/bin/env bash

JAVA_HOME= #java home

ZOO_LOG_DIR= #日志文件放置的路徑

ZOO_LOG4J_PROP="INFO,ROLLINGFILE" #設(shè)置日志輪轉(zhuǎn)

JVMFLAGS="jvm的一些設(shè)置垦页,比如堆大小,開gc log等"

7. 地址

在實(shí)際環(huán)境中薇组,我們可能因?yàn)楦鞣N原因比如機(jī)器過保外臂,硬件故障等需要遷移Zookeeper集群,所以Zookeeper的地址是一個(gè)很頭痛的事情律胀。這個(gè)地址有兩方面宋光,第一個(gè)是提供給Client的地址,建議這個(gè)地址通過配置的方式下發(fā)炭菌,不要讓使用方直接使用罪佳,這一點(diǎn)我們前期做的不好。另外一個(gè)是集群配置里黑低,集群之間需要通訊赘艳,也需要地址酌毡。我們的處理方式是設(shè)置hosts:

192.168.1.20 zk1

192.168.1.21 zk2

192.168.1.22 zk3

在配置里:

server.1=zk1:2081:3801

server.2=zk2:2801:3801

server.3=zk3:2801:3801

這樣在需要遷移的時(shí)候,我們停老的節(jié)點(diǎn)蕾管,起新的節(jié)點(diǎn)只需要修改hosts映射就可以了枷踏。比如現(xiàn)在server.3需要遷移,那我們在hosts里將zk3映射到新的ip地址掰曾。但是對于java有一個(gè)問題是旭蠕,java默認(rèn)會永久緩存DNS cache,即使你將zk3映射到別的ip旷坦,如果并不重啟server.1, server.2掏熬,它是不會解析到新的ip的,這個(gè)需要修改$JAVA_HOME/jre/lib/security/java.security文件里的networkaddress.cache.ttl=60秒梅,將其修改為一個(gè)比較小的數(shù)旗芬。

對于這個(gè)遷移的問題,我們還遇到一個(gè)比較尷尬的情況捆蜀,在最后的坑里會有提及疮丛。

8. 日志位置

Zookeeper主要產(chǎn)生三種IO: txlog(每個(gè)寫操作,包括新Session都會記錄一條log)漱办,Snapshot以及運(yùn)行的應(yīng)用日志这刷。一般建議將這三個(gè)IO分散到三個(gè)不同的盤上。不過我們倒是一直沒有這么實(shí)驗(yàn)過娩井,我們的Zookeeper也是運(yùn)行在虛擬機(jī)(一般認(rèn)為虛擬機(jī)IO較差)上暇屋。

9. 監(jiān)控

我們對Zookeeper做了這樣一些監(jiān)控:

a. 是否可寫。 就是一個(gè)定時(shí)任務(wù)定時(shí)的去創(chuàng)建節(jié)點(diǎn)洞辣,刪節(jié)點(diǎn)等操作咐刨。這里要注意的是Zookeeper是一個(gè)集群,我們監(jiān)控的時(shí)候我還是希望對單個(gè)節(jié)點(diǎn)做監(jiān)控扬霜,所以這些操作的時(shí)候不要連接整個(gè)集群定鸟,而是直接去連接單個(gè)節(jié)點(diǎn)。

b. 監(jiān)控watcher數(shù)和連接數(shù) 特別是這兩個(gè)數(shù)據(jù)有較大波動(dòng)的時(shí)候著瓶,可以發(fā)現(xiàn)使用方是否有誤用的情況

c. 網(wǎng)絡(luò)流量以及client ip 這個(gè)會記錄到監(jiān)控系統(tǒng)里联予,這樣很快能發(fā)現(xiàn)『害群之馬』

10. 一些使用建議

a. 不要強(qiáng)依賴Zookeeper,也就是Zookeeper出現(xiàn)問題業(yè)務(wù)已然可以正常運(yùn)行材原。Zookeeper是一個(gè)分布式的協(xié)調(diào)框架沸久,主要做的事情就是分布式環(huán)境的一致性。這是一個(gè)非秤嘈罚苛刻的事情卷胯,所以它的穩(wěn)定性受很多方面的影響。比如我們常常使用Zookeeper做服務(wù)發(fā)現(xiàn)威酒,那么服務(wù)發(fā)現(xiàn)其實(shí)是不需要嚴(yán)格的一致性的窑睁,我們可以緩存server list挺峡,當(dāng)Zookeeper出現(xiàn)問題的時(shí)候已然可以正常工作,在這方面etcd要做的更好一些担钮,Zookeeper如果出現(xiàn)分區(qū)橱赠,少數(shù)派是不能提供任何服務(wù)的,讀都不可以裳朋,而etcd的少數(shù)派仍然可以提供讀服務(wù)病线,這在服務(wù)發(fā)現(xiàn)的時(shí)候還是不錯(cuò)的。

b. 不要將很多東西塞到Zookeeper里鲤嫡,這個(gè)上面已經(jīng)提到過。

c. 不要使用Zookeeper做細(xì)粒度鎖绑莺,比如很多業(yè)務(wù)在訂單這個(gè)粒度上使用Zookeeper做分布式鎖暖眼,這會頻繁的和Zookeeper交互,對Zookeeper壓力較大纺裁,而且一旦出現(xiàn)問題影響面廣诫肠。但是可以使用粗粒度的鎖(其實(shí)leader選舉也是一種鎖)。

d. 不建議做通用配置的第二個(gè)理由是欺缘,通用配置要提供給特別多特別多系統(tǒng)使用栋豫,而且一些公共配置甚至所有系統(tǒng)都會使用,一旦這樣的配置發(fā)生變更谚殊,Zookeeper會廣播給所有的watcher丧鸯,然后所有Client都來拉取,瞬間造成非常大的網(wǎng)絡(luò)流量嫩絮,引起所謂的『驚群』丛肢。而自己實(shí)現(xiàn)通用配置系統(tǒng)的時(shí)候,一般會對這種配置采取排隊(duì)或分批通知的方式剿干。

11. 一些坑

a. zookeeper client 3.4.5 ping時(shí)間間隔算法有問題蜂怎,在遇到網(wǎng)絡(luò)抖動(dòng)等原因?qū)е乱淮蝡ing失敗后會斷開連接。3.4.6解決了這個(gè)問題 Bug1751置尔。

b. zookeeper client如果因?yàn)榫W(wǎng)絡(luò)抖動(dòng)斷開了連接杠步,如果后來又重連上了,zookeeper client會自動(dòng)的將之前訂閱的watcher等又全部訂閱一遍榜轿,而Zookeeper默認(rèn)對單個(gè)數(shù)據(jù)包的大小有個(gè)1M的限制幽歼,這往往就會超限,最后導(dǎo)致一直不斷地的重試差导。這個(gè)問題在較新的版本得到了修復(fù)试躏。Bug706

c. 拋出UnresolvedAddressException異常導(dǎo)致Zookeeper選舉線程退出,整個(gè)集群無法再選舉设褐,處于崩潰的邊緣颠蕴。這個(gè)問題是泣刹,某次OPS遷移機(jī)器,將老的機(jī)器回收了犀被,所以老的機(jī)器的IP和機(jī)器名不復(fù)存在椅您,最后拋出UnresolvedAddressException這個(gè)異常,而Zookeeper的選舉線程(QuorumCnxManager類里的Listener)只捕獲了IOException寡键,導(dǎo)致該線程退出掀泳,該線程一旦退出只要現(xiàn)在的leader出現(xiàn)問題,需要重新選舉西轩,則不會選出新的leader來员舵,整個(gè)集群就會崩潰。Bug2319(PS藕畔,這個(gè)bug是我report的)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末马僻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子注服,更是在濱河造成了極大的恐慌韭邓,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件溶弟,死亡現(xiàn)場離奇詭異女淑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辜御,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門鸭你,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人我抠,你說我怎么就攤上這事苇本。” “怎么了菜拓?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵瓣窄,是天一觀的道長。 經(jīng)常有香客問我纳鼎,道長俺夕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任贱鄙,我火速辦了婚禮劝贸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逗宁。我一直安慰自己映九,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布瞎颗。 她就那樣靜靜地躺著件甥,像睡著了一般捌议。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上引有,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天瓣颅,我揣著相機(jī)與錄音,去河邊找鬼譬正。 笑死宫补,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的曾我。 我是一名探鬼主播粉怕,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抒巢!你這毒婦竟也來了斋荞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤虐秦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后凤优,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悦陋,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年筑辨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了俺驶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棍辕,死狀恐怖暮现,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情楚昭,我是刑警寧澤栖袋,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站抚太,受9級特大地震影響塘幅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尿贫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一电媳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庆亡,春花似錦匾乓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娱局。三九已至,卻和暖如春珍促,著一層夾襖步出監(jiān)牢的瞬間桑阶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工瞪慧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留夹囚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓穴翩,卻偏偏與公主長得像犬第,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子芒帕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容