一文讀懂Redis

一辣之、redis簡(jiǎn)介

Redis 是C語言開發(fā)的一個(gè)開源高性能鍵值對(duì)的內(nèi)存數(shù)據(jù)庫,可以用來做數(shù)據(jù)庫充边、緩存悍募、消息中間件等場(chǎng)景卵史,是一種NoSQL(not-only sql,非關(guān)系型數(shù)據(jù)庫)的數(shù)據(jù)庫

二、Redis特點(diǎn)

  • 優(yōu)秀的性能搜立,數(shù)據(jù)是存儲(chǔ)在內(nèi)存中,讀寫速度非郴毖恚快啄踊,可支持并發(fā)10W QPS
  • 單線程但進(jìn)程,是線程安全的刁标,采用IO 多路復(fù)用制
  • 可作為分布式鎖
  • 支持五種數(shù)據(jù)類型
  • 支持?jǐn)?shù)據(jù)持久化到磁盤
  • 可以作為消息中間件使用颠通,支持消息發(fā)布及訂閱

二、數(shù)據(jù)類型

下表是我列舉的五種數(shù)據(jù)類型的特性及其使用場(chǎng)景

image

三膀懈、緩存

數(shù)據(jù)緩存是Redis最重要的一個(gè)場(chǎng)景顿锰,為緩存而生,在springboot中启搂,一般有兩種使用方式:

  • 直接通過RedisTemplate使用
  • 通過Spring Cache集成Redis(也就是注解的方式)

四硼控、使用緩存遇到的問題

(1) 數(shù)據(jù)一致性

在分布式環(huán)境下,緩存和數(shù)據(jù)庫很容易出現(xiàn)數(shù)據(jù)一致性問題胳赌,如果項(xiàng)目對(duì)緩存的要求是強(qiáng)一致性牢撼,那就不要使用緩存。

我們只能在項(xiàng)目中使用策略降低緩存與數(shù)據(jù)庫一致性的概率疑苫,是無法保障兩者的強(qiáng)一致性熏版,一般策略包括緩存更新機(jī)制纷责,更新數(shù)據(jù)庫后及時(shí)更新緩存、緩存失敗時(shí)增加重試機(jī)制

(2) 緩存雪崩

在了解雪崩潰之前撼短,我們先了解什么是緩存雪崩現(xiàn)象再膳,假設(shè)A系統(tǒng)每秒需要處理5000個(gè)請(qǐng)求,但數(shù)據(jù)庫每秒只能處理4000個(gè)請(qǐng)求曲横,某一天喂柒,緩存機(jī)器出現(xiàn)了宕機(jī),掛了胜榔,這時(shí)候所有的請(qǐng)求一下子全部落在數(shù)據(jù)庫上胳喷,數(shù)據(jù)庫肯定扛不住,報(bào)警掛掉了夭织,這時(shí)候如果沒有采取緩存設(shè)施吭露,數(shù)據(jù)庫又急著用,重新重啟數(shù)據(jù)庫尊惰,剛重啟完成(有可能沒啟動(dòng)完)讲竿,請(qǐng)求又來,數(shù)據(jù)庫立馬掛掉弄屡。這就是雪崩事件题禀,是Redis緩存中最致命問題之一(有一個(gè)是穿透)。大家可以看看下圖

image

出現(xiàn)雪崩事件后不要急不要慌膀捷,我們可以在事故前中后三個(gè)方面來思考解決方案

  • 事故前:redis高可用方案迈嘹,主從+哨兵,集群方案全庸,避免全盤崩潰
  • 事故中:較少數(shù)據(jù)庫的壓力秀仲,本地Ehcache緩存+限流及降級(jí),避免超過數(shù)據(jù)庫承受壓力
  • 事故后:做redis持久化壶笼,一旦Redis重啟神僵,可從磁盤中快速恢復(fù)數(shù)據(jù)

我們來看看改造后的數(shù)據(jù)流程,假設(shè)用戶A發(fā)送一個(gè)請(qǐng)求覆劈,系統(tǒng)先請(qǐng)求本地Ehcache是否有數(shù)據(jù)保礼,如果沒有再去Redis請(qǐng)求數(shù)據(jù),如果沒有再去數(shù)據(jù)庫請(qǐng)求數(shù)據(jù)责语,獲取到數(shù)據(jù)后同步到Ehcache和redis

