本文由做者餘寶虹受權網易雲社區發佈。redis
Redis是一個支持豐富數據結構的分佈式key-value系統,Redis在雲捕系統的地位至關重要,碰到的問題也比較多,最近才解決了一個遺留的老大難問題。因爲15年的時候才接觸到Redis,使用過程當中姿式存在比較大的問題。在這裏列舉下面幾個問題:數據庫
大Set問題
雲捕中天天,每小時崩潰數,啓動數的統計是經過Storm實時統計,將計算結果存到Redis中實現去重,而後按期將Redis中的數據彙總持久化到數據庫中。緩存
最初的實現方式是每一個產品的崩潰,啓動數都使用一個set來實現統計,set中存儲的是設備ID。隨着數據量的增長,這個set會變得很是大,會達到單機內存的極限,沒法分散到多個節點,不利於擴容,最初雲捕使用的物理機內存是32GB,常常會收到內存使用率的報警。分析大對象可使用 --bigkeys 命令,NCR不支持。網絡
當內存使用量到達maxmemory以後就會執行響應的緩存替換策略,默認是allkey-lru,因此當用於統計數據的set被刪除後,就會出現崩潰數從0開始 統計的狀況,出現統計數據丟失的問題。數據結構
改造前效果:分佈式
爲了使用NCR的擴容能力,就須要消除掉對大Set的依賴,改造後,採用的方法是:對每一個設備ID生成一個key,計數增長以前會判斷對應的設備ID key是否存在。採用這種方式後就會出現大量的key,因此在key的命名上也應該儘可能簡短。性能
protected void add(Jedis jedis, String key, String deviceId, long expireTime) {spa
expireTime /= 1000; String value =""; String member=key+":"+deviceId; if (jedis.setnx(member, value) == 1) { jedis.incr(key); } jedis.expireAt(member, expireTime); jedis.expireAt(key, expireTime);
}
改造後效果:code
CPU抖動
雲捕存儲在Redis中的統計數據具備時效性,天天的凌晨會將前一天的數據持久化到數據庫,因此前一天的key均可以刪掉。問題是若是大量的key都突發在同一時間失效的話,就會致使CPU使用率劇增,並且大Set刪除時耗時更長,因此改進後key的失效時間採用隨機化,分批的方式。orm
具體能夠見DBA同窗的文章 redis cpu 抖動問題分析 ,redis-faina redis性能問題診斷利器
應用自檢
產品的崩潰數天天都是波動的,不利於發現系統的問題,因此雲捕開啓了一個定時發送崩潰數據的任務,每小時發送1000條,而後經過觀察這個App的數據統計就能夠感知到整個系統是否穩定。
重複寫
將Redis中的數據持久化到數據庫的過程當中可能會出現網絡波動,寫入失敗的狀況,爲了保證寫成功,雲捕中採用每小時重複寫4次的策略,一方面重複寫數據庫比讀取Redis重試的邏輯要簡單,另外一方面當出現網絡問題的時候重試有可能反而會加重這種狀況。
更多網易技術、產品、運營經驗分享請訪問網易雲社區。
文章來源: 網易雲社區