Redis面試以及在分布式集群環(huán)境中遇到的問題

Redis 面試題

前面已經(jīng)系統(tǒng)的梳理了Redis的各個(gè)功能和搭建的方法闻察,下面我們就來系統(tǒng)的梳理下械荷,關(guān)于Redis在系統(tǒng)中可能會(huì)出現(xiàn)的面試題

  1. 介紹Redis的集中架構(gòu)模式

    • 單機(jī)型

    這個(gè)模型很簡單磅甩,多個(gè)客戶端直接連接Redis服務(wù)器

    特點(diǎn):內(nèi)存容量有限,支持的QPS有限痴昧,無法擴(kuò)容鸯隅,并且沒有高可用

    • 主從復(fù)制(讀寫分離)

    通過Redis的replication的功能,創(chuàng)建多個(gè)Master服務(wù)器從屬的Slave服務(wù)器送矩,其中Master服務(wù)器進(jìn)行寫操作蚕甥,所有的Slave服務(wù)器進(jìn)行讀操作,這樣只要網(wǎng)絡(luò)正常的話栋荸,Master和Slave都具有相同的數(shù)據(jù)

    特點(diǎn):支持了讀QPS的擴(kuò)容菇怀,但是內(nèi)存容量的問題沒有解決,也沒有解決寫QPS的高并發(fā)問題晌块,同時(shí)也沒有高可用

    • 哨兵

    利用Redis的sentinel分布式集群爱沟,來兼容Redis主從服務(wù)器,當(dāng)Master服務(wù)器下線或者不再對(duì)外提供服務(wù)時(shí)匆背,將Slave節(jié)點(diǎn)升級(jí)為Master節(jié)點(diǎn)呼伸,以保證Redis服務(wù)能繼續(xù)對(duì)外提供服務(wù)

    特點(diǎn):集群監(jiān)控、消息通知钝尸、故障轉(zhuǎn)移和配置中心括享,解決了上面兩個(gè)架構(gòu)模式中的高可用的問題搂根,但是主從切換需要時(shí)間,可能會(huì)造成數(shù)據(jù)部分丟失

    • 集群

    Redis 3.x版本之后铃辖,提供RedisCluster來創(chuàng)建Redis集群環(huán)境剩愧,利用RedisCluster來管理多個(gè)Redis的服務(wù)

    特點(diǎn):無中心架構(gòu)、數(shù)據(jù)按照hashslot存儲(chǔ)分布在多個(gè)節(jié)點(diǎn)澳叉,節(jié)點(diǎn)之間數(shù)據(jù)共享隙咸、可橫向和縱向擴(kuò)容,Master節(jié)點(diǎn)擴(kuò)容成洗,高可用并且能自動(dòng)實(shí)現(xiàn)故障轉(zhuǎn)移五督、節(jié)點(diǎn)之間通過gossip協(xié)議進(jìn)行狀態(tài)信息交換

  2. Redis集群對(duì)于存儲(chǔ)節(jié)點(diǎn)采用的算法是什么?能否詳細(xì)介紹該算法?

Redis在分布式的算法中采用了哈希槽的概念瓶殃,在詳細(xì)介紹哈希槽之前充包,我們需要先簡單的了解下一致性hash算法的概念

  • 一致性hash算法

一致性hash算法的總結(jié)參考了博文《一致性哈希算法原理》,現(xiàn)整理如下:

