搞懂Redis,這一篇就夠了

1芙粱、緩存帶來的好處:

  • 高性能
    大量相同的請求過來划咐,每次查詢mysql耗時(shí)600ms拴念,如果用緩存耗時(shí)20ms,性能提高30倍.
  • 高并發(fā)
    單機(jī)mysql一般的最大QPS 2000褐缠,超過2000mysql直接死掉政鼠;單機(jī)redis QPS輕松10萬,并發(fā)提高50倍.

2队魏、緩存帶來的壞處:

  • 緩存與數(shù)據(jù)庫的雙寫不一致
  • 緩存雪崩公般、緩存穿透万搔、緩存擊穿
  • 緩存并發(fā)競爭問題

3、redis高性能的三大核心(為什么單線程還能這么快):

  • 純內(nèi)存操作:

這時(shí)Redis達(dá)到每秒萬級別訪問的重要基礎(chǔ)

  • 單線程:

保證高并發(fā)下數(shù)據(jù)的一致性官帘,避免了多線程下的并發(fā)問題:資源共享瞬雹、線程切換、死鎖刽虹、競態(tài)產(chǎn)生的消耗酗捌;

  • 多路I/O復(fù)用,非阻塞I/O:

linux平臺(tái)下涌哲,Redis使用epoll作為I/O多路復(fù)用技術(shù)的實(shí)現(xiàn)胖缤,在加上Redis自身的事件處理模型將epoll中的鏈接、讀寫阀圾、關(guān)閉都轉(zhuǎn)換為事件哪廓,不在網(wǎng)絡(luò)I/O上浪費(fèi)過多的時(shí)間;

3.1 源碼層面

C語言編寫稍刀,源代碼精簡(2萬行)撩独,C語言實(shí)現(xiàn)的程序”距離“操作系統(tǒng)更近,執(zhí)行速度快账月;
Redis源碼里综膀,包含了多種數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn):
簡單動(dòng)態(tài)字符串(SDS)、雙端鏈表局齿、字典剧劝、壓縮列表、整數(shù)集合抓歼、跳躍表等等讥此;
Redis并沒有直接使用這些數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)鍵值對數(shù)據(jù)庫,而是基于這些數(shù)據(jù)結(jié)構(gòu)創(chuàng)建了一個(gè)對象系統(tǒng)谣妻,這個(gè)系統(tǒng)包含了字符串萄喳、列表、哈希蹋半、集合他巨、有序集合這五種類型的對象,每種對象都用到了至少一種前面所說的數(shù)據(jù)結(jié)構(gòu)减江;
針對不同的使用場景染突,為對象設(shè)置多種不同的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),從而優(yōu)化對象在不同場景下的使用效率辈灼;

image.png

4份企、除了緩存,Redis能做些什么特別的事 巡莹?

  • 利用redis生成唯一key
  • 分布式鎖
  • 消息隊(duì)列

5司志、利用redis實(shí)現(xiàn)分布式鎖

redis是單線程的甜紫,利用setnx命令的原子性(判斷指定key是否存在,不存在才能添加成功)骂远,實(shí)現(xiàn)多線程狀態(tài)下的分布式鎖
SET my_key my_value NX PX milliseconds

引用:如何優(yōu)雅地用Redis實(shí)現(xiàn)分布式鎖?

6棵介、redis過期策略

Reference:引用
當(dāng)redis存了非常多數(shù)據(jù)數(shù)據(jù)時(shí),過期的數(shù)據(jù)不是實(shí)時(shí)刪除的吧史,如果每次刪除都是掃描全部獲取過期數(shù)據(jù)邮辽,代價(jià)太大,所以很可能當(dāng)內(nèi)存滿了時(shí)贸营,會(huì)先刪除沒有過期的

定期刪除

每個(gè)一段時(shí)間吨述,從設(shè)置了過期的key里面隨機(jī)挑選,判斷是否過期钞脂,過期則刪除

惰性刪除

通過定期刪除肯定會(huì)遺留很多沒刪掉的揣云,所以,當(dāng)在獲取某個(gè)key時(shí)冰啃,會(huì)判斷是否已經(jīng)過期邓夕,過期則刪除不返回

8、內(nèi)存淘汰機(jī)制(LRU算法)

