ClickHouse 案例 | ClickHouse 連接 ZK 頻繁超時(shí)處理案例
1、背景:
我們線上有一套clickhouse集群,5分片2副本總計(jì)10個(gè)實(shí)例,每個(gè)實(shí)例獨(dú)占1臺(tái)物理機(jī),配套混布一個(gè)3節(jié)點(diǎn)zookeeper集群。
軟件版本:centos 7.5 ?+ CK 19.7.3 + ZK 3.4.13
從昨天開(kāi)始應(yīng)用寫(xiě)入日志開(kāi)始堆積,并不斷的報(bào)錯(cuò)zookeeper session timeout。
登錄機(jī)器查看clickhouse的errlog,大量的timeout信息:
2021.09.29?05:48:19.940814?[?32?]?{}??app.log_dev_local?(ReplicatedMergeTreeRestartingThread):?ZooKeeper?session?has?expired.?Switching?to?a?new?session.
2021.09.29?05:48:19.949000?[?25?]?{}??app.log_k8s_local?(ReplicatedMergeTreeRestartingThread):?ZooKeeper?session?has?expired.?Switching?to?a?new?session.
2021.09.29?05:48:19.952341?[?30?]?{}??app.log_dev_local?(ReplicatedMergeTreeRestartingThread):?void?DB::ReplicatedMergeTreeRestartingThread::run():?Code:?999,?e.displayText()?=?Coordination::Exception:?All?con
nection?tries?failed?while?connecting?to?ZooKeeper.?Addresses:?10.1.1.1:2181,?10.1.1.1.2:2181,?10.1.1.3:2181
2、診斷
查看zookeeper狀態(tài),3個(gè)實(shí)例都執(zhí)行
echo?stat|nc?127.0.0.1?2181

返回1個(gè)leader 2個(gè)follower,集群狀態(tài)是正常的,但是該命令執(zhí)行很慢。
嘗試登錄zk實(shí)例
sh?/usr/lib/zookeeper/bin/zkCli.sh?-server?127.0.0.1:2181
進(jìn)入登錄界面后執(zhí)行 ls /卡頓半天,然后返回timeout。應(yīng)該是ZK集群通信出了問(wèn)題,先對(duì)其進(jìn)行滾動(dòng)重啟,重啟后問(wèn)題依然存在。
嘗試調(diào)優(yōu)zk參數(shù),當(dāng)前參數(shù)為
tickTime=?2000?
syncLimit?=?10
minSessionTimeout?=?4000
maxSessionTimeout?=?120000
forceSync=yes
leaderServes?=?yes
調(diào)整成
tickTime=?2000?
syncLimit?=?100
minSessionTimeout?=?40000
maxSessionTimeout?=?600000
forceSync=?no
leaderServes?=?no
重啟集群后問(wèn)題依然存在。
我們線上有4套CK集群,每套都獨(dú)占一套zk,其余3套集群的zookeeper的內(nèi)存只有幾十K,Node count只有幾萬(wàn),而出問(wèn)題的這套Node count有2千多萬(wàn),zookeeper進(jìn)程內(nèi)存30G左右。
現(xiàn)在懷疑是Node count過(guò)多,導(dǎo)致節(jié)點(diǎn)通信擁堵,于是想辦法降低Node數(shù)量:
該環(huán)境有一套kafka混用了ZK集群,為其搭建了一套專(zhuān)屬ZK集群并將ZK元數(shù)據(jù)目錄刪除,node count和物理內(nèi)存依然很高,問(wèn)題沒(méi)有解決。 清理無(wú)用表,找出600多個(gè)表,執(zhí)行drop后,node count和物理內(nèi)存依然很高,問(wèn)題沒(méi)有解決。降低Node count的嘗試失敗。
排查到現(xiàn)在,基本能想到的招數(shù)都已用到,再整理一下思路:
ZK節(jié)點(diǎn)響應(yīng)很慢,但是集群狀態(tài)是正常的; CK的insert經(jīng)常超時(shí),但是偶爾能執(zhí)行成功; 增大ZK的超時(shí)參數(shù),沒(méi)有絲毫改善 ZK的node count非常多,當(dāng)前的3個(gè)ZK實(shí)例占用內(nèi)存很高(RSS一直在30G上下浮動(dòng))
zookeeper實(shí)例本質(zhì)是1個(gè)java進(jìn)程,有沒(méi)有可能是達(dá)到內(nèi)存上限頻繁的觸發(fā)full gc,進(jìn)而導(dǎo)致ZK服務(wù)響應(yīng)經(jīng)常性卡頓?
搜索半天沒(méi)有在機(jī)器上發(fā)現(xiàn)full gc的日志記錄,只能直接驗(yàn)證一下猜想。
在/usr/lib/zookeeper/conf目錄下新建1個(gè)文件java.env,內(nèi)容如下:
export?JVMFLAGS="-Xms16384m?-Xmx32768m?$JVMFLAGS"
滾動(dòng)重啟ZK集群,啟動(dòng)完畢后問(wèn)題依然存在,但是ZK實(shí)例的RSS從原來(lái)的30G上升到了33G,超出了Xmx上限。
應(yīng)該是沒(méi)吃飽,修改一下文件參數(shù)
export?JVMFLAGS="-Xms16384m?-Xmx65536m?$JVMFLAGS"
再次重啟ZK集群,ZK實(shí)例的RSS飆升到55G左右就不再上升,困擾多時(shí)的問(wèn)題也自動(dòng)消失了,看來(lái)剛剛的full gc猜想是正確的。
既然已經(jīng)證明是JVM heap內(nèi)存的問(wèn)題,那么剛剛調(diào)整的ZK參數(shù)就全部回滾,然后滾動(dòng)重啟ZK集群。
3、溯源
系統(tǒng)自此穩(wěn)定了,但是zk進(jìn)程占用的物理內(nèi)存越來(lái)越大,沒(méi)幾天就達(dá)到了64G,照這個(gè)消耗速度,256G內(nèi)存被耗光是遲早的事情。
為什么這套zk的node count會(huì)這么多,zk進(jìn)程的RSS這么大?
登錄zk,隨意翻找一個(gè)表的副本目錄,發(fā)現(xiàn)parts目錄居然有8000多個(gè)znode,
登錄到ck實(shí)例,執(zhí)行
use?system
select?substring(name,1,6),count(*)?from?zookeeper?where?path='/clickhouse/tables/01-01/db/table/replicas/ch1/parts'?group?by?substring(name,1,6)?order?by?substring(name,1,6);

