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