限流組件的作用:可以設(shè)置每秒請(qǐng)求數(shù)次炮障,有多少通過請(qǐng)求,剩余的未通過的可以走降級(jí)處理坤候,返回一些默認(rèn)的值铝阐,或者友情提示等默認(rèn)操作。具體流程可以看看下圖:

image

這樣做的好處是:

  • 數(shù)據(jù)庫安全:在限流組件可用的情況下铐拐,數(shù)據(jù)庫不會(huì)掛掉徘键,限流根據(jù)確保了每秒多少請(qǐng)求能通過练对。
  • 部分請(qǐng)求可以被處理:數(shù)據(jù)庫沒掛,就意味著至少2/5的請(qǐng)求可以被處理掉
  • 高峰時(shí)期部分請(qǐng)求無法處理到吹害,需要用戶多次點(diǎn)擊螟凭,因?yàn)橹挥?/5的請(qǐng)求被處理,剩下的請(qǐng)求它呀,用戶刷不出來界面螺男,需要多點(diǎn)擊幾次
  • redis設(shè)置的緩存失效時(shí)間不是設(shè)置成同一個(gè)時(shí)間喳张,可根據(jù)功能希停、業(yè)務(wù)、請(qǐng)求接口靈活設(shè)置緩存時(shí)間:setRedis(key, value, time+Math.random()*10000);

(3) 緩存穿透

緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù)攻走,用戶(黑客)不斷發(fā)起請(qǐng)求谓媒,導(dǎo)致請(qǐng)求直接查詢數(shù)據(jù)庫淆院,這種惡意行為攻擊場(chǎng)景的會(huì)直接導(dǎo)致數(shù)據(jù)庫掛掉,數(shù)據(jù)流程如下圖所示

image

處理這種情況相對(duì)比較簡(jiǎn)單點(diǎn)句惯,這種情況是繞過redis或本地緩存直接到達(dá)數(shù)據(jù)庫土辩,可以采取以下方案:

  • 在請(qǐng)求接口層可以做一些校驗(yàn),比如用戶簽權(quán)抢野、參數(shù)校驗(yàn)拷淘,不合法的請(qǐng)求直接return,
  • 還可以針對(duì)有效id做認(rèn)證或直接攔截指孤,不符合的id直接過濾或采用統(tǒng)一key保存到redis启涯,下次不合法的id請(qǐng)求時(shí),直接到緩存中獲取數(shù)據(jù)
  • 采用redis的高級(jí)接口Bloom Filter恃轩,利用高效的數(shù)據(jù)結(jié)構(gòu)和算法快速判斷出你這個(gè) Key 是否在數(shù)據(jù)庫中存在结洼,不存在你 return 就好了,存在你就去查 DB 刷新 KV 再 return

(4) 緩存擊穿

上面講的穿透是針對(duì)大面積數(shù)據(jù)請(qǐng)求详恼,那么擊穿是針對(duì)一點(diǎn)(一個(gè)key)來來導(dǎo)致redis異常,但某個(gè)key是非常熱點(diǎn)引几,請(qǐng)求非常頻繁昧互,處于集中式訪問現(xiàn)象,當(dāng)這個(gè)key失效(過期)時(shí)伟桅,大量的請(qǐng)求就會(huì)擊穿了緩存敞掘,直接請(qǐng)求數(shù)據(jù)庫,就像在屏障中鑿開了一個(gè)洞楣铁。

不同場(chǎng)景下緩存擊穿解決方案

  • 數(shù)據(jù)基本不變:熱點(diǎn)數(shù)據(jù)value基本不更新時(shí)玖雁,可以設(shè)置成永不過期
  • 數(shù)據(jù)更新不頻繁:緩存刷新流程耗時(shí)較少時(shí),可采用redis盖腕、zookeeper等分布式中間件的分布式互斥鎖或者本地互斥鎖保證少量的請(qǐng)求能請(qǐng)求到數(shù)據(jù)庫并重新更新緩存赫冬,其他的流程等鎖釋放后才可以訪問新緩存
  • 數(shù)據(jù)更新頻繁:采用定時(shí)線程浓镜,在緩存過期前主動(dòng)重新構(gòu)建緩存或延長(zhǎng)過期時(shí)間,保證所有的請(qǐng)求能一直訪問緩存