該表自從7月后znode part數(shù)量就一路飆升,在9月末達(dá)到最高值。
嘗試執(zhí)行optimize table table final,對(duì)降低part沒(méi)什么用。
經(jīng)和開(kāi)發(fā)溝通后獲悉,在7月的時(shí)候部分表的insert從每10s執(zhí)行1次改成了1s執(zhí)行1次,對(duì)應(yīng)的就是part數(shù)量的飆升。
將這些表的insert統(tǒng)統(tǒng)改回了每10s執(zhí)行1次,截止目前(10月28號(hào)),10月份的part基本回落到了一個(gè)正常值。
至于如何清理已有的znode,目前有2種方法:
將部分離線表導(dǎo)出后drop,然后再導(dǎo)入,操作后znode從2400w下降到了1700w 大部分表的數(shù)據(jù)都有生命周期,N個(gè)月后將不再需要的歷史分區(qū)直接drop
至少目前可以確信znode不會(huì)再暴漲,zk進(jìn)程的內(nèi)存也不會(huì)繼續(xù)增加,可以保證clickhouse集群穩(wěn)定的運(yùn)行下去。
4、小結(jié)
這次案例前后耗費(fèi)了2天的時(shí)間才得以定位原因并解決,又耗費(fèi)了更長(zhǎng)的時(shí)間才找到問(wèn)題根源,距離發(fā)稿截止日期已經(jīng)過(guò)了整整1個(gè)月,期間沒(méi)有再?gòu)?fù)發(fā)過(guò)。
java進(jìn)程對(duì)Xms和Xmx設(shè)置很敏感,線上應(yīng)用要密切關(guān)注其內(nèi)存占用情況。
作者簡(jiǎn)介: 任坤,現(xiàn)居珠海,先后擔(dān)任專(zhuān)職 Oracle 和 MySQL DBA,現(xiàn)在主要負(fù)責(zé) MySQL、mongoDB、Redis 和 Clickhouse 維護(hù)工作。
