上篇文章:
Redis原理之集群https://blog.csdn.net/sniper_fandc/article/details/149141342?fromshare=blogdetail&sharetype=blogdetail&sharerId=149141342&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link
目錄
1 Redis作為MySQL緩存
2 緩存更新策略
2.1 定期生成
2.2 實時生成
3 緩存預熱(Cache preheating)
4 緩存穿透(Cache penetration)
5 緩存雪崩(Cache avalanche)
6 緩存擊穿(Cache breakdown)
????????由于Redis基于內存,比基于磁盤的數據庫查詢效率(讀請求)快的多,因此Redis常用于作為MySQL數據庫的緩存。而內存成本高,因此通常只往內存存儲少量的熱點數據。
1 Redis作為MySQL緩存
????????關系型數據庫比如MySQL查詢效率一般比較慢,有如下原因:
????????1.基于磁盤,磁盤IO速度慢。
????????2.如果查詢不能命中索引,就需要遍歷表,增加磁盤IO次數。
????????3.關系型數據庫會對執行的SQL進行一些解析、校驗、優化等工作,進一步增加耗時。
????????4.如果是復雜查詢,比如涉及到多表聯查,笛卡爾積的時間復雜度O(M*N),效率就更低了。
????????因此在高并發的環境下,只使用MySQL很容易宕機。為了優化系統性能,提高系統并發量,有兩種方式:1.增加MySQL集群,但是成本很高。2.使用Redis作為緩存。方式2就是業界常用的方式:
????????注意:這種方式只是加快了讀請求的查詢效率,而寫請求緩存并不能加快效率,還是需要寫到MySQL中。
2 緩存更新策略
2.1 定期生成
????????定期對訪問的數據進行頻次統計(通常基于日志分析),選取頻次最高的那部分數據作為熱點數據存入緩存中。
????????優點:實現簡單,過程可控,方便排查問題。
????????缺點:數據實時性不夠。
2.2 實時生成
????????實時生成就是當Redis查詢未命中時,服務器就會去MySQL數據庫查詢,并將查詢的數據寫入到Redis緩存中。
????????優點:數據具有實時性。
????????缺點:緩存容易很快就寫滿。
????????正因為這樣的缺點,就需要合適的內存淘汰策略來更新:
????????FIFO:先進先出,緩存時間最久的數據先淘汰。
????????LRU:淘汰最久未使用,每個數據設置最近訪問時間,優先淘汰最近訪問時間最久的數據。
????????LFU:淘汰最少使用的,每個數據設置最近一段時間訪問次數,優先淘汰訪問次數最少的數據。
????????Random:隨機淘汰。
????????而Redis內部也用到了這些策略思想,并按照key是否設置過期時間對這些策略進行了細化:
????????volatile-lru:針對設置了過期時間的key(只要設置了過期時間,即使還沒過期,如果內存滿了又有新數據寫入就會淘汰),按照LRU思想淘汰。
????????allkeys-lru:針對所有的key,按照LRU思想淘汰。
????????volatile-lfu:針對設置了過期時間的key,按照LFU思想淘汰。
????????allkeys-lfu:針對所有的key,按照LFU思想淘汰。
????????volatile-random:針對設置了過期時間的key,隨機淘汰。
????????allkeys-random:針對所有的key,隨機淘汰。
????????volatile-ttl:按照ttl(生存時間,也就是設置了過期時間的key),越早過期越優先淘汰(局限于設置了過期時間key的FIFO)。
????????noeviction:默認策略,內存滿了再寫入就報錯。
3 緩存預熱(Cache preheating)
????????當Redis剛啟動或大批key同時過期,此時Redis中沒有數據,查詢就無法命中緩存,從而去查MySQL,給數據庫帶來大量查詢壓力。
????????解決辦法:通過緩存預熱,即提前給緩存中存入一些數據(不一定完全是熱點數據),來幫助MySQL減輕大量請求的壓力。可以采用定期生成的策略來離線為Redis提前存入一些熱點數據,隨著時間推移,緩存中的數據最終變為真正的熱點數據。
4 緩存穿透(Cache penetration)
????????查詢的key在Redis和MySQL數據庫中都不存在,這樣的key不會被實時緩存到Redis中,后續如果這類key頻繁訪問,依然會對MySQL造成較大壓力。
????????問題產生原因:1.業務未進行合理的參數校驗,導致非法的key被查詢。2.數據庫部分數據被誤刪。3.黑客攻擊。
????????解決辦法:1.業務設計更規范,進行必要的參數校驗。2.針對不存在的key,可以在MySQL也未命中后,把該key存入Redis中,value設為非法值(比如””),避免頻繁訪問數據庫。3.使用布隆過濾器(hash+bitmap,能夠用較少的空間和時間判斷某個數據是否存在)存入所有的key,查詢Redis和數據庫前先查布隆過濾器是否存在該key。
5 緩存雪崩(Cache avalanche)
????????短時間內Redis上的大量的key失效,從而導致大量的查詢未命中緩存,給數據庫帶來較大壓力。
????????問題產生原因:1.Redis節點宕機。2.在短時間內設置了大量過期時間相同的key。
????????解決辦法:1.部署Redis集群保證高可用性,并進行安全監控。2.不設置過期時間或設置過期時間時附加隨機種子,保證不會同時過期。
6 緩存擊穿(Cache breakdown)
????????緩存穿透的特殊情況,緩存穿透是針對普遍的key(包括熱點和非熱點)突然同時失效的問題,而緩存擊穿是指熱點key突然過期,導致大量查詢未命中去查數據庫。
????????解決辦法:1.統計出熱點key,并設置永不過期。2.必要時進行服務降級(關掉不必要的服務),比如使用分布式鎖限制數據庫的訪問請求。
下篇文章:
Redis原理之分布式鎖https://blog.csdn.net/sniper_fandc/article/details/149142059?fromshare=blogdetail&sharetype=blogdetail&sharerId=149142059&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link