1. 場景:如果一個(gè)集群接收多個(gè)請(qǐng)求遥椿,那么該怎么通過算法將每個(gè)請(qǐng)求分布到集群中對(duì)應(yīng)的服務(wù)基矮,并且滿足高效率呢?
2. 一致性hash算法的原理:將集群中所有的服務(wù)器的節(jié)點(diǎn)先計(jì)算hash值冠场,然后將該值存放管道0~2的32次方的圓形節(jié)點(diǎn)中家浇;
發(fā)送過來的請(qǐng)求也計(jì)算對(duì)應(yīng)的hash值,然后根據(jù)hash值到圓形節(jié)點(diǎn)中順時(shí)針查找最新的服務(wù)節(jié)點(diǎn)碴裙,然后將請(qǐng)求發(fā)送過去钢悲,等待該節(jié)點(diǎn)服務(wù)器的響應(yīng);
3. 如果對(duì)集群進(jìn)行擴(kuò)容舔株,新增一臺(tái)服務(wù)莺琳,則相當(dāng)于在圓形節(jié)點(diǎn)上新增一個(gè)節(jié)點(diǎn),
這樣當(dāng)訪問的請(qǐng)求進(jìn)行hash計(jì)算后的值到圓形節(jié)點(diǎn)上進(jìn)行匹配時(shí)载慈,最多影響該節(jié)點(diǎn)相鄰的節(jié)點(diǎn)惭等,對(duì)其他的節(jié)點(diǎn)沒有任何影響;
4. 一致性hash性質(zhì):平衡性办铡,單調(diào)性辞做,分散性,負(fù)載和平滑性寡具;
  • hashslot

hashslot的算法參考了博文《Redis哈希槽》秤茅,先整理如下:

1. RedisCluster采用無中心結(jié)構(gòu),每個(gè)節(jié)點(diǎn)保存數(shù)據(jù)和整個(gè)集群狀態(tài)晒杈,每個(gè)節(jié)點(diǎn)和其他節(jié)點(diǎn)進(jìn)行連接
2. 所有的redis節(jié)點(diǎn)彼此互聯(lián)(PING-PONG機(jī)制),內(nèi)部使用RESP協(xié)議進(jìn)行通訊孔厉,該協(xié)議具有實(shí)現(xiàn)簡單拯钻、快速解析和可讀性好的優(yōu)點(diǎn)帖努;
3. 節(jié)點(diǎn)的fail是通過集群中超過半數(shù)的節(jié)點(diǎn)檢測(cè)失效時(shí)才生效
4. redis-cluster把所有的物理節(jié)點(diǎn)映射到0-16383個(gè)slot上,cluster負(fù)責(zé)維護(hù)node-slot-vlaue
5. Redis集群預(yù)先分好16384個(gè)slot粪般,當(dāng)需要在Redis集群中放置一個(gè)key-value時(shí)拼余,根據(jù)CRC16 mod 15384的值,決定將一個(gè)key放置到哪個(gè)slot中
  1. 什么是緩存穿透亩歹,緩存擊穿匙监,如果避免,什么是緩存雪崩小作,如何避免
  • 緩存穿透

一般前端傳來請(qǐng)求亭姥,先查詢緩存,緩存中沒有了在查詢數(shù)據(jù)庫顾稀,而緩存穿透达罗,前端大量請(qǐng)求過來,查詢緩存中不存在静秆,則再查詢數(shù)據(jù)庫粮揉,而數(shù)據(jù)庫中也不存在,則這個(gè)值無法形成緩存抚笔,那么這個(gè)請(qǐng)求每次都會(huì)請(qǐng)求數(shù)據(jù)庫扶认,這對(duì)數(shù)據(jù)庫就造成了極大的壓力;

我們可以對(duì)空也進(jìn)行緩存殊橙,緩存的失效時(shí)間可以設(shè)置短點(diǎn)辐宾;也可以對(duì)一定不存在的key進(jìn)行過濾,可以將所有可能存在的key存放在一個(gè)大的bitmap中蛀柴,查詢時(shí)通過bitmap進(jìn)行過濾螃概;

  • 緩存擊穿

是指一個(gè)Key非常熱點(diǎn),再不停的抗住高并發(fā)鸽疾,大并發(fā)集中對(duì)這個(gè)key進(jìn)行訪問吊洼,如果該key失效了,則持續(xù)的高并發(fā)就會(huì)擊穿緩存制肮,直接請(qǐng)求數(shù)據(jù)庫冒窍,嚴(yán)重時(shí)可能造成數(shù)據(jù)庫宕機(jī)