當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí)阎毅,redis會(huì)啟用內(nèi)存淘汰機(jī)制:

  • allkey_LRU:移除最近最少使用的key(最常用
  • allkey_Random:隨機(jī)移除一個(gè)key
  • volatile_LRU:在設(shè)置了過期時(shí)間的鍵空間中焚刚,移除最近最少使用的key
  • volatile_Random:在設(shè)置了過期時(shí)間的鍵空間中,隨機(jī)移除key
  • volatile_TTL:在設(shè)置了過期時(shí)間的鍵空間中扇调,優(yōu)先移除更早過期的key

9矿咕、Redis的I/O多路復(fù)用

Reference:引用
下面舉一個(gè)例子,模擬一個(gè)tcp服務(wù)器處理30個(gè)客戶socket狼钮。假設(shè)你是一個(gè)老師碳柱,讓30個(gè)學(xué)生解答一道題目,然后檢查學(xué)生做的是否正確熬芜,你有下面幾個(gè)選擇:

  1. 第一種選擇:按順序逐個(gè)檢查莲镣,先檢查A,然后是B涎拉,之后是C瑞侮、D。曼库。区岗。這中間如果有一個(gè)學(xué)生卡主略板,全班都會(huì)被耽誤毁枯。這種模式就好比,你用循環(huán)挨個(gè)處理socket叮称,根本不具有并發(fā)能力种玛。
  2. 第二種選擇:你創(chuàng)建30個(gè)分身藐鹤,每個(gè)分身檢查一個(gè)學(xué)生的答案是否正確。 這種類似于為每一個(gè)用戶創(chuàng)建一個(gè)進(jìn)程或者線程處理連接赂韵。
  3. 第三種選擇娱节,你站在講臺(tái)上等,誰解答完誰舉手祭示。這時(shí)C肄满、D舉手,表示他們解答問題完畢质涛,你下去依次檢查C稠歉、D的答案,然后繼續(xù)回到講臺(tái)上等汇陆。此時(shí)E怒炸、A又舉手,然后去處理E和A毡代。阅羹。。

這種就是IO復(fù)用模型教寂,Linux下的select捏鱼、poll和epoll就是干這個(gè)的。將用戶socket對應(yīng)的fd注冊進(jìn)epoll酪耕,然后epoll幫你監(jiān)聽哪些socket上有消息到達(dá)穷躁,這樣就避免了大量的無用操作。此時(shí)的socket應(yīng)該采用非阻塞模式因妇。這樣问潭,整個(gè)過程只在調(diào)用select、poll婚被、epoll這些調(diào)用的時(shí)候才會(huì)阻塞狡忙,收發(fā)客戶消息是不會(huì)阻塞的,整個(gè)進(jìn)程或者線程就被充分利用起來址芯,這就是事件驅(qū)動(dòng)灾茁,所謂的reactor模式。

java的NIO 是IO的多路復(fù)用谷炸; IO多路復(fù)用聽上去好像是多個(gè)數(shù)據(jù)可以共享一個(gè)IO(socket連接)北专,實(shí)際上并非如此。IO多路復(fù)用不是指多個(gè)服務(wù)共享一個(gè)連接旬陡,而僅僅是指多個(gè)連接的管理可以在同一進(jìn)程拓颓。

IO多路復(fù)用:各個(gè)平臺(tái)的底層IO復(fù)用實(shí)現(xiàn)各不相同,linux采用select描孟、poll驶睦、epoll實(shí)現(xiàn)砰左,macOS采用kqueue,windows采用IOCP场航,netty在此基礎(chǔ)上進(jìn)行了封裝缠导,使其更好用,而底層實(shí)際上是調(diào)用的當(dāng)前平臺(tái)的IO復(fù)用接口(native方法)溉痢,而Redis底層也是依賴平臺(tái)的IO復(fù)用

10僻造、redis 集群的三種模式

10.1 主從復(fù)制(無法保證高可用)

image.png

10.2 哨兵模式(無法保證高性能)

Redis主從模式雖然能做到很好的數(shù)據(jù)備份,但是他并不是高可用的孩饼。一旦主服務(wù)器點(diǎn)宕機(jī)后嫡意,只能通過人工去切換主服務(wù)器。因此Redis的哨兵模式也就是為了解決主從模式的高可用方案捣辆。


image.png

10.3 集群模式

Redis哨兵模式實(shí)現(xiàn)了高可用蔬螟,讀寫分離,但是其主節(jié)點(diǎn)仍然只有一個(gè)汽畴,即寫入操作都是在主節(jié)點(diǎn)中旧巾,這也成為了性能的瓶頸。
因此Redis在 3.0 后加入了Cluster模式忍些,它采用去無心節(jié)點(diǎn)方式實(shí)現(xiàn)鲁猩,集群將會(huì)通過分片方式保存數(shù)據(jù)庫中的鍵值對;
每個(gè)分片節(jié)點(diǎn)又通過主從方式保證高可用:與哨兵類似罢坝,分片中的每個(gè)節(jié)點(diǎn)會(huì)定期向其他節(jié)點(diǎn)發(fā)送消息廓握,已檢測各個(gè)節(jié)點(diǎn)的狀態(tài),如果主節(jié)點(diǎn)被半數(shù)以上節(jié)點(diǎn)檢測到下線嘁酿,會(huì)重新選擇主節(jié)點(diǎn)隙券;


image.png
  • 集群模式下的擴(kuò)縮容:
    每個(gè)分片節(jié)點(diǎn)的分片范圍維護(hù)在配置文件中,當(dāng)增刪節(jié)點(diǎn)時(shí)闹司,需要將重新將16383個(gè)slots分配到集群中的節(jié)點(diǎn)上(數(shù)據(jù)遷移)

11娱仔、一致性Hash算法

先說一個(gè)誤區(qū):Redis的集群模式本身沒有使用一致性hash算法,而是使用slots插槽實(shí)現(xiàn)了數(shù)據(jù)分片游桩。
一致性Hash算法主要用于解決分布式緩存集群節(jié)點(diǎn)新增牲迫,和節(jié)點(diǎn)失效的問題;
我們說的一致性hash都不是緩存機(jī)器自身的功能借卧,而是集群前置的代理或客戶端實(shí)現(xiàn)的盹憎。比如在redis的jedis客戶端jar包就是實(shí)現(xiàn)了一致性hash算法(客戶端模式)。

12铐刘、緩存穿透陪每、緩存雪崩、緩存擊穿

緩存穿透(不存在key)
  • 概念:訪問一個(gè)數(shù)據(jù)庫不存在的key,一般情況不會(huì)緩存這種數(shù)據(jù)奶稠,所以的請求都命中DB;
  • 解決方案
  1. 采用布隆過濾器捡遍,使用一個(gè)足夠大的bitmap锌订,用于存儲(chǔ)可能訪問的key,不存在的key直接被過濾画株;引用

  2. 訪問key未在DB查詢到值辆飘,也將空值寫進(jìn)緩存,但可以設(shè)置較短過期時(shí)間谓传。

緩存雪崩(同時(shí)過期)
  • 概念:大量的key設(shè)置了相同的過期時(shí)間蜈项,導(dǎo)致在緩存在同一時(shí)刻全部失效,造成瞬時(shí)DB請求量大续挟、壓力驟增紧卒,引起雪崩。
  • 解決方案
    可以給緩存設(shè)置過期時(shí)間時(shí)加上一個(gè)隨機(jī)值時(shí)間诗祸,使得每個(gè)key的過期時(shí)間分布開來跑芳,不會(huì)集中在同一時(shí)刻失效。
緩存擊穿(熱點(diǎn)key過期)
  • 概念
    一個(gè)存在的key直颅,在緩存過期的一刻博个,同時(shí)有大量的請求,這些請求都會(huì)擊穿到DB功偿,造成瞬時(shí)DB請求量大盆佣、壓力驟增。
  • 解決方案
    設(shè)置熱點(diǎn)緩沖永不過期
    緩存預(yù)熱:每次查出來看看是不是要過期了械荷,快過期了則更新緩存
    在訪問key之前共耍,采用SETNX(set if not exists)來設(shè)置另一個(gè)短期key來鎖住當(dāng)前key的訪問,訪問結(jié)束再刪除該短期key吨瞎。

13征堪、數(shù)據(jù)庫與緩存雙寫一致性問題

引用
一般采用:先更新數(shù)據(jù)庫,再刪除緩存

14关拒、redis的持久化

14.1 redis持久化的意義

redis服務(wù)器宕機(jī)的兜底措施佃蚜,避免宕機(jī)時(shí)直接訪問數(shù)據(jù)庫、降低請求響應(yīng)速度着绊;

14.2 AOF(Append Only File)日志

寫后日志谐算,類似redo log,每執(zhí)行一次命令归露,如果成功則保存命令到aof日志文件洲脂,在主線程中執(zhí)行,有阻塞風(fēng)險(xiǎn);

  • 三種寫回策略


    AOF三種寫回策略

AOF重寫機(jī)制

如果一直往AOF文件里寫日志恐锦,日志文件會(huì)爆炸往果;
當(dāng)AOF文件的大小超過了配置所設(shè)置的闕值時(shí),Redis就會(huì)啟動(dòng)AOF文件壓縮一铅,只保留可以恢復(fù)數(shù)據(jù)的最小指令集陕贮,可以使用命令bgrewriteaof;

  • 觸發(fā)機(jī)制:Redis會(huì)記錄上次重寫時(shí)的AOF文件大小潘飘,默認(rèn)配置時(shí)當(dāng)AOF文件大小是上次rewrite后大小的一倍且文件大于64M時(shí)觸發(fā)
      auto-aof-rewrite-percentage 100 (一倍)
       auto-aof-rewrite-min-size 64mb
    AOF重寫可避免主線程阻塞:主線程fork一個(gè)子線程肮之,同時(shí)把主線程的內(nèi)存通過寫時(shí)復(fù)制的方式拷貝給子線程,然后子線程在不影響主線程的情況下逐一把拷貝的數(shù)據(jù)寫成操作卜录,記入重寫日志戈擒;
    如果在子線程寫日志的過程中主線程產(chǎn)生的數(shù)據(jù),會(huì)放到一個(gè)緩存區(qū)中艰毒,后續(xù)寫入AOF文件筐高;
    AOF非阻塞的重寫過程

14.3 RDB(Redis DataBase)內(nèi)存快照

默認(rèn)持久化方式

與AOF對比

AOF記錄的是操作命令,不是實(shí)際數(shù)據(jù)丑瞧,故障恢復(fù)的時(shí)候緩慢凯傲;
RDB能夠快速恢復(fù),但是相比于AOF的增量式操作嗦篱,RDB的全量試操作更耗時(shí)耗力冰单;

兩個(gè)命令來生成RDB

Redis 提供了兩個(gè)命令來生成 RDB 文件,分別是 save 和 bgsave灸促。

  • save:在主線程中執(zhí)行诫欠,會(huì)導(dǎo)致阻塞;
  • bgsave:創(chuàng)建一個(gè)子進(jìn)程浴栽,專門用于寫入 RDB 文件荒叼,避免了主線程的阻塞,這也是 Redis RDB 文件生成的默認(rèn)配置典鸡。

AOF和RDB結(jié)合使用

Redis 4.0提出一個(gè)混合使用AOF日志和內(nèi)存快照的方法被廓;內(nèi)存快照以一定頻率執(zhí)行,兩次快照間萝玷,使用AOF日志記錄這期間的所有命令操作嫁乘;
這個(gè)方法既能享受到 RDB 文件快速恢復(fù)的好處,又能享受到 AOF 只記錄操作命令的簡單優(yōu)勢

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末球碉,一起剝皮案震驚了整個(gè)濱河市蜓斧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌睁冬,老刑警劉巖挎春,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡直奋,警方通過查閱死者的電腦和手機(jī)能庆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脚线,“玉大人搁胆,你說我怎么就攤上這事⊙惩欤” “怎么了丰涉?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵拓巧,是天一觀的道長斯碌。 經(jīng)常有香客問我,道長肛度,這世上最難降的妖魔是什么傻唾? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮承耿,結(jié)果婚禮上冠骄,老公的妹妹穿的比我還像新娘。我一直安慰自己加袋,他們只是感情好凛辣,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著职烧,像睡著了一般扁誓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蚀之,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天蝗敢,我揣著相機(jī)與錄音,去河邊找鬼足删。 笑死寿谴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的失受。 我是一名探鬼主播讶泰,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拂到!你這毒婦竟也來了峻厚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤谆焊,失蹤者是張志新(化名)和其女友劉穎惠桃,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡辜王,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年劈狐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呐馆。...
    茶點(diǎn)故事閱讀 40,872評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肥缔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汹来,到底是詐尸還是另有隱情续膳,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布收班,位于F島的核電站坟岔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏摔桦。R本人自食惡果不足惜社付,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望邻耕。 院中可真熱鬧鸥咖,春花似錦、人聲如沸兄世。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽御滩。三九已至鸥拧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間艾恼,已是汗流浹背住涉。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钠绍,地道東北人舆声。 一個(gè)月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像柳爽,于是被迫代替她去往敵國和親媳握。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評論 2 361

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