2021-01-13 關(guān)于線上redis和k8s的幾個事故復(fù)盤

image.png

如圖,你覺得當(dāng)前系統(tǒng)可用內(nèi)存還有多少?實際上剩余內(nèi)存不是 1.5gb,而是 2.5Gb。

你需要知道這個命令展示的 buffer/cache 實際上指的是緩沖區(qū)數(shù)據(jù)大小,是被操作系統(tǒng)分配了但還未使用的內(nèi)存空間。

  • buffer 全稱 buffer cache,是塊設(shè)備的緩沖區(qū),即磁盤緩沖區(qū)。操作系統(tǒng)會先把磁盤塊讀取到 buffer cache 中,cache 空間不夠時會通過一定的策略清除部分 cache 數(shù)據(jù)。
  • cache 全稱 page cache,是文件系統(tǒng)的緩沖區(qū),即內(nèi)存緩沖區(qū)。幾個塊組成一個頁,只緩存文件的內(nèi)容,比 buffer cache 更優(yōu)先提供給應(yīng)用程序使用。
  • swap 線上一般關(guān)閉,使用了交換空間意味著應(yīng)用性能會較大幅度下降。

如果 cache 的值比較大,說明被緩存的文件數(shù)量比較多,這樣的話磁盤的讀取IO壓力就會相對小。

redis 一旦開啟持久化,尤其是 aof 持久化方式,這個 buffer/cache 就會增長的比較快。但實際上這個參數(shù)變大并不會影響系統(tǒng)使用,應(yīng)用需要的內(nèi)存還是可以分配。

但容器環(huán)境可就不一樣了哦。容器部署的情況下,無論是 docker stat 還是 cadvisor 統(tǒng)計方式,都會將 buffer/cache 計算到已使用的內(nèi)存中,所以配套的指標(biāo)閾值告警也會存在問題。這個問題在 docker17.06 版本得到解決,但還是建議實際測試下自己的 docker 和監(jiān)控方案。

redis 創(chuàng)建子進(jìn)程做 aofrewrite 時,如果內(nèi)存資源不足,會導(dǎo)致 fork 失敗,fd 不會被釋放,報錯提示不能申請內(nèi)存??梢酝ㄟ^ /proc/${pid}/fd 下看某 redis 線程具體的 fd 數(shù)量。

通過 redis-cli 查看 info memory 內(nèi)存使用大概了23Gb,機(jī)器本身有 32Gb 可用,buffer/cache 目前使用約 2Gb,意味著剩余可分配內(nèi)存約 8Gb。

關(guān)于 redis 啟動時日志提醒了三個配置項優(yōu)化點:

30914:M 03 Jan 16:30:34.425 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
30914:M 03 Jan 16:30:34.425 # Server started, Redis version 3.2.11
30914:M 03 Jan 16:30:34.425 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
30914:M 03 Jan 16:30:34.425 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
  1. tcp 連接問題

意思就是這個參數(shù)系統(tǒng)設(shè)置為 128,但你的 redis配置設(shè)置的 511 超過了系統(tǒng)值。解決方式是通過修改內(nèi)核配置文件 sysctl.conf,添加 net.core.somaxconn= 1024,即將這個系統(tǒng)參數(shù)設(shè)置大一點,這叫操作系統(tǒng)性能優(yōu)化。

  1. 內(nèi)存分配策略設(shè)置不當(dāng)

應(yīng)用程序向操作系統(tǒng)申請內(nèi)存時,內(nèi)存不足內(nèi)核會怎么處理?

  • overcommit_memory=0,系統(tǒng)默認(rèn)值,即系統(tǒng)剩余內(nèi)存不能滿足你這次的申請需要,就返回報錯信息;
  • overcommit_memory=1,redis.conf 建議值,即允許分配所有的物理內(nèi)存,就是先給你再說,最終還是不夠就直接 oom
  • overcommit_memory=2,允許分配一定量的物理內(nèi)存(overcommit_ratio)和交換空間的內(nèi)存值,一般不會使用,除非你的 redis 內(nèi)存硬件資源不足,又不能關(guān)機(jī)加內(nèi)存,臨時可以用這種方式。