其實(shí)對(duì)于熱點(diǎn)key來說,很容易解決豺鼻,只要將這個(gè)key對(duì)應(yīng)的失效時(shí)間設(shè)置為永不失效即可综液,當(dāng)然這個(gè)主要是根據(jù)業(yè)務(wù)的需求,一般大key是一段時(shí)間內(nèi)的訪問量是很恐怖的儒飒,但是過了這個(gè)時(shí)間段訪問請(qǐng)求就下來了谬莹,到時(shí)再更改失效時(shí)間即可;

  • 緩存雪崩

緩存雪崩是指在某個(gè)時(shí)間段內(nèi),緩存集中過期失效附帽。這樣請(qǐng)求都會(huì)落在數(shù)據(jù)庫上埠戳,對(duì)數(shù)據(jù)庫造成極大的壓力,出現(xiàn)系統(tǒng)崩潰蕉扮;

1. 我們可以將系統(tǒng)中不同種類的key分別設(shè)置不同的失效時(shí)間整胃,
比如說我們可以在原來的過期時(shí)間基礎(chǔ)上增加一個(gè)隨機(jī)值,這樣的話大部分的key的過期時(shí)間就會(huì)有差別喳钟,不會(huì)集中失效<br/>
2. 其次使用緩存降級(jí)屁使,利用eehcache等本地緩存,但主要還是對(duì)源服務(wù)訪問進(jìn)行限流奔则、資源隔離蛮寂、降級(jí)等。
當(dāng)訪問量劇增应狱、服務(wù)出現(xiàn)問題仍然需要保證服務(wù)還是可用的共郭。
系統(tǒng)可以根據(jù)一些關(guān)鍵數(shù)據(jù)進(jìn)行自動(dòng)降級(jí),也可以配置開關(guān)實(shí)現(xiàn)人工降級(jí)疾呻,這里會(huì)涉及到運(yùn)維的配合
3. Redis緩存的備份和預(yù)熱
  • 緩存并發(fā)

是指多個(gè)redis的client同時(shí)set

解決的思路可以將redis的set操作放到隊(duì)列中使其進(jìn)行串行執(zhí)行

  1. Redis有哪些常見的用途
  • 會(huì)話緩存
  • 全頁緩存
  • 隊(duì)列
  • 排行榜/計(jì)數(shù)器
  • 發(fā)布/訂閱
  1. Redis中事務(wù)相關(guān)的命令有哪些除嘹?
  • MULTI
  • EXEC
  • DISCARD
  • WATCH
  1. Redis如何做內(nèi)存優(yōu)化

在選擇數(shù)據(jù)結(jié)構(gòu)時(shí),盡可能使用散列表(hashes),因?yàn)樯⒘斜硎褂玫膬?nèi)存是非常小的岸蜗,所以你盡可能的將你的數(shù)據(jù)模型抽象到一個(gè)散列表中

  1. Redis內(nèi)存回收機(jī)制以及過期策略

Redis的內(nèi)存監(jiān)控是使用:redis-cli 中的info命令來查看的

    # Memory
    used_memory:26355360#當(dāng)前Redis所有key-value值及內(nèi)部開銷理論上要占用的內(nèi)存
    used_memory_human:25.13M#上一數(shù)據(jù)的可讀版本
    used_memory_rss:28127232##(Resident Set Size常駐數(shù)據(jù)集大形竟尽),可理解為OS為Redis分配的物理內(nèi)存總量
    used_memory_rss_human:26.82M
    used_memory_peak:26355360#峰值內(nèi)存
    used_memory_peak_human:25.13M#峰值內(nèi)存可讀版本
    total_system_memory:8253997056
    total_system_memory_human:7.69G
    used_memory_lua:37888#lua引擎占用內(nèi)存
    used_memory_lua_human:37.00K
    maxmemory:0
    maxmemory_human:0B
    maxmemory_policy:noeviction
    mem_fragmentation_ratio:1.07#內(nèi)存碎片率璃岳,used_memory_rss 和 used_memory 之間的比率
    mem_allocator:jemalloc-4.0.3#所使用的內(nèi)存分配器年缎。可以是 libc 铃慷、 jemalloc 或者 tcmalloc

