oracle缓存和Redis,说说数据缓存那点事:Redis和memcached对比
【此為"一森咖記"公眾號——第86篇文章】
本文預計閱讀15分鐘
【引言】
當我們為一個并發量較大的應用做數據架構時,會考慮使用緩存,意欲達到三個目標:
1. 加快用戶訪問速度,提高業務用戶體驗;
2. 降低后端服務負載,保證系統平滑平穩;
3. 保證數據盡可能及時更新,最大程度保證數據一致性。
之前的兩篇文章分別介紹了數據緩存層常用的兩個產品redis和memcached,點擊如下兩篇文章:
今天對比分析下Redis和memcached。
【大綱】
1. Redis和memcached的區別
2. redis相比memcache的優勢
3. redis常見性能問題和解決方案
4. 緩存使用時的常見現象
一、 Redis和memcached的區別
1. 數據類型
memcached所有的值均是簡單的字符串,redis支持豐富數據類型,支持string,list,set,sorted set,hash;
2.?線程機制
Redis為單線程,Memcached為多線程工作,每一個核上Redis在存儲小數據時比Memcached性能更高。而在100k以上的數據時,Memcached性能要高于Redis;
3. 存儲方式
redis和Memcached均是內存數據庫,但redis可以數據持久化,Memcached不支持持久化。Redis并非所有的數據一直在內存,當物理內存用完時,Redis使用LRU算法將value交換到磁盤,memcached超過內存比例會抹掉前面的數據。故,memcached斷電,重啟系統后,數據不可恢復;redis數據丟失后可以通過RDB和AOF恢復。
4. 分布式存儲
Memcached和Redis是基于服務器物理內存級的數據緩存,如需要處理的數據量超過單臺機器的物理內存,就需構建分布式集群來擴展存儲能力。
Memcached本身并不支持分布式,只能在客戶端通過像一致性哈希這樣的分布式算法
來實現Memcached的分布式存儲,為客戶端式分布式緩存;Redis更偏向于服務器端構建分布式緩存,沒有采用一致性哈希做分布式。在Redis Cluster中,每個Master節點都有對應的兩個冗余Slave節點。當Master節點退出后,集群會自動選擇一個Slave節點成為新的Master節點。熟悉MySQL高可用架構MHA部署的親,可以更容易理解。
5.?底層模型不同
Redis自己構建VM機制 ,而系統調用系統函數會浪費一定的時間去移動和請求。
6. value大小
redis最大可以達到1GB,而memcache只有1MB
小結:
1. redis支持master-slave復制模式;memcache可以使用一致性hash做分布式。
2. 如有持久化方面的需求或者對數據類型和處理有要求,應選擇redis;
3. 如果是簡單的key/value存儲可以考慮memcached;
4. 內存管理機制,Memcached主要的cache機制是LRU算法+超時失效。Redis采用的是包裝的mallc/free,相較于Memcached的內存管理方法來說,要簡單很多。
二、 redis相比memcache的優勢
1、 memcached所有的值均是簡單的字符串,redis作為其替代者,支持更為豐富的數據類型;
2、redis的速度比memcached快很多;
3、redis可以持久化其數據。
市面上,目前使用redis較多,但須知redis有哪些性能問題。
三、?redis常見性能問題和解決方案
1.Master最好不要做任何持久化工作(RDB內存快照和AOF日志文件)
原因: 1) 如Master寫RDB內存快照,save命令調度rdbSave函數,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務,所以Master最好不要寫RDB內存快照。2) Master調用BGREWRITEAOF重寫AOF文件,AOF在重寫的時候會占大量的CPU和內存資源,導致服務load過高,出現短暫服務暫停現象。
如RDB內存快照和AOF日志文件;
2.如果數據比較重要,Slave開啟AOF備份數據,策略設置最好為每秒同步一次;
3.為了主從復制的速度和連接的穩定性,Master和Slave最好在同一個局域網;
4.避免在壓力很大的主庫上增加從庫;
5.主從復制不要用圖狀結構,用串行鏈表結構,可方便解決單點故障問題,實現Slave對Master的替換。如果Master宕機,可立刻啟用Slave1做Master。
四、?緩存使用時的常見現象
使用數據緩存會發生幾種現象和解決方法:緩存雪崩、緩存擊穿、緩存擊穿、緩存預熱。
4.1緩存穿透
緩存穿透是指查詢一個一定不存在的數據,由于緩存是不命中時需要從數據庫查詢,查不到數據則不寫入緩存,這將導致這個不存在的數據每次請求都要到數據庫去查詢,造成緩存穿透,也是經常提的緩存命中率問題。
解決辦法
1. 采用布隆過濾器,將所有可能存在的數據哈希到一個足夠大的bitmap中,一個一定不存在的數據會被這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。
2. 如果查詢數據庫也為空,直接設置一個默認值存放到緩存,這樣第二次到緩沖中獲取就有值了,而不會繼續訪問數據庫,但它的過期時間會很短,最長不超過五分鐘。這種辦法最簡單粗暴。
4.2緩存雪崩
緩存雪崩,是指在某一個時間段,緩存集中過期失效。
由于原有緩存失效(過期),新緩存未到期間。所有請求都去查詢數據庫,而對數據庫CPU和內存造成巨大壓力,嚴重的會造成數據庫宕機。從而形成一系列連鎖反應,造成整個系統崩潰。
某個時期緩存集中過期時自然形成的緩存雪崩,一定是在某個時間段集中創建緩存,數據庫如能頂住壓力,緩存的定期創建無非就是對數據庫產生周期性壓力;比較可怕的是而緩存服務節點宕機,對數據庫服務器造成的壓力是不可預知,很可能瞬間把數據庫壓垮。
解決辦法
1)在緩存失效后,通過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。如對某個key只允許一個線程查詢數據和寫緩存,其他線程等待。此方法只允許一個線程重建緩存,其他線程等待重建緩存的線程執行完;加鎖排隊只是為了減輕數據庫的壓力,并沒有提高系統吞吐量。假設在高并發下,緩存重建期間key是鎖著的,過來100個請求99個都在阻塞。同樣會導致用戶等待超時,此方法治標不治本。
2)可以通過緩存reload機制,預先去更新緩存,再即將發生大并發訪問前手動觸發加載緩存;
3)設置不同的key的過期時間,讓緩存失效時間點盡量均勻. 如可以在原有的失效時間上增加一個隨機值,如1-5分鐘隨機。緩存的過期時間的重復率就會降低,避免引發集體失效的事件;
4)做二級緩存,或者雙緩存策略。A1為原始緩存,A2為拷貝緩存,A1失效時,可以訪問A2,A1緩存失效時間設置為短期,A2設置為長期;此方法等同于方法3。
4.3緩存擊穿
緩存擊穿,是指一個key非常熱點,,大并發集中對這一個點進行訪問,當這個key在失效的瞬間,持續的大并發就穿破緩存,直接請求數據庫,就像在一個屏障上鑿開了一個洞,引起數據庫壓力瞬間增大,造成過大壓力。
緩存擊穿和緩存雪崩的區別在于這里針對某一key緩存,前者則是很多key。
解決辦法:
1)設置熱點數據永遠不過期,這種方案由于沒有設置真正的過期時間,實際上已經不存在熱點 key 產生的一系列危害,但會存在數據不一致,代碼復雜度會增大。
加互斥鎖,此方案思路簡單,但存在一定隱患,如構建緩存過程出現問題或者時間較長,可能會存在死鎖和線程池阻塞的風險;這種方法最大的優點是能較好的降低后端存儲負載并在一致性上做的較好。
緩存預熱
緩存預熱就是系統上線后,提前將相關的緩存數據直接加載到緩存系統。避免在用戶請求的時候,先查詢數據庫,再將數據緩存的問題。用戶直接查詢事先被預熱的緩存數據。
解決方法:
1)直接寫個緩存刷新頁面,上線時手工操作下。
2)數據量不大,可以在應用啟動時提前加載常用的熱點數據。
3)定時刷新緩存
4.4緩存更新
通過expire來設置key的過期時間,Redis的6種數據淘汰策略:
1)noeviction:返回錯誤當內存限制達到并且客戶端嘗試執行會讓更多內存被使用的命令(大部分的寫入指令,但DEL和幾個例外)
2)allkeys-lru: 嘗試回收最少使用的鍵(LRU),使得新添加的數據有空間存放。
3)volatile-lru: 嘗試回收最少使用的鍵(LRU),但僅限于在過期集合的鍵,使得新添加的數據有空間存放。
4)allkeys-random: 回收隨機的鍵使得新添加的數據有空間存放。
5)volatile-random: 回收隨機的鍵使得新添加的數據有空間存放,但僅限于在過期集合的鍵。
6)volatile-ttl: 回收在過期集合的鍵,并且優先回收存活時間(TTL)較短的鍵,使得新添加的數據有空間存放。
除了上述緩存失效策略外,還可以根據具體的業務需求進行自定義的緩存淘汰,常見的策略有兩種:
1)定時去清理過期的緩存;
2)當用戶請求過來時,再行判斷此請求所用緩存是否過期,過期的話就去庫取新數并更新緩存。
方法1優點簡單,缺點是維護大量緩存的key是繁瑣;
方法2缺點是每次用戶請求均要判斷緩存是否失效,邏輯相對復雜;
上述兩種客戶化方法業務可根據具體業務場景來權衡使用。
4.5緩存降級
當訪問量劇增、響應時間慢或不響應、非核心服務影響到核心流程的性能時,為保證核心業務服務可用,可對某些數據服務自動降級或人工降級。如電商系統無法降級的服務有加入購物車、訂單結算;可降級的服務有某些商品的訪問瀏覽。
【總結】
1.?如下兩篇推文分別講述了redis和memcached的兩種緩存;
2. 今天文章內容主要介紹了兩者的區別,并介紹了使用數據緩存時常見的緩存擊穿、緩存穿透、緩存雪崩5種常見現象和處理方式;
3. 后續將持續進行試驗進行論證。
To be continued.
【參考】
https://blog.csdn.net/m0_37501154/article/details/89916036
【參考】
https://www.cnblogs.com/lijiasnong/p/9963853.html
【參考】
https://blog.csdn.net/qq_36071795/article/details/83988177
以下為個人公眾號“一森咖記”,歡迎關注。
總結
以上是生活随笔為你收集整理的oracle缓存和Redis,说说数据缓存那点事:Redis和memcached对比的全部內容,希望文章能夠幫你解決所遇到的問題。