【問題追查】mc叢集寫入恍惚問題排查
1.現象
業務方反饋在向memcache叢集寫入資料時,出現不穩定。表現為向mc寫入一個creative和ad物件的list,有的時候能寫進去並讀出來,有的時候寫成功但是讀不出來。
2.問題排查
2.1 復現問題
a.有的key沒有問題,能夠一直寫+讀。
b.有的key一直都是寫ok,讀None。
c.有的key寫ok,有的時候讀ok有的時候讀None.
2.2 proxy的問題?
使用同一個proxy的再次復現問題,出現了之前的多種情況。所以排除proxy問題。
另外在排查中發現出現問題的key長度小於20B、value長度在9K~10K左右。
2.3.mc叢集問題?
2.3.1 叢集各節點狀態
叢集各個節點狀態,以10.2.10.10:11211為例:
透過看叢集各個節點的狀態,發現節點的slab存在不同程度的Full.
情節較為嚴重的是10.2.10.8:11211,10.2.10.9:11211,10.2.10.10:11211這三個節點,並且Evicted很多。
2.3.2 再次復現問題
用client直接連線不同的節點,在有的節點上讀寫都ok,有的節點上出現了之前的問題。確定是叢集節點出現問題。
基本確定問題和mc叢集節點上5.5K~16.9K之間的slab的Full狀態以及Evicted有關。
2.3.3 叢集記憶體使用情況
記憶體使用情況
最大記憶體5GB,每個例項用了1.5GB左右。 記憶體沒滿啊,為什麼存不進去?
再次返回來看各個節點的狀態,以10.2.10.10:11211為例:
把分配的Page都加起來:158+2+1+1+1+1+1+1+2+7+4+9+5+754+58+558+576+2869+90+7+6+2+1+1+1+1+1+1+1+1=5121 ~ 5GB
5GB是分配給每個節點的maxmemory.
說明所有的memory page都被分配給相應的slab了,目前即使有一部分page回收後空閒,但是這部分空閒的page沒有被重新分配到全域性空閒空間,供其他slab使用。
看一下chunk size為1.8K的一行,分配page為754,item數量1209,也就是說這個slab裡面,實際只有1MB左右的資料,卻分配了754M的空間,嚴重浪費。
為什麼mc就不能把已經分配的空閒空間回收呢?
問題定位:mc沒有把已經分配的空閒空間回收。
3.問題解決
3.1 再造叢集復現問題
1.自己搭了一個64M的mc節點。
2.用4k的value資料寫滿:
3.刪除所有資料:
4.再用1k的value寫滿:
發現這次value大小為1k的很多都Evited了。並且上次value大小為4k的資料雖然已經刪除了,但是page大多數還處於被分配狀態。
在stats裡面看到,slabs也出現了reassign(就是在啟動引數裡面指定了slabsreassign和slabsautomove),但是和我們要的差距有點大。
在1.4.11的ReleaseNote裡面看到:
可以透過命令手動重新分配slot,試一下
寫滿1k資料:
有4個page遷移了
再寫一遍1k資料:
寫一遍2k的資料:
能看到reassign的速度變快了。但還是和我們要的差距有點大。我們不能經常手動執行slabs reassign.
我們用的mc是1.4.13,新版本的mc是不是解決了這個問題?
於是下載最新的1.4.33,重複上面的測試。
3.3 新版本測試
下載最新版本1.4.33,重試上面的測試:
用4k的value資料寫滿:
刪除所有資料:
用1k的value寫滿:
貌似沒什麼變化啊,趕緊下載最新的程式碼看看在申請空間的時候怎麼做的。
這4個函式基本就是lru_maintainer執行緒回收空間的核心程式碼了,限於篇幅不再羅列程式碼。
概括一下就是:
maintainer執行緒處於一個while迴圈中,不斷對所有的slabscls進行迴圈,看看哪些slabscls裡面空閒空間的>2.5個page,就標記一下到slab_reb裡面,等待回收。
並且不斷對lru表維護,如果hot,warm lru佔有記憶體超過限定額度,將hot lru的item移至warm lru, warm lru的item移至cold lru,以及對cold lru裡面物件的回收等等.
slabclass_t對應三條lru佇列,即hot,warm,cold lru,最終記憶體不足的時候會有優先刪除cold lru的資料。
另外,最新的mc裡面也支援一個crawler執行緒和maintainer執行緒配合。crawler執行緒用來檢查當前memcache裡面的所有item是否過期等。
3.4 新版本再測試
1.啟動引數:
增加lru_maintainer引數
2.寫4k資料:
3.全部刪除:
4.寫入8k資料:
5.刪除8k資料:
6.寫滿6k資料:
7.寫入4k無過期資料,8k有過期的資料600s
8.寫入5k的不過期資料:
9.寫入5k無過期資料,8k有過期的資料600s
10.寫入4k帶過期資料:
刪除了8k的過期資料。
加入lru_maintainer執行緒之後效果大好,另外,如果增加crawler執行緒的話會佔用鎖,可能會影響mc的效能(需要效能測試)
4.結論
透過上面的實驗看出,1.4.33的mc在page分配完成後的回收上效果很好。
如果叢集已經出現了page分配完的情況,如果使用新版的mc,一方面會快取之前1.4.13版本寫不進去的資料,提高在slab鈣化情況下的空間利用率,提高mc命中率。另一方面因為將資料分別放在hot,warm,cold lru裡面,能快速的找到替換的空間,大大降低查詢已經過期的空間回收時間,進一步提高效能。
5.升級新版本
目前廣告的所有mc都已經升級到1.4.33版本。
6.Ref
原文地址:https://techblog.toutiao.com/2018/05/29/untitled-22/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3137/viewspace-2802046/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 安全叢集訪問非安全叢集問題記錄
- java問題排查Java
- 框架問題排查框架
- mysql叢集02:幾個問題MySql
- redis 叢集常見問題 QARedis
- ngnix叢集產生的問題
- 手把手教你使用容器服務 TKE 叢集審計排查問題
- Java服務.問題排查.問題復現Java
- 線上問題排查神器入門——Arthas
- 排查 k8s 叢集 master 節點無法正常工作的問題K8SAST
- zookeeper叢集奇偶數節點問題
- 診斷叢集的潛在問題
- repmgr 叢集雙主問題處理
- kubernetesgraceperiod失效問題排查
- SDK與問題排查
- Linux排查JVM問題LinuxJVM
- 解決叢集 Yellow 與 Red 的問題
- 異常問題排查之旅
- Redis阻塞問題排查方向Redis
- Spark學習——問題排查Spark
- 利用greys排查java問題Java
- 資料問題排查思路
- Kubernetes 問題排查全景圖
- redis connect timeout問題排查Redis
- JVM問題排查步驟JVM
- 線上FullGC問題排查實踐——手把手教你排查線上問題GC
- java 入門篇 問題集錦Java
- k8s——叢集環境問題合集K8S
- Spark 問題集Spark
- 問題排查之RocketMQAutoConfiguration not loaded.MQ
- SpringBoot Seata 死鎖問題排查Spring Boot
- VictoriaMetrics常見效能問題排查
- TNS問題排查 The listener supports no services
- 日常問題排查-呼叫超時
- 伺服器問題 排查思路伺服器
- 運維排查問題常用sql運維SQL
- [開發問題]React-native問題集React
- ZooKeeper 05 - ZooKeeper 叢集的腦裂問題(Split Brain)AI