其中mem_fragmentation_ratio(內(nèi)存碎片率)是分析Redis性能的重要數(shù)據(jù)指標(biāo)

  • 大于1:OS為Redis分配的物理內(nèi)存 > Redis所有key-value值及內(nèi)部開銷應(yīng)占用的內(nèi)存
    產(chǎn)生原因:物理內(nèi)存多出的部分单芜,Redis內(nèi)移除對(duì)象的占用內(nèi)存,但這部分內(nèi)存由Redis自帶內(nèi)存分配器占用犁柜,沒有向操作系統(tǒng)返回洲鸠。這一部分就是內(nèi)存碎片
  • 小于1:OS為Redis分配的物理內(nèi)存 < Redis所有key-value值及內(nèi)部開銷理應(yīng)占用的內(nèi)存
    產(chǎn)生原因:應(yīng)占內(nèi)存比物理內(nèi)存多出的部分,是被操作系統(tǒng)交換到虛擬內(nèi)存馋缅,說明當(dāng)前Redis的內(nèi)存使用已經(jīng)超出物理內(nèi)存

內(nèi)存碎片率保持在1.0至1.5之間是最理想的狀態(tài)扒腕。假若碎片率超過了1.5,我所知道的最有效解決手段就是重啟Redis服務(wù)器萤悴,釋放內(nèi)存回到操作系統(tǒng)瘾腰;反之,若碎片率為0.9覆履,說明物理內(nèi)存已不夠用蹋盆,應(yīng)增添硬件费薄,或設(shè)置Redis最大內(nèi)存限制maxmemory

最大內(nèi)存限制maxmemory的設(shè)置非常重要栖雾,如果不設(shè)置maxmemory义锥,Redis一直會(huì)為其分配內(nèi)存,直至耗盡所有物理內(nèi)存岩灭,直到操作系統(tǒng)進(jìn)行虛擬內(nèi)存交換。因此赂鲤,一般情況下噪径,作者建議還是把峰值設(shè)置設(shè)上。開啟此配置数初,當(dāng)超出限定內(nèi)存情況發(fā)生找爱,Redis會(huì)返回異常消息,操作系統(tǒng)不會(huì)因內(nèi)存溢出而奔潰泡孩。還有一點(diǎn)建議是车摄,開發(fā)者在系統(tǒng)設(shè)計(jì)之初,就應(yīng)當(dāng)制定Redis內(nèi)存使用劃分計(jì)劃仑鸥,而劃分原則是吮播,為Redis準(zhǔn)備系統(tǒng)可能使用的峰值內(nèi)存,而不是平均使用內(nèi)存眼俊。例如系統(tǒng)大部分情況會(huì)以Redis作為分布式緩存寫入10G數(shù)據(jù)意狠,但大部分情況下只會(huì)跑到4G,但Redis依然推薦用戶為其預(yù)留10G內(nèi)存(used_memory_peak峰值)疮胖。

maxmemory的單位是bytes环戈,默認(rèn)為0,即不限制最大內(nèi)存澎灸。

Redis的內(nèi)存回收主要圍繞Redis的過期策略和淘汰策略來進(jìn)行的院塞,Redis中過期策略和淘汰策略是不一樣的,我們來詳細(xì)了解下兩者之間的區(qū)別:

  • 過期策略

過期策略分為三種:定時(shí)過期性昭、惰性過期以及定期過期

1. 定時(shí)過期

是我們通過程序向redis中新增數(shù)據(jù)的同時(shí)就已經(jīng)設(shè)置好該數(shù)據(jù)的過期時(shí)間拦止,到了定時(shí)時(shí)間就會(huì)讓該數(shù)據(jù)失效,
這種方式對(duì)內(nèi)存友好巩梢,但是對(duì)CPU的計(jì)算相對(duì)就提高了很多创泄,這個(gè)在系統(tǒng)提供高并發(fā)服務(wù)的受到影響,并且影響系統(tǒng)的響應(yīng)和吞吐量

