3.redis記憶體佔用飆升

來源:互聯網
上載者:User
 一、現象:     redis-cluster某個分區記憶體飆升,明顯比其他分區高很多,而且持續增長。並且主從的記憶體使用量量並不一致。   二、分析可能原因:  1.  redis-cluster的bug (這個應該不存在)  2. 用戶端的hash(key)有問題,造成分配不均。(redis使用的是crc16, 不會出現這麼不均的情況)  3. 存在個別大的key-value: 例如一個包含了幾百萬資料set資料結構(這個有可能)  4. 主從複製出現了問題。  5. 其他原因   三、調查原因:  1. 經查詢,上述1-4都不存在  2. 觀察info資訊,有一點引起了懷疑: client_longes_output_list有些異常。 3. 於是理解想到服務端和用戶端互動時,分別為每個用戶端設定了輸入緩衝區和輸出緩衝區,這部分如果很大的話也會佔用Redis伺服器的記憶體。   從上面的client_longest_output_list看,應該是輸出緩衝區佔用記憶體較大,也就是有大量的資料從Redis伺服器向某些用戶端輸出。 於是使用client list命令(類似於mysql processlist) redis-cli -h host -p port client list | grep -v "omem=0",來查詢輸出緩衝區不為0的用戶端串連,於是查詢到禍首monitor,於是豁然開朗.   monitor的模型是這樣的,它會將所有在Redis伺服器執行的命令進行輸出,通常來講Redis伺服器的QPS是很高的,也就是如果執行了monitor命令,Redis伺服器在Monitor這個用戶端的輸出緩衝區又會有大量“存貨”,也就佔用了大量Redis記憶體。     四、緊急處理和解決方案 進行主從切換(主從記憶體使用量量不一致),也就是redis-cluster的fail-over操作,繼續觀察新的Master是否有異常,通過觀察未出現異常。 尋找到真正的原因後,也就是monitor,關閉掉monitor命令的進程後,記憶體很快就降下來了。   五、 預防辦法: 1. 為什麼會有monitor這個命令發生,我想原因有兩個: (1). 工程師想看看究竟有哪些命令在執行,就用了monitor (2). 工程師對於redis學習的目的,因為進行了redis的託管,工程師只要會用redis就可以了,但是作為技術人員都有學習的好奇心和慾望。 2. 預防方法: (1) 對工程師培訓,講一講redis使用過程中的坑和禁忌 (2) 對redis雲進行介紹,甚至可以讓有興趣的同學參與進來 (3) 針對client做限制,但是官方也不建議這麼做,官方的預設配置中對於輸出緩衝區沒有限制。 Java代碼   client-output-buffer-limit normal 0 0 0   (4) 密碼:redis的密碼功能較弱,同時多了一次IO (5) 修改用戶端原始碼,禁止掉一些危險的命令(shutdown, flushall, monitor, keys *),當然還是可以通過redis-cli來完成 (6) 添加command-rename配置,將一些危險的命令(flushall, monitor, keys * , flushdb)做rename,如果有需要的話,找到redis的營運人員處理 Java代碼   rename-command FLUSHALL "隨機數"   rename-command FLUSHDB "隨機數"   rename-command KEYS "隨機數"     六、類比實驗: 1.  開啟一個空的Redis(最簡,直接redis-server) Java代碼   redis-server       初始化記憶體使用量量如下: Java代碼   # Memory   used_memory:815072   used_memory_human:795.97K   used_memory_rss:7946240   used_memory_peak:815912   used_memory_peak_human:796.79K   used_memory_lua:36864   mem_fragmentation_ratio:9.75   mem_allocator:jemalloc-3.6.0       client緩衝區: Java代碼   # Clients   connected_clients:1   client_longest_output_list:0   client_biggest_input_buf:0   blocked_clients:0     2. 開啟一個monitor: Java代碼   redis-cli -h 127.0.0.1 -p 6379 monitor   3. 使用redis-benchmark: Java代碼   redis-benchmark -h 127.0.0.1 -p 6379 -c 500 -n 200000   4. 觀察 (1) info memory:記憶體一直增加,直到benchmark結束,monitor輸出完畢,但是used_memory_peak_human(曆史峰值)依然很高--觀察附件中日誌 (2)info clients: client_longest_output_list: 一直在增加,直到benchmark結束,monitor輸出完畢,才變為0 --觀察附件中日誌 (3)redis-cli -h host -p port client list | grep "monitor" omem一直很高,直到benchmark結束,monitor輸出完畢,才變為0 --觀察附件中日誌 監控指令碼: Java代碼   while [ 1 == 1 ]   do   now=$(date "+%Y-%m-%d_%H:%M:%S")   echo "=========================${now}==============================="   echo " #Client-Monitor"   redis-cli -h 127.0.0.1 -p 6379 client list | grep monitor   redis-cli -h 127.0.0.1 -p 6379 info clients   redis-cli -h 127.0.0.1 -p 6379 info memory   #休息100毫秒   usleep 100000   done    完整的記錄檔:  http://dl.iteye.com/topics/download/096f5da0-4318-332e-914f-6f7c7298ddc9  部分日誌: Java代碼   =========================2015-11-06_10:07:16===============================    #Client-Monitor   id=7 addr=127.0.0.1:56358 fd=6 name= age=91 idle=0 flags=O db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=4869 omem=133081288 events=rw cmd=monitor   # Clients   connected_clients:502   client_longest_output_list:4869   client_biggest_input_buf:0   blocked_clients:0  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.