之前這種模式壹直運轉的比較好,沒有出現過問題,不過近期發現,對該表發起Alter語句時,出現了ZK Connection Loss的錯誤,但是對其他的表發起Alter語句沒有出現相同的錯誤。
本文主要分析壹下定位問題的過程以及確定問題所在,也希望大家就該問題進行討論提供更好的解決方案。
Clickhouse版本:20.9.3.45
表結構:
Alter語句以及響應的報錯信息:
首先查看了壹下clickhouse的錯誤日誌,錯誤日誌中有相關的堆棧信息
再查看了壹下zk的錯誤日誌
然後大致對比了壹下系統的表的大小,目前出問題的表是最大的。
從上面可以看出表的數據分片很多。
分析ZK的日誌發現,ZK認為客戶端發送的消息格式不正確,從而主動斷開了clickhouse的連接。從clickhouse的異常日誌有可以看出正在執行zk操作時出現了連接斷開的錯誤。
現在我們從代碼層面去看看問題的根因,當clickhouse執行alter操作時,如果對應的mutation如果涉及到分片數據的變更時,就需要對分片進行鎖定,而分片的鎖定操作是在對應的分片對應的zk子目錄下面創建壹個臨時節點,如下面代碼所示:
clickhouse在zk的訪問中,采用了大量批量操作,在上面的分片鎖定操作中,它針對所有影響到的分片的鎖定批量壹次性提交命令到zk中,而zk的傳輸使用了jute,jute缺省最大的包大小為1M,具體細節可以參考壹下關於zookeeper寫入數據超過1M大小的踩坑記。
這裏clickhouse的問題在於它沒有做分包,而是對所有影響的分片合並請求後,批量向zk發起請求,從而造成了超過zk最大的傳輸包大小,從而造成連接斷開。
為什麽這裏需要壹次性的批量提交呢?具體的原因有朋友了解的可以分享壹下,我理解可能clickhouse需要做類似事務級別的保證。
知道了問題的根因首先考慮到增加zk的jute缺省的最大包大小,zookeeper本身,我們可以在配置上實現。但是我們查看了壹下clickhouse的zk配置相關參數,能夠調整的主要是ip、port和會話時長,沒有看到jute大小的控制參數,所以這條路基本上行不通,經過只修改zk的參數重啟後,測試也發現不能成功。
控制Alter DELETE影響的數據範圍,從原來的Alter語句來看我們已經制定了時間的範圍,但是看起來Clickhouse不會主動根據條件來做分區裁剪。查看源碼也發現沒有這塊邏輯,但是從最新的clickhouse的文檔中,我們可以看到Delete語句支持分區操作。