五劲厌、為什么Redis會(huì)如此快

Redis官方介紹可以達(dá)到10W+的QPS膛薛,這個(gè)數(shù)據(jù)不比MEMCache差,而且Redis 是單進(jìn)程單線程的模型补鼻,完全基于內(nèi)存的操作哄啄,CPU不是Redis的瓶頸,Redis的瓶頸是內(nèi)存及網(wǎng)絡(luò)帶寬风范,有以下特點(diǎn):

  • 使用類似于HashMap的原理咨跌,HashMap的查詢及操作的時(shí)間復(fù)雜度是O(1),且絕大多數(shù)請(qǐng)求是純碎的內(nèi)存操作硼婿,數(shù)據(jù)存在內(nèi)存中
  • 數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單锌半,對(duì)數(shù)據(jù)操作也簡(jiǎn)單,基于KV
  • 不錯(cuò)死鎖現(xiàn)象采用單線程操作加酵,避免了不必要的上下文切換及競(jìng)爭(zhēng)條件拳喻,不存在CPU切換現(xiàn)象,也就不存在考慮各種鎖的問題
  • 使用非阻塞IO猪腕,多路復(fù)用IO模型

六冗澈、Redis淘汰策略

  • volatile為前綴的策略都是從已過期的數(shù)據(jù)集中進(jìn)行淘汰。
  • allkeys為前綴的策略都是面向所有key進(jìn)行淘汰陋葡。
  • LRU(least recently used)最近最少用到的亚亲。
  • LFU(Least Frequently Used)最不常用的。
  • 它們的觸發(fā)條件都是Redis使用的內(nèi)存達(dá)到閾值時(shí)腐缤。
image

七捌归、Redis持久化

Redis 持久化策略有兩種:

  • RDB:快照形式是直接把內(nèi)存中的數(shù)據(jù)保存到一個(gè) dump 的文件中,定時(shí)保存岭粤,保存策略惜索。
  • AOF:把所有的對(duì) Redis 的服務(wù)器進(jìn)行修改的命令都存到一個(gè)文件里,命令的集合剃浇。Redis 默認(rèn)是快照 RDB 的持久化方式巾兆。

如果非常關(guān)心你的數(shù)據(jù),但仍然可以承受數(shù)分鐘內(nèi)的數(shù)據(jù)丟失虎囚,那么可以額只使用 RDB 持久角塑。

AOF 將 Redis 執(zhí)行的每一條命令追加到磁盤中,處理巨大的寫入會(huì)降低Redis的性能淘讥,不知道你是否可以接受圃伶。

數(shù)據(jù)庫備份和災(zāi)難恢復(fù):定時(shí)生成 RDB 快照非常便于進(jìn)行數(shù)據(jù)庫備份,并且 RDB 恢復(fù)數(shù)據(jù)集的速度也要比 AOF 恢復(fù)的速度快。

當(dāng)然了窒朋,Redis 支持同時(shí)開啟 RDB 和 AOF搀罢,系統(tǒng)重啟后,Redis 會(huì)優(yōu)先使用 AOF 來恢復(fù)數(shù)據(jù)炼邀,這樣丟失的數(shù)據(jù)會(huì)最少魄揉。

八、Redis 主從復(fù)制

  • 從節(jié)點(diǎn)執(zhí)行 slaveof[masterIP][masterPort]拭宁,保存主節(jié)點(diǎn)信息洛退。
  • 從節(jié)點(diǎn)中的定時(shí)任務(wù)發(fā)現(xiàn)主節(jié)點(diǎn)信息,建立和主節(jié)點(diǎn)的 Socket 連接杰标。
  • 從節(jié)點(diǎn)發(fā)送 Ping 信號(hào)兵怯,主節(jié)點(diǎn)返回 Pong,兩邊能互相通信腔剂。
  • 連接建立后媒区,主節(jié)點(diǎn)將所有數(shù)據(jù)發(fā)送給從節(jié)點(diǎn)(數(shù)據(jù)同步)。
  • 主節(jié)點(diǎn)把當(dāng)前的數(shù)據(jù)同步給從節(jié)點(diǎn)后掸犬,便完成了復(fù)制的建立過程袜漩。接下來,主節(jié)點(diǎn)就會(huì)持續(xù)的把寫命令發(fā)送給從節(jié)點(diǎn)湾碎,保證主從數(shù)據(jù)一致性宙攻。

