經過線報,說前方應用有異常,導致了可用性變差。咦!討厭的異常,拋異常是程序猿最討厭的事情之一。
經過收集異常信息如下
一看異常很神秘,
從異常的表面意思看就是去zookeeper查詢某個node是否存在然后爆出了 KeeperErrorCode = ConnectionLoss這個錯誤
經過各種查詢說需要調優zookeeper,具體情況大家可以自行進行搜索。
我們的實現馬上轉移到zookeeper上面,觀察zk的運行環境。
我們經過了如下各種過程處理(以下是未成功的處理):
加內存:2G-->4G(雖然我們知道加內存沒有用,自己心里安慰一下萬一能解決那,哈哈)
加CPU:4C-->6C
換磁盤空間並打開虛擬機讀寫限制
移動虛擬機主機位置
調整前后統計對比圖:
網絡 I/O:sar -n DEV 1
CPU I/O: vmstat 1
磁盤 I/O : sar -d 1
這里我說下經過各種環境的取值分析得出如下現象和結論:
現象:
CPU有點高但是在可接受范圍內
內存完全夠用不存在內存溢出可能
磁盤讀寫完全沒有達到所能承受的上限
網絡同樣沒有達到可用的上限
問題指標
發現cpu執行的IO等待高,why?
經過各種數據的分析有了如下大膽的猜測,
zookeeper是強一致性的分布式系統,
CAP理論中它屬於CP系列,
所以對於讀寫有強一致的要求,
大量並發情況下對一個文件的讀寫(zookeeper日志文件 log.xxxxx的那個文件)會有排隊想象同時他還會對從機進行分發數據,
搞得主機(master)很忙造成cpu的操作都在等待那一個文件上面,
但實際上讀寫的內容並不多,
也就沒有達到磁盤的上限。
然后就造成了主動斷開連接上面的異常 ConnectionLoss。
也就是說這個異常個人猜測是zookeeper的主動行為,否則的話會報超時異常。
所以針對各種分析與搜索以及實踐有如下兩種方法解決:
- 設置zookeeper本身的參數forceSync=no
- 將日志文件寫入目錄指向內存句柄
本次采用第二種方法:修改zoo.cfg配置文件:
dataLogDir=/zookeeper/logs 修改為
dataLogDir=/dev/shm
從目前情況看問題基本解決,也請大家調整相關系統框架與zookeeper的心跳頻率,以減少zk的壓力。