所以啊,老老實實設(shè)置 vm.overcommit=1 吧。

  1. 系統(tǒng)默認(rèn)設(shè)置的 透明大頁 可能會存在性能問題

還是頁式存儲的問題,每個內(nèi)存頁默認(rèn)為 4kb8kb 大小。如果要在內(nèi)存中運行比較大的應(yīng)用程序,那么操作系統(tǒng)以 4kb 為單位進(jìn)行物理地址映射時就會產(chǎn)生比較多的缺頁中斷和 TLBMiss,從而大大影響性能。
為了能夠動態(tài)的修改虛擬內(nèi)存單位的大小,linux 引入了 hugetlbfs 文件系統(tǒng),最大支持設(shè)置每頁 2Mb 內(nèi)存空間。
對于目前大多數(shù)做了 4k 優(yōu)化的應(yīng)用程序而言,一旦動態(tài)修改了這個參數(shù),分配系統(tǒng)內(nèi)存時就會涉及各種內(nèi)存鎖,應(yīng)用程序性能隨機(jī)就會下降,所以我們要禁用這個參數(shù)。

/etc/rc.local 文件添加兩行即可:

echo never > /sys/kernel/mm/redhat_transparent_hugepage/defrag
echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled

線上環(huán)境 k8s 集群安裝成功后,服務(wù)拉鏡像部署的過程中機(jī)房斷電了。你們猜猜會影響了什么?

  1. xfs 文件系統(tǒng)損壞
  2. etcd 心跳檢測斷連

etcd 斷連的話,從集群摘除再重新加入集群就好了? 但是 systemctl restart etcd 依然不生效,必須先 systemctl stop etcdsystemctl start etcd 才行。之前 dockernginx 也出現(xiàn)過這種問題,執(zhí)行 systemctl reload nginxsystemctl restart docker 也都有過無效的情況,必須先停止再啟動,更底層的原因就沒有去深究了。

重點的 xfs 文件系統(tǒng)損壞的問題。容器啟動失敗,查看日志可以很明顯看到文件系統(tǒng)相關(guān)的報錯。先使用 xfs_repair -n 檢查確定某臺節(jié)點的文件系統(tǒng)損壞。再檢查了一下故障實例所在的節(jié)點,確實都在這臺機(jī)器上,且這臺機(jī)器上的部分實例是能正常運行的。

xfs_repair 命令就可以修復(fù)損壞的 xfs 文件系統(tǒng)(垃圾浪潮磁盤真的經(jīng)常出問題),但是執(zhí)行這個命令之前你要umount 相關(guān)的磁盤。如果這個磁盤掛載的目錄正在使用中怎么辦呢?你 umount -f 都沒用,永遠(yuǎn)都是 device is busy,這可怎么辦?

通過 fuser 這個工具可以找出某個目錄被哪些進(jìn)程占用著,也可以殺這些進(jìn)程(線上環(huán)境小心操作,建議先把服務(wù)調(diào)度到其他節(jié)點),知道了進(jìn)程就可以通過 lsof、netstat 查看端口,猜測哪些服務(wù)使用,能否先 kill 掉。但 yum install fuser 發(fā)現(xiàn)沒這個包?百度一下 yum install -y psmisc 就行了,這種問題在 centos 里是很常見的坑了。rhel8 改成 dnf 命令后就會提示你這個命令在哪個包里能使用,但估計還要一兩年才能普及 centos8 吧。

結(jié)果 fuser -cu 看占用,fuser -ck 殺相關(guān)進(jìn)程。沒錯能殺掉,但得多次執(zhí)行后這目錄又會被占用,因為有文件源源不斷地在寫入啊,即使你 fuser -ck /xxoo && umount 還是不行哦。