九、Redis哨兵模式

我們先說說主從復(fù)制會(huì)存在問題:

  • 一旦主節(jié)點(diǎn)宕機(jī)介褥,從節(jié)點(diǎn)晉升為主節(jié)點(diǎn)座掘,同時(shí)需要修改應(yīng)用方的主節(jié)點(diǎn)地址,還需要命令所有從節(jié)點(diǎn)去復(fù)制新的主節(jié)點(diǎn)柔滔,整個(gè)過程需要人工干預(yù)溢陪。
  • 主節(jié)點(diǎn)的寫能力受到單機(jī)的限制。
  • 主節(jié)點(diǎn)的存儲(chǔ)能力受到單機(jī)的限制睛廊。
  • 原生復(fù)制的弊端在早期的版本中也會(huì)比較突出形真,比如:Redis 復(fù)制中斷后,從節(jié)點(diǎn)會(huì)發(fā)起 psync超全。
  • 此時(shí)如果同步不成功咆霜,則會(huì)進(jìn)行全量同步,主庫執(zhí)行全量備份的同時(shí)卵迂,可能會(huì)造成毫秒或秒級(jí)的卡頓裕便。

哨兵的架構(gòu)模式如下:

image

該系統(tǒng)可以執(zhí)行以下四個(gè)任務(wù):

  • 監(jiān)控:不斷檢查主服務(wù)器和從服務(wù)器是否正常運(yùn)行绒净。
  • 通知:當(dāng)被監(jiān)控的某個(gè) Redis 服務(wù)器出現(xiàn)問題见咒,Sentinel 通過 API 腳本向管理員或者其他應(yīng)用程序發(fā)出通知。
  • 自動(dòng)故障轉(zhuǎn)移:當(dāng)主節(jié)點(diǎn)不能正常工作時(shí)挂疆,Sentinel 會(huì)開始一次自動(dòng)的故障轉(zhuǎn)移操作改览,它會(huì)將與失效主節(jié)點(diǎn)是主從關(guān)系的其中一個(gè)從節(jié)點(diǎn)升級(jí)為新的主節(jié)點(diǎn)下翎,并且將其他的從節(jié)點(diǎn)指向新的主節(jié)點(diǎn),這樣人工干預(yù)就可以免了宝当。
  • 配置提供者:在 Redis Sentinel 模式下视事,客戶端應(yīng)用在初始化時(shí)連接的是 Sentinel 節(jié)點(diǎn)集合,從中獲取主節(jié)點(diǎn)的信息庆揩。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末俐东,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子订晌,更是在濱河造成了極大的恐慌虏辫,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锈拨,死亡現(xiàn)場(chǎng)離奇詭異砌庄,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)奕枢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門娄昆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缝彬,你說我怎么就攤上這事萌焰。” “怎么了跌造?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵杆怕,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我壳贪,道長(zhǎng)陵珍,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任违施,我火速辦了婚禮互纯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘磕蒲。我一直安慰自己留潦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布辣往。 她就那樣靜靜地躺著兔院,像睡著了一般。 火紅的嫁衣襯著肌膚如雪站削。 梳的紋絲不亂的頭發(fā)上坊萝,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼十偶。 笑死菩鲜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惦积。 我是一名探鬼主播接校,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼狮崩!你這毒婦竟也來了蛛勉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤睦柴,失蹤者是張志新(化名)和其女友劉穎董习,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體爱只,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡皿淋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恬试。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窝趣。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖训柴,靈堂內(nèi)的尸體忽然破棺而出哑舒,到底是詐尸還是另有隱情,我是刑警寧澤幻馁,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布洗鸵,位于F島的核電站,受9級(jí)特大地震影響仗嗦,放射性物質(zhì)發(fā)生泄漏膘滨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一稀拐、第九天 我趴在偏房一處隱蔽的房頂上張望火邓。 院中可真熱鬧,春花似錦德撬、人聲如沸铲咨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纤勒。三九已至,卻和暖如春隆檀,著一層夾襖步出監(jiān)牢的瞬間摇天,已是汗流浹背北滥。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闸翅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓菊霜,卻偏偏與公主長(zhǎng)得像坚冀,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鉴逞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容