2. 惰性過期

所謂的惰性過期括蝠,就是我們?cè)谠L問該數(shù)據(jù)時(shí)鞠抑,在判斷該數(shù)據(jù)是否過期失效,如果過期則刪除忌警,
這種方法能大量的節(jié)省CPU的資源搁拙,但是對(duì)內(nèi)存非常不友好秒梳,可能出現(xiàn)大量的Key沒有被訪問,從而也不會(huì)刪除箕速,占用大量的內(nèi)存

3. 定期過期

每隔一段時(shí)間酪碘,就會(huì)掃描一下redis中expires字典中一定數(shù)量的key,并且清除其中已經(jīng)過期的key盐茎。
通過定時(shí)掃描的時(shí)間間隔和每次掃描的限定損耗兴垦,在不同的情況下,使得CPU和內(nèi)存資源達(dá)到相對(duì)的一種平衡

Redis中同時(shí)用了惰性過期和定期過期

  • 淘汰策略

所謂淘汰策略就是當(dāng)內(nèi)存中內(nèi)存不足字柠,Redis中是達(dá)到redis.conf配置中的maxmemory的極限時(shí)探越,需要采用LUA淘汰算法來定期清理掉哪些數(shù)據(jù)

1. LUA算法

LUA算法就是最近最少使用算法

2. 緩存清理配置

redis.conf配置中的maxmemory配置內(nèi)存達(dá)到多大時(shí),進(jìn)行內(nèi)存請(qǐng)求窑业,
在64位系統(tǒng)中钦幔,如果配置為0,則不限制內(nèi)存的使用常柄,
但是在32位系統(tǒng)中鲤氢,默認(rèn)顯示內(nèi)存大小是3G

3. Redis內(nèi)存淘汰策略

淘汰策略是有redis.conf配置中的 maxmemory-policy來控制的,其值主要有以下幾個(gè):
策略名稱 策略說明
volatile-lru 使用LRU算法刪除一個(gè)鍵(只對(duì)設(shè)置了生存時(shí)間的鍵)
allkeys-lru 使用LRU算法刪除一個(gè)鍵
volatile-random 隨機(jī)刪除一個(gè)鍵(只對(duì)設(shè)置了生存時(shí)間的鍵)
allkeys-random 隨機(jī)刪除一個(gè)鍵
volatile-ttl 刪除生存時(shí)間接近的一個(gè)鍵
noeviction 不刪除鍵西潘,只返回錯(cuò)誤
  • noeviction: 當(dāng)內(nèi)存不足時(shí)寫入新的數(shù)據(jù)卷玉,寫入操作會(huì)報(bào)錯(cuò)
  • allkeys-lru: 當(dāng)不存不足時(shí)寫入新的數(shù)據(jù),在鍵空間中喷市,移除最近最少使用的key
  • allkeys-random:當(dāng)不存不足時(shí)寫入新的數(shù)據(jù)揍庄,在鍵空間中,隨機(jī)移除某個(gè)key
  • volatile-lru: 當(dāng)不存不足時(shí)寫入新的數(shù)據(jù)东抹,在設(shè)置過期時(shí)間的鍵中蚂子,移除最近最少使用的鍵
  • volatile-random:當(dāng)不存不足時(shí)寫入新的數(shù)據(jù),在設(shè)置過期時(shí)間的鍵中缭黔,隨機(jī)移除一個(gè)鍵
  • volatile-ttl:當(dāng)內(nèi)存不足時(shí)寫入新的數(shù)據(jù)食茎,在設(shè)置過期時(shí)間的鍵中,有更早過期時(shí)間的key優(yōu)先刪除
  1. Redis實(shí)現(xiàn)分布式鎖