我和運維當(dāng)時都懵逼了,我們頻繁執(zhí)行幾次,特么居然成功了,別問我為什么,我也不知道為什么。和 systemctl 有時候 restart 失敗一樣:未知力量。然后修復(fù) xfs,重點是修復(fù)后,之前被 k8s 調(diào)度到這臺節(jié)點的容器有好幾個都無法啟動,pod 狀態(tài)為:ImageInspectError。

這個狀態(tài)是鏡像校驗過程發(fā)生錯誤,第一,我們部署包關(guān)于鏡像校驗?zāi)_本都沒改動啊,第二,k8s集群本身是不是有對鏡像的檢驗,第三,上傳到docker-registy的鏡像是否完整(第二次意識到harbor的重要性,第一次是跨集群鏡像同步需求),第四,本地拉到的鏡像是不是出問題了。

然后簡單問了一下運維這次的部署包有變更嗎,最近沒有改動。k8s本身我記得是沒有對docker image做什么判斷改動的,就算有也應(yīng)該最后去看(主要是其他服務(wù)正常,散列類型的出錯不太可能是集群本身環(huán)境問題)然后docker-registry都倉庫了我也沒去驗證啊,那我只能認(rèn)為是下拉鏡像過程sha1變了,或者拉下來后斷電導(dǎo)致磁盤壞道,導(dǎo)致某些服務(wù)的overlayfs壞了,通過systemctl status docker和journalctl -f日志確實看到overlayfs報錯(etcd斷連同樣這樣看到的,這是基操),返回狀態(tài)碼-2,谷歌一下都說文件系統(tǒng)損壞,可我特么剛修復(fù)xfs文件系統(tǒng)啊。然后我認(rèn)為是原因是后者,文件系統(tǒng)是當(dāng)時出問題了,拉下來的鏡像在repair后不完整了,這時候你想到了如何解決嗎?

我先手動改yaml nodeName強(qiáng)制服務(wù)調(diào)度到非斷電機(jī)器,結(jié)果服務(wù)正常了。(你要是K8s上萬臺就GG了)我查看某個ImageInspectErr服務(wù),-owide查看鏡像名和調(diào)度節(jié)點發(fā)現(xiàn)出問題的都在斷電機(jī)器上。然后ssh去那個機(jī)器(你要是沒權(quán)限就GG了),嘗試性的在這個k8s節(jié)點docker命令刪除本地鏡像,結(jié)果特么打死都刪除不了(因為有容器跑著?。姨孛催t疑了3s才想起來k8s deployment確保一直有一個容器服務(wù)啟動,然后還要edit deploy replicas=0。然后刪啊刪,然后又改回來replicas=1,ok一切都成功啦!?。?/p>

結(jié)果特么還有個末尾,有個服務(wù)正常Running,0/1,logs查看一直都是sleep。這尼瑪?shù)疤垡槐龋M(jìn)去服務(wù)里看日志,尼瑪Nodejs服務(wù),提示丟失ippxxoo mudule,what??我特么寫Nodejs的也沒發(fā)現(xiàn)我們用了這個模塊啊,問了運維他說上午這個服務(wù)運行是正常的。事后解決才想起,可能底層overlayfs丟失的磁盤數(shù)據(jù)里包含了這個modules吧。同樣的道理操作解決(這個問題在上一條之前發(fā)現(xiàn),困擾了十分鐘)。本來只是因為開發(fā)網(wǎng)玩壞了codis導(dǎo)致找運維上物理機(jī),結(jié)果全程2小時操蛋。另外目前docker更推薦的存儲是overlay2,但建議內(nèi)核 >4.0(我們是3.10跑著容器服務(wù),才過很多坑了,如果你的大規(guī)模使用k8s,其實有坑也不用踩,最終一致性的集群,OOM之前也會給你重啟,很多時候卻是臨時解決了可用性問題)

其實這個開發(fā)網(wǎng)codis問題后面還引發(fā)了半小時zk注冊節(jié)點和codis-dashboard問題,就不說了,心累

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容