雪花臺灣

海量數據下如何正確訪問Redis服務纔不會掛掉?


要保證Redis不會掛掉,也就是提高Redis的高可用性,可以從這麼幾個方面考慮。

集羣式部署方式

Redis分片

Redis在3.0之前只支持單實例,在此之前,在數據量比較大的情況,通常有幾種方案可以做到把數據分片保存到多臺伺服器上。

熱點數據挑戰單節點的極限

雖然我們已經把數據分散保存到多臺Redis實例上了,但是如果有一個熱點數據被頻繁訪問,超過了單實例的伺服器極限,那麼該如何解決呢?通常的手段就是做讀寫分離,部署多臺只讀節點,對外提供服務。

我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。


海量數據下正確的訪問redis要注意的事情有很多,基本上可以從服務治理,數據,redis正確使用三個方面來講。

既然是海量數據,那麼服務肯定要拆分成多個服務,最常見的採用「大中臺,小前臺」的概念,中臺分各個服務中心,各個中心去維護自己中心負責的服務,向上遊前臺提供數據和服務。比如一個做內容付費的公司可以有內容中心、商品中心、交易中心

用戶中心、促銷中心、基礎中心、開放平臺等,中心之間採用RPC通信或者數據共享。

在服務治理的基礎上,各個中心負責維護自己的數據,那麼數據的存儲有MySQL、MongoDB(存儲非結構化數據)、Redis,這些數據存儲介質都做成獨立實例,互不影響。那麼海量數據分散到各個中心了,壓力也會相對少一些,做到每個中心都有自己獨立的一個或多個資料庫實例、Redis實例。每個中心再根據自己中心的數據做好分庫分表、緩存同步等工作。下圖是一張資料庫和redis緩存同步的方案,通過實時刷新+定時任務同步補償機制,將大部分熱點業務數據實時同步至redis。

在做好服務治理和數據劃分的基礎上,這個時候就是重點講如何正確使用redis的時候了,個人列舉了部分細則僅供大家參考:

  1. 熟練使用五種數據結構(String、Set|、Hash、List、ZSet)以及每種數據結構的適用場景和注意事項;

  2. 防止緩存雪崩,即避免大批量緩存同一時間段集中過期,導致大量請求都懟到資料庫上,導致資料庫連接數爆滿、宕機;

  3. 防止緩存穿透,避免redis中熱點key存入了null或者不存在,導致大量請求繞過redis請求資料庫去了;

  4. 避免大key的存在:比如一個redis集羣是16G,共8個節點,每個節點平均分配2G的內存,這時候如果有一個大的hash key佔用內存超過2G了,這個時候儘管集羣還有剩餘的空間,這個大key的寫入依舊會失敗,單個key是無法做到集羣的,另外再想想如果一個hash存儲了大量的數據,考慮一下性能問題?

  5. 禁止使用keys、flushall、flushdb等,運維同學通過redis的rename機制禁掉命令,或者使用scan的方式漸進式處理;

  6. 批量讀寫redis請採用pipeline管道的方式;

  7. 在代碼中採用線程連接池的方式定義每一個redis bean

  8. 這裡和大家一起溫習一下redis過期策略和內存淘汰機制:redis採用的是惰性刪除和定期刪除的過期策略,內存淘汰機制有:

volatile-lru :在設置了過期時間的鍵空間中,移除最近最少使用的key。

allkeys-lru : 移除最近最少使用的key (推薦)

volatile-random : 在設置了過期時間的鍵空間中,隨機移除一個鍵,不推薦

allkeys-random : 直接在鍵空間中隨機移除一個鍵,沒人用

volatile-ttl : 在設置了過期時間的鍵空間中,有更早過期時間的key優先移除 不推薦

noeviction : 不做過鍵處理,只返回一個寫操作錯誤。 不推薦

如果是你,你會使用哪種過期策略?

所以,個人認為redis用好並不難,難的是把服務治理好,redis跟著服務走就可以了。

以上,是個人對redis使用的一些認識和看法,大家還有什麼好的使用建議和想法,歡迎下方留言討論,共同成長~


掛掉?一般都是配置不足,如果你伺服器和redis在同同一機器,機器內存和伺服器內存 幾乎佔了機器的全部內存,這時候你訪問取一個比較大的數據肯定會掛的。加錢吧??


推薦閱讀:
相關文章