在開發(fā)中鎖的概念就非常重要了馏谨,我們常接觸到的有線程鎖别渔、進(jìn)程鎖和分布式鎖。

分布式鎖就是當(dāng)多個(gè)進(jìn)程不在同一系統(tǒng)中惧互,用分布式鎖控制多個(gè)線程對(duì)資源進(jìn)行訪問哎媚。

分布式鎖不僅具有鎖的特征,還多了一下其他的特征

  • 互斥性:任意時(shí)刻喊儡,只有一個(gè)客戶端獲取鎖拨与,不能同時(shí)又多個(gè)客戶端獲取鎖
  • 安全性:鎖只能被持有該鎖的對(duì)象機(jī)進(jìn)行解決,獲取鎖自動(dòng)消除
  • 死鎖:獲取鎖的客戶端因?yàn)槟承┰蝈礄C(jī)了而未能釋放鎖艾猜,其他的客戶端無法獲取鎖
  • 容錯(cuò):當(dāng)部分節(jié)點(diǎn)宕機(jī)了买喧,客戶端仍能獲取鎖和釋放鎖

Redis實(shí)現(xiàn)分布式鎖有以下兩種方案:

1. 在操作某個(gè)記錄時(shí)捻悯,查看是否存在對(duì)應(yīng)的key記錄 ,如果存在說明該記錄被加鎖淤毛,如果沒有的話在繼續(xù)添加鎖今缚,
并且添加鎖成功之后處理自己的業(yè)務(wù)邏輯,相關(guān)的偽代碼如下
// 加鎖
function boolean lock(taskId) {
    if (existsKey(taskId)) {
        return false;
    }else {
        // 向redis中查詢新的key 設(shè)置過期時(shí)間
        setKey(taskId);
        return true;
    }
}

// 釋放鎖
function relaseLock(taskId) {
    if (existsKey(taskId)) {
        delKey(taskId);
    }
}

// 使用鎖
booelan lock = false;
try{
    lock = lock(taskId);
    if (lock) {
        // 業(yè)務(wù)處理
    }
}catch(Exception e) {

}finally {
    if (lock) {
        relaseKey(taskId);
    }
}

上面的代碼會(huì)出現(xiàn)兩個(gè)問題

- 釋放鎖的代碼必須保持原子性低淡,否則在高并發(fā)的情況下會(huì)出現(xiàn)不可預(yù)知的問題姓言,不能保證鎖的互斥性
- 同一把鎖同一個(gè)時(shí)間內(nèi)可能會(huì)被其他的線程獲取到,并且由其他的線程來釋放鎖蔗蹋,不能保證鎖的安全性

2. 為了解決上述的問題事期,我們來優(yōu)化代碼,針對(duì)加鎖和釋放鎖都添加原子性操作纸颜,這樣單機(jī)版的redis環(huán)境就不會(huì)出現(xiàn)上述的問題了

Redis中支持一個(gè)語法 `SETEX key seconds value`, 該語法可以添加一個(gè)key,并且給這個(gè)key設(shè)置過期時(shí)間和value绎橘,為了達(dá)到誰加鎖胁孙,就讓誰來解鎖,
則我們可以將value設(shè)置成用戶的sessionId称鳞,并且在釋放鎖的時(shí)候確認(rèn)是否是對(duì)應(yīng)用戶進(jìn)行操作的涮较,
同時(shí)鑒于redis目前沒有針對(duì)這個(gè)業(yè)務(wù)提供具有原子性的操作指令,我們可以使用lua算法來實(shí)現(xiàn)鎖的釋放冈止,
完善后的偽代碼跟上述的代碼很像狂票,只是修改了加鎖和釋放鎖的操作,我們這里描述下lua算法:
if readdirSync.call('get', KEYS[1] == ARGV[1] then
    return redis.call('del', KEYS[1]);
else
    return 0;
end

該分布式鎖在單機(jī)版環(huán)境下能達(dá)到業(yè)務(wù)的需求熙暴,但是在Redis集群環(huán)境中闺属,由于Redis的主從復(fù)制時(shí)異步的,所以上述的方案在集群環(huán)境中還是有問題的

  1. Redis緩存和Mysql數(shù)據(jù)庫一致性的問題

在高并發(fā)的業(yè)務(wù)場景中周霉,一般都是先從緩存中讀取數(shù)據(jù)掂器,緩存中沒有的再從數(shù)據(jù)庫中讀取,并且寫入到緩存中俱箱,一般來說讀的情況還好国瓮,但是數(shù)據(jù)庫更新和緩存更新容易出現(xiàn)緩存和數(shù)據(jù)庫一致性的問題

不管是先寫數(shù)據(jù)庫,再刪除Redis緩存狞谱,還是先刪除緩存乃摹,再寫數(shù)據(jù)庫,都有可能出現(xiàn)數(shù)據(jù)不一致的問題

1. 如果先刪除緩存跟衅,還沒來得及寫入數(shù)據(jù)庫孵睬,此時(shí)又一個(gè)線程過來請(qǐng)求緩存了,發(fā)現(xiàn)緩存是空的伶跷,就會(huì)到數(shù)據(jù)庫中去請(qǐng)求肪康,此時(shí)緩存中的是臟數(shù)據(jù)

2. 如果先寫庫荚恶,在刪除緩存之前,寫庫的線程宕機(jī)了磷支,沒有刪除緩存谒撼,則此時(shí)緩存中的數(shù)據(jù)就和數(shù)據(jù)庫中的不一致

有兩種方案

  • 采用延時(shí)雙刪策略

在寫庫的前后都進(jìn)行redis.del(key)的操作,并且設(shè)定合理的超時(shí)時(shí)間
具體的操作步驟:

1. 先刪除緩存
2. 再寫數(shù)據(jù)庫
3. 休眠一段時(shí)間(具體時(shí)間由業(yè)務(wù)決定雾狈,考慮讀寫庫的時(shí)間)
4. 再次刪除緩存
5. 設(shè)置緩存超時(shí)

該方案的弊端:采用上述的方案廓潜,最差的情況下在超時(shí)時(shí)間內(nèi)數(shù)據(jù)是不一致的,而且增加了寫請(qǐng)求的耗時(shí)善榛,高并發(fā)的情況下對(duì)系統(tǒng)響應(yīng)造成一定的影響辩蛋。

  • 異步更新緩存(基于訂閱binlog的同步機(jī)制)

該方法的整體的思路如下:

MySql binlog增量訂閱消費(fèi)+消息隊(duì)列+增量數(shù)據(jù)更新到Redis

具體的流程如下:

mysql中一旦產(chǎn)生了新的寫入、更新移盆、刪除等操作悼院,就可以把binlog相關(guān)的消息推送至Redis,
Redis再根據(jù)binlog中的記錄咒循,對(duì)Redis進(jìn)行更新据途。其實(shí)這種機(jī)制,很類似MySQL的主從備份機(jī)制叙甸,
因?yàn)镸ySQL的主備也是通過binlog來實(shí)現(xiàn)的數(shù)據(jù)一致性颖医。
這里可以結(jié)合使用canal(阿里的一款開源框架),通過該框架可以對(duì)MySQL的binlog進(jìn)行訂閱裆蒸,
而canal正是模仿了mysql的slave數(shù)據(jù)庫的備份請(qǐng)求熔萧,使得Redis的數(shù)據(jù)更新達(dá)到了相同的效果。
當(dāng)然僚祷,這里的消息推送工具你也可以采用別的第三方:kafka佛致、rabbitMQ等來實(shí)現(xiàn)推送更新Redis。
  1. Redis為什么是單線程及高并發(fā)
  • redis是基于內(nèi)存的辙谜,內(nèi)存的讀寫速度非成谓埽快
  • 之所以設(shè)計(jì)為單線程,是為了減少上下文切換的時(shí)間
  • 使用多路復(fù)用技術(shù)筷弦,可以處理并發(fā)鏈接肋演,非阻塞IO,內(nèi)部實(shí)現(xiàn)epoll+自己實(shí)現(xiàn)的簡單的時(shí)間框架,將所有的請(qǐng)求轉(zhuǎn)化為事件烂琴,不在IO上花費(fèi)時(shí)間
  1. Redis的注意事項(xiàng)

實(shí)際生產(chǎn)活動(dòng)中redis的注意事項(xiàng):

1. Master最好不要做任何持久化工作爹殊,如RDB內(nèi)存快照和AOF日志文件
2. 如果數(shù)據(jù)比較重要,某個(gè)Slave開啟AOF備份數(shù)據(jù)奸绷,策略設(shè)置為每秒同步一次
3. 為了主從復(fù)制的速度和連接的穩(wěn)定性梗夸,Master和Slave最好在同一個(gè)局域網(wǎng)內(nèi)
4. 盡量避免在壓力很大的主庫上增加從庫
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市号醉,隨后出現(xiàn)的幾起案子反症,更是在濱河造成了極大的恐慌辛块,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铅碍,死亡現(xiàn)場離奇詭異润绵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)胞谈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門尘盼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人烦绳,你說我怎么就攤上這事卿捎。” “怎么了径密?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵午阵,是天一觀的道長。 經(jīng)常有香客問我享扔,道長底桂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任伪很,我火速辦了婚禮,結(jié)果婚禮上奋单,老公的妹妹穿的比我還像新娘锉试。我一直安慰自己,他們只是感情好览濒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布呆盖。 她就那樣靜靜地躺著,像睡著了一般贷笛。 火紅的嫁衣襯著肌膚如雪应又。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天乏苦,我揣著相機(jī)與錄音株扛,去河邊找鬼。 笑死汇荐,一個(gè)胖子當(dāng)著我的面吹牛洞就,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掀淘,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼旬蟋,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了革娄?” 一聲冷哼從身側(cè)響起倾贰,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤冕碟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后匆浙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體安寺,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年吞彤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了我衬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡饰恕,死狀恐怖挠羔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情埋嵌,我是刑警寧澤破加,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站雹嗦,受9級(jí)特大地震影響范舀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜了罪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一锭环、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泊藕,春花似錦辅辩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至讼呢,卻和暖如春撩鹿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背悦屏。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工节沦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人础爬。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓散劫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親幕帆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子获搏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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

  • Redis是單進(jìn)程單線程的,Redis利用隊(duì)列技術(shù)將并發(fā)訪問變?yōu)榇性L問,消除了傳統(tǒng)數(shù)據(jù)庫串行控制的開銷常熙。 Red...
    編輯小猿閱讀 313評(píng)論 0 0
  • 1.什么是redis? Redis 是一個(gè)基于內(nèi)存的高性能key-value數(shù)據(jù)庫纬乍。 2.Reids的特點(diǎn) Red...
    java成功之路閱讀 425評(píng)論 0 8
  • 作者:孤獨(dú)煙,本文版權(quán)歸作者和博客園所有編輯:陶家龍裸卫、孫淑娟(51CTO技術(shù)棧)出處:http://rjzheng...
    Allen丶Joe閱讀 2,460評(píng)論 0 10
  • 最好的愛情是兩個(gè)人彼此做個(gè)伴仿贬。 不要束縛,不要纏繞墓贿,不要占有茧泪, 不要渴望從對(duì)方身上挖掘到意義,那是注定要落空的東西...
    一夜落花閱讀 436評(píng)論 0 4
  • ?夜色很濃了聋袋,對(duì)于我和我的媽媽來說队伟,這個(gè)點(diǎn)睡覺是在正常不過,媽媽可能是收拾家務(wù)幽勒,看會(huì)電視嗜侮,長時(shí)間累積下來的習(xí)慣,而...
    亻亻卩卩玬刐閱讀 160評(píng)論 0 0