国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解

這篇具有很好參考價(jià)值的文章主要介紹了互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

目錄

一、Redis集群模型

1.1、主從模式

1.1.1 主從模式優(yōu)缺點(diǎn)

1.2、哨兵模式

1.2.1 哨兵模式的作用:

1.2.2 哨兵實(shí)現(xiàn)原理

1.2.3 主觀下線和客觀下線

1.2.4 哨兵模式優(yōu)缺點(diǎn)

1.3、各大廠的Redis集群方案

1.3.1 客戶端分片

1.3.2 代理分片

Twemproxy的優(yōu)點(diǎn):

Twemproxy的不足:

1.3.3 Codis

1.4、Redis Cluster

二.RDB持久化

2.1 RDB全量寫入

2.1.1 rdb原理

2.1.2?rdb模式

2.1.3?rdb觸發(fā)情況

2.1.4?rdb優(yōu)勢(shì)和劣勢(shì)

2.1.5?rdb文件配置

2.1.6?rdb命令配置

2.1.7?rdb數(shù)據(jù)恢復(fù)

2.2 AOF持久化:增量寫入

2.2.1aof原理

2.2.2 aof觸發(fā)情況

2.2.3 aof優(yōu)勢(shì)和劣勢(shì)

2.2.4 aof文件配置

2.2.5 aof命令配置

2.2.6 aof數(shù)據(jù)恢復(fù)

2.3.RDB&AOF對(duì)比

三、Redis高階

3.1 Redis高階之緩存擊穿

3.1.1 緩存擊穿定義

3.1.2?緩存擊穿產(chǎn)生原因

3.1.3?緩存擊穿解決方案

3.1.4?緩存擊穿解決方案之互斥鎖詳解

3.2 Redis高階之緩存穿透

3.2.1 緩存穿透定義

3.2.2?緩存穿透產(chǎn)生的原因

3.2.3?緩存穿透的三種解決方案

3.2.4?緩存穿透解決方案之布隆過濾器詳解

3.3 Redis高階之緩存雪崩

3.3.1?緩存雪奔定義

3.3.2?產(chǎn)生雪崩的原因

3.3.3 緩存雪崩的四種解決方案

3.3.4 緩存雪崩解決方案之加鎖限流詳解

Redis常見面試問題


Redis簡(jiǎn)介

Redis,英文全稱是Remote Dictionary Server(遠(yuǎn)程字典服務(wù)),是一個(gè)開源的使用ANSI C語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫(kù),并提供多種語言的API。

與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是redis會(huì)周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實(shí)現(xiàn)了master-slave(主從)同步。

與MySQL數(shù)據(jù)庫(kù)不同的是,Redis的數(shù)據(jù)是存在內(nèi)存中的。它的讀寫速度非常快,每秒可以處理超過10萬次讀寫操作。因此redis被廣泛應(yīng)用于緩存,另外,Redis也經(jīng)常用來做分布式鎖。除此之外,Redis支持事務(wù)、持久化、LUA 腳本、LRU 驅(qū)動(dòng)事件、多種集群方案。

Redis 是一個(gè)高性能的key-value數(shù)據(jù)庫(kù)。 redis的出現(xiàn),很大程度補(bǔ)償了memcached這類key/value存儲(chǔ)的不足,在部 分場(chǎng)合可以對(duì)關(guān)系數(shù)據(jù)庫(kù)起到很好的補(bǔ)充作用。

Redis支持主從同步。數(shù)據(jù)可以從主服務(wù)器向任意數(shù)量的從服務(wù)器上同步,從服務(wù)器可以是關(guān)聯(lián)其他從服務(wù)器的主服務(wù)器。

一、Redis集群模型

在服務(wù)開發(fā)中,單機(jī)都會(huì)存在單點(diǎn)故障的問題,及服務(wù)部署在一場(chǎng)臺(tái)服務(wù)器上,一旦服務(wù)器宕機(jī)服務(wù)就不可用,所以為了讓服務(wù)高可用,分布式服務(wù)就出現(xiàn)了,將同一服務(wù)部署到多臺(tái)機(jī)器上,即使其中幾臺(tái)服務(wù)器宕機(jī),只要有一臺(tái)服務(wù)器可用服務(wù)就可用。

redis也是一樣,為了解決單機(jī)故障引入了主從模式,但主從模式存在一個(gè)問題:master節(jié)點(diǎn)故障后服務(wù),需要人為的手動(dòng)將slave節(jié)點(diǎn)切換成為maser節(jié)點(diǎn)后服務(wù)才恢復(fù)。redis為解決這一問題又引入了哨兵模式,哨兵模式能在master節(jié)點(diǎn)故障后能自動(dòng)將salve節(jié)點(diǎn)提升成master節(jié)點(diǎn),不需要人工干預(yù)操作就能恢復(fù)服務(wù)可用。

但是主從模式、哨兵模式都沒有達(dá)到真正的數(shù)據(jù)sharding存儲(chǔ),每個(gè)redis實(shí)例中存儲(chǔ)的都是全量數(shù)據(jù),所以redis cluster就誕生了,實(shí)現(xiàn)了真正的數(shù)據(jù)分片存儲(chǔ)。但是由于redis cluster發(fā)布得比較晚(2015年才發(fā)布正式版 ),各大廠等不及了,陸陸續(xù)續(xù)開發(fā)了自己的redis數(shù)據(jù)分片集群模式,比如:Twemproxy、Codis等。

1.1、主從模式

redis單節(jié)點(diǎn)雖然有通過RDB和AOF持久化機(jī)制能將數(shù)據(jù)持久化到硬盤上,但數(shù)據(jù)是存儲(chǔ)在一臺(tái)服務(wù)器上的,如果服務(wù)器出現(xiàn)硬盤故障等問題,會(huì)導(dǎo)致數(shù)據(jù)不可用,而且讀寫無法分離,讀寫都在同一臺(tái)服務(wù)器上,請(qǐng)求量大時(shí)會(huì)出現(xiàn)I/O瓶頸。

為了避免單點(diǎn)故障 和 讀寫不分離,Redis 提供了復(fù)制(replication)功能實(shí)現(xiàn)master數(shù)據(jù)庫(kù)中的數(shù)據(jù)更新后,會(huì)自動(dòng)將更新的數(shù)據(jù)同步到其他slave數(shù)據(jù)庫(kù)上。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

如上redis主從結(jié)構(gòu)特點(diǎn):一個(gè)master可以有多個(gè)salve節(jié)點(diǎn);salve節(jié)點(diǎn)可以有slave節(jié)點(diǎn),從節(jié)點(diǎn)是級(jí)聯(lián)結(jié)構(gòu)。

1.1.1 主從模式優(yōu)缺點(diǎn)
  1. 優(yōu)點(diǎn): 主從結(jié)構(gòu)具有讀寫分離,提高效率、數(shù)據(jù)備份,提供多個(gè)副本等優(yōu)點(diǎn)。

  2. 不足: 最大的不足就是主從模式不具備自動(dòng)容錯(cuò)和恢復(fù)功能,主節(jié)點(diǎn)故障,集群則無法進(jìn)行工作,可用性比較低,從節(jié)點(diǎn)升主節(jié)點(diǎn)需要人工手動(dòng)干預(yù)。

普通的主從模式,當(dāng)主數(shù)據(jù)庫(kù)崩潰時(shí),需要手動(dòng)切換從數(shù)據(jù)庫(kù)成為主數(shù)據(jù)庫(kù):

  1. 在從數(shù)據(jù)庫(kù)中使用SLAVE NO ONE命令將從數(shù)據(jù)庫(kù)提升成主數(shù)據(jù)繼續(xù)服務(wù)。

  2. 啟動(dòng)之前崩潰的主數(shù)據(jù)庫(kù),然后使用SLAVEOF命令將其設(shè)置成新的主數(shù)據(jù)庫(kù)的從數(shù)據(jù)庫(kù),即可同步數(shù)據(jù)。

1.2、哨兵模式

第一種主從同步/復(fù)制的模式,當(dāng)主服務(wù)器宕機(jī)后,需要手動(dòng)把一臺(tái)從服務(wù)器切換為主服務(wù)器,這就需要人工干預(yù),費(fèi)事費(fèi)力,還會(huì)造成一段時(shí)間內(nèi)服務(wù)不可用,這時(shí)候就需要哨兵模式登場(chǎng)了。

哨兵模式是從Redis的2.6版本開始提供的,但是當(dāng)時(shí)這個(gè)版本的模式是不穩(wěn)定的,直到Redis的2.8版本以后,這個(gè)哨兵模式才穩(wěn)定下來。

哨兵模式核心還是主從復(fù)制,只不過在相對(duì)于主從模式在主節(jié)點(diǎn)宕機(jī)導(dǎo)致不可寫的情況下,多了一個(gè)競(jìng)選機(jī)制:從所有的從節(jié)點(diǎn)競(jìng)選出新的主節(jié)點(diǎn)。競(jìng)選機(jī)制的實(shí)現(xiàn),是依賴于在系統(tǒng)中啟動(dòng)一個(gè)sentinel進(jìn)程。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

如上圖,哨兵本身也有單點(diǎn)故障的問題,所以在一個(gè)一主多從的Redis系統(tǒng)中,可以使用多個(gè)哨兵進(jìn)行監(jiān)控,哨兵不僅會(huì)監(jiān)控主數(shù)據(jù)庫(kù)和從數(shù)據(jù)庫(kù),哨兵之間也會(huì)相互監(jiān)控。每一個(gè)哨兵都是一個(gè)獨(dú)立的進(jìn)程,作為進(jìn)程,它會(huì)獨(dú)立運(yùn)行。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

1.2.1 哨兵模式的作用:

監(jiān)控所有服務(wù)器是否正常運(yùn)行:通過發(fā)送命令返回監(jiān)控服務(wù)器的運(yùn)行狀態(tài),處理監(jiān)控主服務(wù)器、從服務(wù)器外,哨兵之間也相互監(jiān)控。

故障切換:當(dāng)哨兵監(jiān)測(cè)到master宕機(jī),會(huì)自動(dòng)將slave切換成master,然后通過發(fā)布訂閱模式通知其他的從服務(wù)器,修改配置文件,讓它們切換master。同時(shí)那臺(tái)有問題的舊主也會(huì)變?yōu)樾轮鞯膹模簿褪钦f當(dāng)舊的主即使恢復(fù)時(shí),并不會(huì)恢復(fù)原來的主身份,而是作為新主的一個(gè)從。

1.2.2 哨兵實(shí)現(xiàn)原理

哨兵在啟動(dòng)進(jìn)程時(shí),會(huì)讀取配置文件的內(nèi)容,通過如下的配置找出需要監(jiān)控的主數(shù)據(jù)庫(kù):

sentinel?monitor?master-name?ip?port?quorum
#master-name是主數(shù)據(jù)庫(kù)的名字
#ip和port?是當(dāng)前主數(shù)據(jù)庫(kù)地址和端口號(hào)
#quorum表示在執(zhí)行故障切換操作前,需要多少哨兵節(jié)點(diǎn)同意。

這里之所以只需要連接主節(jié)點(diǎn),是因?yàn)橥ㄟ^主節(jié)點(diǎn)的info命令,獲取從節(jié)點(diǎn)信息,從而和從節(jié)點(diǎn)也建立連接,同時(shí)也能通過主節(jié)點(diǎn)的info信息知道新增從節(jié)點(diǎn)的信息。

一個(gè)哨兵節(jié)點(diǎn)可以監(jiān)控多個(gè)主節(jié)點(diǎn),但是并不提倡這么做,因?yàn)楫?dāng)哨兵節(jié)點(diǎn)崩潰時(shí),同時(shí)有多個(gè)集群切換會(huì)發(fā)生故障。哨兵啟動(dòng)后,會(huì)與主數(shù)據(jù)庫(kù)建立兩條連接。

  1. 訂閱主數(shù)據(jù)庫(kù)_sentinel_:hello頻道以獲取同樣監(jiān)控該數(shù)據(jù)庫(kù)的哨兵節(jié)點(diǎn)信息

  2. 定期向主數(shù)據(jù)庫(kù)發(fā)送info命令,獲取主數(shù)據(jù)庫(kù)本身的信息。

跟主數(shù)據(jù)庫(kù)建立連接后會(huì)定時(shí)執(zhí)行以下三個(gè)操作:

(1)每隔10s向master和 slave發(fā)送info命令。作用是獲取當(dāng)前數(shù)據(jù)庫(kù)信息,比如發(fā)現(xiàn)新增從節(jié)點(diǎn)時(shí),會(huì)建立連接,并加入到監(jiān)控列表中,當(dāng)主從數(shù)據(jù)庫(kù)的角色發(fā)生變化進(jìn)行信息更新。

(2)每隔2s向主數(shù)據(jù)里和從數(shù)據(jù)庫(kù)的_sentinel_:hello頻道發(fā)送自己的信息。作用是將自己的監(jiān)控?cái)?shù)據(jù)和哨兵分享。每個(gè)哨兵會(huì)訂閱數(shù)據(jù)庫(kù)的_sentinel:hello頻道,當(dāng)其他哨兵收到消息后,會(huì)判斷該哨兵是不是新的哨兵,如果是則將其加入哨兵列表,并建立連接。

(3)每隔1s向所有主從節(jié)點(diǎn)和所有哨兵節(jié)點(diǎn)發(fā)送ping命令,作用是監(jiān)控節(jié)點(diǎn)是否存活。

1.2.3 主觀下線和客觀下線

哨兵節(jié)點(diǎn)發(fā)送ping命令時(shí),當(dāng)超過一定時(shí)間(down-after-millisecond)后,如果節(jié)點(diǎn)未回復(fù),則哨兵認(rèn)為主觀下線。主觀下線表示當(dāng)前哨兵認(rèn)為該節(jié)點(diǎn)已經(jīng)下面,如果該節(jié)點(diǎn)為主數(shù)據(jù)庫(kù),哨兵會(huì)進(jìn)一步判斷是夠需要對(duì)其進(jìn)行故障切換,這時(shí)候就要發(fā)送命令(SENTINEL is-master-down-by-addr)詢問其他哨兵節(jié)點(diǎn)是否認(rèn)為該主節(jié)點(diǎn)是主觀下線,當(dāng)達(dá)到指定數(shù)量(quorum)時(shí),哨兵就會(huì)認(rèn)為是客觀下線。

當(dāng)主節(jié)點(diǎn)客觀下線時(shí)就需要進(jìn)行主從切換,主從切換的步驟為:

  • 選出領(lǐng)頭哨兵。

  • 領(lǐng)頭哨兵所有的slave選出優(yōu)先級(jí)最高的從數(shù)據(jù)庫(kù)。優(yōu)先級(jí)可以通過slave-priority選項(xiàng)設(shè)置。

  • 如果優(yōu)先級(jí)相同,則從復(fù)制的命令偏移量越大(即復(fù)制同步數(shù)據(jù)越多,數(shù)據(jù)越新),越優(yōu)先。

  • 如果以上條件都一樣,則選擇run ID較小的從數(shù)據(jù)庫(kù)。

選出一個(gè)從數(shù)據(jù)庫(kù)后,哨兵發(fā)送slave no one命令升級(jí)為主數(shù)據(jù)庫(kù),并發(fā)送slaveof命令將其他從節(jié)點(diǎn)的主數(shù)據(jù)庫(kù)設(shè)置為新的主數(shù)據(jù)庫(kù)。

1.2.4 哨兵模式優(yōu)缺點(diǎn)

1.優(yōu)點(diǎn)

  • 哨兵模式是基于主從模式的,解決可主從模式中master故障不可以自動(dòng)切換故障的問題。

2.不足-問題

  • 是一種中心化的集群實(shí)現(xiàn)方案:始終只有一個(gè)Redis主機(jī)來接收和處理寫請(qǐng)求,寫操作受單機(jī)瓶頸影響。

  • 集群里所有節(jié)點(diǎn)保存的都是全量數(shù)據(jù),浪費(fèi)內(nèi)存空間,沒有真正實(shí)現(xiàn)分布式存儲(chǔ)。數(shù)據(jù)量過大時(shí),主從同步嚴(yán)重影響master的性能。

  • Redis主機(jī)宕機(jī)后,哨兵模式正在投票選舉的情況之外,因?yàn)橥镀边x舉結(jié)束之前,誰也不知道主機(jī)和從機(jī)是誰,此時(shí)Redis也會(huì)開啟保護(hù)機(jī)制,禁止寫操作,直到選舉出了新的Redis主機(jī)。

主從模式或哨兵模式每個(gè)節(jié)點(diǎn)存儲(chǔ)的數(shù)據(jù)都是全量的數(shù)據(jù),數(shù)據(jù)量過大時(shí),就需要對(duì)存儲(chǔ)的數(shù)據(jù)進(jìn)行分片后存儲(chǔ)到多個(gè)redis實(shí)例上。此時(shí)就要用到Redis Sharding技術(shù)。

1.3、各大廠的Redis集群方案

Redis在3.0版本前只支持單實(shí)例模式,雖然Redis的開發(fā)者Antirez早在博客上就提出在Redis 3.0版本中加入集群的功能,但3.0版本等到2015年才發(fā)布正式版。各大企業(yè)等不急了,在3.0版本還沒發(fā)布前為了解決Redis的存儲(chǔ)瓶頸,紛紛推出了各自的Redis集群方案。這些方案的核心思想是把數(shù)據(jù)分片(sharding)存儲(chǔ)在多個(gè)Redis實(shí)例中,每一片就是一個(gè)Redis實(shí)例。

1.3.1 客戶端分片

客戶端分片是把分片的邏輯放在Redis客戶端實(shí)現(xiàn),(比如:jedis已支持Redis Sharding功能,即ShardedJedis),通過Redis客戶端預(yù)先定義好的路由規(guī)則(使用一致性哈希),把對(duì)Key的訪問轉(zhuǎn)發(fā)到不同的Redis實(shí)例中,查詢數(shù)據(jù)時(shí)把返回結(jié)果匯集。這種方案的模式如圖所示。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

客戶端分片的優(yōu)缺點(diǎn):

優(yōu)點(diǎn):客戶端sharding技術(shù)使用hash一致性算法分片的好處是所有的邏輯都是可控的,不依賴于第三方分布式中間件。服務(wù)端的Redis實(shí)例彼此獨(dú)立,相互無關(guān)聯(lián),每個(gè)Redis實(shí)例像單服務(wù)器一樣運(yùn)行,非常容易線性擴(kuò)展,系統(tǒng)的靈活性很強(qiáng)。開發(fā)人員清楚怎么實(shí)現(xiàn)分片、路由的規(guī)則,不用擔(dān)心踩坑。

1.一致性哈希算法:

是分布式系統(tǒng)中常用的算法。比如,一個(gè)分布式的存儲(chǔ)系統(tǒng),要將數(shù)據(jù)存儲(chǔ)到具體的節(jié)點(diǎn)上,如果采用普通的hash方法,將數(shù)據(jù)映射到具體的節(jié)點(diǎn)上,如mod(key,d),key是數(shù)據(jù)的key,d是機(jī)器節(jié)點(diǎn)數(shù),如果有一個(gè)機(jī)器加入或退出這個(gè)集群,則所有的數(shù)據(jù)映射都無效了。

一致性哈希算法解決了普通余數(shù)Hash算法伸縮性差的問題,可以保證在上線、下線服務(wù)器的情況下盡量有多的請(qǐng)求命中原來路由到的服務(wù)器。

2.實(shí)現(xiàn)方式:一致性hash算法,比如MURMUR_HASH散列算法、ketamahash算法

比如Jedis的Redis Sharding實(shí)現(xiàn),采用一致性哈希算法(consistent hashing),將key和節(jié)點(diǎn)name同時(shí)hashing,然后進(jìn)行映射匹配,采用的算法是MURMUR_HASH。

采用一致性哈希而不是采用簡(jiǎn)單類似哈希求模映射的主要原因是當(dāng)增加或減少節(jié)點(diǎn)時(shí),不會(huì)產(chǎn)生由于重新匹配造成的rehashing。一致性哈希只影響相鄰節(jié)點(diǎn)key分配,影響量小。

不足:

  • 這是一種靜態(tài)的分片方案,需要增加或者減少Redis實(shí)例的數(shù)量,需要手工調(diào)整分片的程序。

  • 運(yùn)維成本比較高,集群的數(shù)據(jù)出了任何問題都需要運(yùn)維人員和開發(fā)人員一起合作,減緩了解決問題的速度,增加了跨部門溝通的成本。

  • 在不同的客戶端程序中,維護(hù)相同的路由分片邏輯成本巨大。比如:java項(xiàng)目、PHP項(xiàng)目里共用一套R(shí)edis集群,路由分片邏輯分別需要寫兩套一樣的邏輯,以后維護(hù)也是兩套。

客戶端分片有一個(gè)最大的問題就是,服務(wù)端Redis實(shí)例群拓?fù)浣Y(jié)構(gòu)有變化時(shí),每個(gè)客戶端都需要更新調(diào)整。如果能把客戶端分片模塊單獨(dú)拎出來,形成一個(gè)單獨(dú)的模塊(中間件),作為客戶端 和 服務(wù)端連接的橋梁就能解決這個(gè)問題了,此時(shí)代理分片就出現(xiàn)了。

1.3.2 代理分片

redis代理分片用得最多的就是Twemproxy,由Twitter開源的Redis代理,其基本原理是:通過中間件的形式,Redis客戶端把請(qǐng)求發(fā)送到Twemproxy,Twemproxy根據(jù)路由規(guī)則發(fā)送到正確的Redis實(shí)例,最后Twemproxy把結(jié)果匯集返回給客戶端。

Twemproxy通過引入一個(gè)代理層,將多個(gè)Redis實(shí)例進(jìn)行統(tǒng)一管理,使Redis客戶端只需要在Twemproxy上進(jìn)行操作,而不需要關(guān)心后面有多少個(gè)Redis實(shí)例,從而實(shí)現(xiàn)了Redis集群。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

Twemproxy的優(yōu)點(diǎn):
  • 客戶端像連接Redis實(shí)例一樣連接Twemproxy,不需要改任何的代碼邏輯。

  • 支持無效Redis實(shí)例的自動(dòng)刪除。

  • Twemproxy與Redis實(shí)例保持連接,減少了客戶端與Redis實(shí)例的連接數(shù)。

Twemproxy的不足:
  • 由于Redis客戶端的每個(gè)請(qǐng)求都經(jīng)過Twemproxy代理才能到達(dá)Redis服務(wù)器,這個(gè)過程中會(huì)產(chǎn)生性能損失。

  • 沒有友好的監(jiān)控管理后臺(tái)界面,不利于運(yùn)維監(jiān)控。

  • Twemproxy最大的痛點(diǎn)在于,無法平滑地?cái)U(kuò)容/縮容。對(duì)于運(yùn)維人員來說,當(dāng)因?yàn)闃I(yè)務(wù)需要增加Redis實(shí)例時(shí)工作量非常大。

Twemproxy作為最被廣泛使用、最久經(jīng)考驗(yàn)、穩(wěn)定性最高的Redis代理,在業(yè)界被廣泛使用。

1.3.3 Codis

Twemproxy不能平滑增加Redis實(shí)例的問題帶來了很大的不便,于是豌豆莢自主研發(fā)了Codis,一個(gè)支持平滑增加Redis實(shí)例的Redis代理軟件,其基于Go和C語言開發(fā),并于2014年11月在GitHub上開源。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

在Codis的架構(gòu)圖中,Codis引入了Redis Server Group,其通過指定一個(gè)主CodisRedis和一個(gè)或多個(gè)從CodisRedis,實(shí)現(xiàn)了Redis集群的高可用。當(dāng)一個(gè)主CodisRedis掛掉時(shí),Codis不會(huì)自動(dòng)把一個(gè)從CodisRedis提升為主CodisRedis,這涉及數(shù)據(jù)的一致性問題(Redis本身的數(shù)據(jù)同步是采用主從異步復(fù)制,當(dāng)數(shù)據(jù)在主CodisRedis寫入成功時(shí),從CodisRedis是否已讀入這個(gè)數(shù)據(jù)是沒法保證的),需要管理員在管理界面上手動(dòng)把從CodisRedis提升為主CodisRedis。

如果手動(dòng)處理覺得麻煩,豌豆莢也提供了一個(gè)工具Codis-ha,這個(gè)工具會(huì)在檢測(cè)到主CodisRedis掛掉的時(shí)候?qū)⑵湎戮€并提升一個(gè)從CodisRedis為主CodisRedis。

Codis中采用預(yù)分片的形式,啟動(dòng)的時(shí)候就創(chuàng)建了1024個(gè)slot,1個(gè)slot相當(dāng)于1個(gè)箱子,每個(gè)箱子有固定的編號(hào),范圍是1~1024。slot這個(gè)箱子用作存放Key,至于Key存放到哪個(gè)箱子,可以通過算法“crc32(key)%1024”獲得一個(gè)數(shù)字,這個(gè)數(shù)字的范圍一定是1~1024之間,Key就放到這個(gè)數(shù)字對(duì)應(yīng)的slot。

例如,如果某個(gè)Key通過算法“crc32(key)%1024”得到的數(shù)字是5,就放到編碼為5的slot(箱子)。1個(gè)slot只能放1個(gè)Redis Server Group,不能把1個(gè)slot放到多個(gè)Redis Server Group中。1個(gè)Redis Server Group最少可以存放1個(gè)slot,最大可以存放1024個(gè)slot。因此,Codis中最多可以指定1024個(gè)Redis Server Group

Codis最大的優(yōu)勢(shì)在于支持平滑增加(減少)Redis Server Group(Redis實(shí)例),能安全、透明地遷移數(shù)據(jù),這也是Codis 有別于Twemproxy等靜態(tài)分布式 Redis 解決方案的地方。Codis增加了Redis Server Group后,就牽涉到slot的遷移問題。

例如,系統(tǒng)有兩個(gè)Redis Server Group,Redis Server Group和slot的對(duì)應(yīng)關(guān)系如下。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

當(dāng)增加了一個(gè)Redis Server Group,slot就要重新分配了。Codis分配slot有兩種方法:

第一種:通過Codis管理工具Codisconfig手動(dòng)重新分配,指定每個(gè)Redis Server Group所對(duì)應(yīng)的slot的范圍,例如:可以指定Redis Server Group和slot的新的對(duì)應(yīng)關(guān)系如下。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

第二種:通過Codis管理工具Codisconfig的rebalance功能,會(huì)自動(dòng)根據(jù)每個(gè)Redis Server Group的內(nèi)存對(duì)slot進(jìn)行遷移,以實(shí)現(xiàn)數(shù)據(jù)的均衡。

1.4、Redis Cluster

Redis 的哨兵模式雖然已經(jīng)可以實(shí)現(xiàn)高可用,讀寫分離 ,但是存在幾個(gè)方面的不足:

  • 哨兵模式下每臺(tái) Redis 服務(wù)器都存儲(chǔ)相同的數(shù)據(jù),很浪費(fèi)內(nèi)存空間;數(shù)據(jù)量太大,主從同步時(shí)嚴(yán)重影響了master性能。

  • 哨兵模式是中心化的集群實(shí)現(xiàn)方案,每個(gè)從機(jī)和主機(jī)的耦合度很高,master宕機(jī)到salve選舉master恢復(fù)期間服務(wù)不可用。

  • 哨兵模式始終只有一個(gè)Redis主機(jī)來接收和處理寫請(qǐng)求,寫操作還是受單機(jī)瓶頸影響,沒有實(shí)現(xiàn)真正的分布式架構(gòu)。

redis在3.0上加入了 Cluster 集群模式,實(shí)現(xiàn)了 Redis 的分布式存儲(chǔ),也就是說每臺(tái) Redis 節(jié)點(diǎn)上存儲(chǔ)不同的數(shù)據(jù)。cluster模式為了解決單機(jī)Redis容量有限的問題,將數(shù)據(jù)按一定的規(guī)則分配到多臺(tái)機(jī)器,內(nèi)存/QPS不受限于單機(jī),可受益于分布式集群高擴(kuò)展性。

Redis Cluster是一種服務(wù)器Sharding技術(shù)(分片和路由都是在服務(wù)端實(shí)現(xiàn)),采用多主多從,每一個(gè)分區(qū)都是由一個(gè)Redis主機(jī)和多個(gè)從機(jī)組成,片區(qū)和片區(qū)之間是相互平行的。Redis Cluster集群采用了P2P的模式,完全去中心化。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

如上圖,官方推薦,集群部署至少要 3 臺(tái)以上的master節(jié)點(diǎn),最好使用 3 主 3 從六個(gè)節(jié)點(diǎn)的模式。Redis Cluster集群具有如下幾個(gè)特點(diǎn):

  • 集群完全去中心化,采用多主多從;所有的redis節(jié)點(diǎn)彼此互聯(lián)(PING-PONG機(jī)制),內(nèi)部使用二進(jìn)制協(xié)議優(yōu)化傳輸速度和帶寬。

  • 客戶端與 Redis 節(jié)點(diǎn)直連,不需要中間代理層??蛻舳瞬恍枰B接集群所有節(jié)點(diǎn),連接集群中任何一個(gè)可用節(jié)點(diǎn)即可。

  • 每一個(gè)分區(qū)都是由一個(gè)Redis主機(jī)和多個(gè)從機(jī)組成,分片和分片之間是相互平行的。

  • 每一個(gè)master節(jié)點(diǎn)負(fù)責(zé)維護(hù)一部分槽,以及槽所映射的鍵值數(shù)據(jù);集群中每個(gè)節(jié)點(diǎn)都有全量的槽信息,通過槽每個(gè)node都知道具體數(shù)據(jù)存儲(chǔ)到哪個(gè)node上。

redis cluster主要是針對(duì)海量數(shù)據(jù)+高并發(fā)+高可用的場(chǎng)景,海量數(shù)據(jù),如果你的數(shù)據(jù)量很大,那么建議就用redis cluster,數(shù)據(jù)量不是很大時(shí),使用sentinel就夠了。redis cluster的性能和高可用性均優(yōu)于哨兵模式。

Redis Cluster采用虛擬哈希槽分區(qū)而非一致性hash算法,預(yù)先分配一些卡槽,所有的鍵根據(jù)哈希函數(shù)映射到這些槽內(nèi),每一個(gè)分區(qū)內(nèi)的master節(jié)點(diǎn)負(fù)責(zé)維護(hù)一部分槽以及槽所映射的鍵值數(shù)據(jù)。

二.RDB持久化

2.1 RDB全量寫入

2.1.1 rdb原理

RDB持久化是把當(dāng)前進(jìn)程數(shù)據(jù)生成快照保存到硬盤的過程,觸發(fā)RDB持久化過程分為手動(dòng)觸發(fā)和自動(dòng)觸發(fā)

過程:

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

  • 1)執(zhí)行bgsave命令,Redis父進(jìn)程判斷當(dāng)前是否存在正在執(zhí)行的子進(jìn)程,如RDB/AOF子進(jìn)程,如果存在bgsave命令直接返回。
  • 2)父進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程,fork操作過程中父進(jìn)程會(huì)阻塞,通過info stats命令查看latest_fork_usec選項(xiàng),可以獲取最近一個(gè)fork操作的耗時(shí),單位為微秒。
  • 3)父進(jìn)程fork完成后,bgsave命令返回“Background saving started”信息并不再阻塞父進(jìn)程,可以繼續(xù)響應(yīng)其他命令。
  • 4)子進(jìn)程創(chuàng)建RDB文件,根據(jù)父進(jìn)程內(nèi)存生成臨時(shí)快照文件,完成后對(duì)原有文件進(jìn)行原子替換 執(zhí)行l(wèi)astsave命令可以獲取最后一次生成RDB的時(shí)間,對(duì)應(yīng)info統(tǒng)計(jì)的rdb_last_save_time選項(xiàng)。
  • 5)進(jìn)程發(fā)送信號(hào)給父進(jìn)程表示完成,父進(jìn)程更新統(tǒng)計(jì)信息,具體見info Persistence下的rdb_*相關(guān)選項(xiàng)。

2.1.2?rdb模式

SAVE 阻塞式的RDB持久化,當(dāng)執(zhí)行這個(gè)命令時(shí)間時(shí)rdis的主進(jìn)程把內(nèi)存里的數(shù)據(jù)庫(kù)狀態(tài)寫入到rdb文件中,直到該文件創(chuàng)建完畢的這段時(shí)間內(nèi)redis講不能處理任何命令請(qǐng)求

BGSAVE 非阻塞式的持久化,它會(huì)創(chuàng)建一個(gè)子進(jìn)程,專門去把內(nèi)存中的數(shù)據(jù)庫(kù)狀態(tài)寫入RDB文件,同時(shí)主進(jìn)程還可以處理來自客戶端的請(qǐng)求命令,但子進(jìn)程基本是復(fù)制父進(jìn)程,這等于兩個(gè)相同大小的redis進(jìn)程在系統(tǒng)上運(yùn)行,會(huì)造成內(nèi)存使用率的大幅增加。

2.1.3?rdb觸發(fā)情況

1.手動(dòng)執(zhí)行bgsave或save命令 2.根據(jù)配置文件的save選項(xiàng)自動(dòng)觸發(fā) 3.主從結(jié)構(gòu)時(shí),從節(jié)點(diǎn)執(zhí)行全量復(fù)制操作,主節(jié)點(diǎn)自動(dòng)執(zhí)行,將生成的RDB文件發(fā)送給從 4.執(zhí)行debug reload命令重新加載Redis時(shí) 5.默認(rèn)情況下執(zhí)行shutdown命令關(guān)閉redis時(shí),如果沒有開啟AOF持久化功能則自動(dòng)執(zhí)行

2.1.4?rdb優(yōu)勢(shì)和劣勢(shì)

優(yōu)勢(shì):

  • 一旦采用該方式,那么你的整個(gè)Redis數(shù)據(jù)庫(kù)將只包含一個(gè)文件,這對(duì)可以定時(shí)每天可以備份出一個(gè)整個(gè)的數(shù)據(jù)文件。
  • 對(duì)于災(zāi)難恢復(fù)而言,RDB是非常不錯(cuò)的選擇。因?yàn)槲覀兛梢苑浅]p松的將一個(gè)單獨(dú)的文件壓縮后再轉(zhuǎn)移到其它存儲(chǔ)介質(zhì)上。
  • 相比于AOF機(jī)制,如果數(shù)據(jù)集很大,RDB的啟動(dòng)效率會(huì)更高。

劣勢(shì):

  • 由于RDB是通過fork子進(jìn)程來協(xié)助完成數(shù)據(jù)持久化工作的,因此,如果當(dāng)數(shù)據(jù)集較大時(shí),可能會(huì)導(dǎo)致整個(gè)服務(wù)器停止服務(wù)幾百毫秒,甚至是1秒鐘。
  • RDB文件使用特定二進(jìn)制格式保存,Redis版本演進(jìn)過程中有多個(gè)格式的RDB版本,存在老版本Redis服務(wù)無法兼容新版RDB格式的問題。
2.1.5?rdb文件配置

redis.conf文件

#注釋所有save行則停止rdb持久化

#900秒(15分鐘)內(nèi)至少1個(gè)key值改變(則進(jìn)行數(shù)據(jù)庫(kù)保存--持久化)

save 900 1

#300秒(5分鐘)內(nèi)至少10個(gè)key值改變(則進(jìn)行數(shù)據(jù)庫(kù)保存--持久化)

save 300 10
#60秒(1分鐘)內(nèi)至少10000個(gè)key值改變(則進(jìn)行數(shù)據(jù)庫(kù)保存--持久化)

save 60 10000
#當(dāng)RDB持久化出現(xiàn)錯(cuò)誤后,再寫入數(shù)據(jù)會(huì)報(bào)錯(cuò),用于提示用戶出問題了。

#yes是開啟,no是關(guān)閉,默認(rèn)開啟

stop-writes-on-bgsave-error yes
#是否壓縮rdb文件,rdb文件壓縮使用LZF壓縮算法,壓縮會(huì)消耗一些cpu,不壓縮文件會(huì)很大

#yes開啟,no關(guān)閉,默認(rèn)開啟

rdbcompression yes
#使用CRC64算法來進(jìn)行數(shù)據(jù)校驗(yàn),防止RDB是錯(cuò)誤的,但是這樣做會(huì)增加大約10%的性能消耗

#yes開啟,no關(guān)閉,默認(rèn)開啟

rdbchecksum yes

復(fù)制

2.1.6?rdb命令配置

阻塞當(dāng)前Redis服務(wù)器 直到RDB過程完成為止,對(duì)于內(nèi)存比較大的實(shí)例會(huì)造成長(zhǎng)時(shí)間阻塞,線上環(huán)境不建議使用。 save

Redis進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程,RDB持久化過程由子進(jìn)程負(fù)責(zé),完成后自動(dòng)結(jié)束。阻塞只發(fā)生在fork階段,一般時(shí)間很短。 bgsave

查看latest_fork_usec選項(xiàng),可以獲取最近一個(gè)fork操作的耗時(shí),單位為微秒。 info stats

2.1.7?rdb數(shù)據(jù)恢復(fù)

1.將RDB備份放到配置文件指定的數(shù)據(jù)目錄下,啟動(dòng)redis將會(huì)自動(dòng)恢復(fù)。加載期間將會(huì)阻塞,無法進(jìn)行其它操作。

2.上述方法不行,或者恢復(fù)的集群,可以使用redis-migrate-tool工具進(jìn)行恢復(fù)。

2.2 AOF持久化:增量寫入

2.2.1aof原理

以獨(dú)立日志的方式記錄每次寫命令,重啟時(shí)再重新執(zhí)行AOF文件中的命令達(dá)到恢復(fù)數(shù)據(jù)的目的。AOF的主要作用是解決了數(shù)據(jù)持久化的實(shí)時(shí)性,目前已經(jīng)是Redis持久化的主流方式。

寫入的數(shù)據(jù)具有可讀性,同步時(shí)先寫入緩沖區(qū),再放入硬盤。如果直接寫入硬盤,性能將取決于磁盤負(fù)載,并且放到緩沖區(qū),可以提供各種同步策略。

過程:

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

  • 1)所有的寫入命令會(huì)追加到aof_buf(緩沖區(qū))中。
  • 2)AOF緩沖區(qū)根據(jù)對(duì)應(yīng)的策略向硬盤做同步操作。
  • 3)隨著AOF文件越來越大,需要定期對(duì)AOF文件進(jìn)行重寫,達(dá)到壓縮的目的。
  • 4)當(dāng)Redis服務(wù)器重啟時(shí),可以加載AOF文件進(jìn)行數(shù)據(jù)恢復(fù)。
2.2.2 aof觸發(fā)情況

1.根據(jù)配置文件自動(dòng)觸發(fā)

2.2.3 aof優(yōu)勢(shì)和劣勢(shì)

優(yōu)勢(shì):

  • 該機(jī)制可以帶來更高的數(shù)據(jù)安全性,即數(shù)據(jù)持久性。根據(jù)策略不同,從而對(duì)數(shù)據(jù)安全性不同,可以在性能和安全區(qū)選擇一個(gè)。
  • 由于該機(jī)制對(duì)日志文件的寫入操作采用的是append模式,因此在寫入過程中即使出現(xiàn)宕機(jī)現(xiàn)象,也不會(huì)破壞日志文件中已經(jīng)存在的內(nèi)容。
  • 如果日志過大,將自動(dòng)啟用rewrite機(jī)制。以append模式不斷的將修改數(shù)據(jù)寫入到老的磁盤文件中,同時(shí)還會(huì)創(chuàng)建一個(gè)新的文件用于記錄此期間有哪些修改命令被執(zhí)行,保證安全性。
  • AOF包含一個(gè)格式清晰、易于理解的日志文件用于記錄所有的修改操作。事實(shí)上,我們也可以通過該文件完成數(shù)據(jù)的重建。

劣勢(shì):

  • 對(duì)于相同數(shù)量的數(shù)據(jù)集而言,AOF文件通常要大于RDB文件。RDB 在恢復(fù)大數(shù)據(jù)集時(shí)的速度比 AOF 的恢復(fù)速度要快。
  • 根據(jù)同步策略的不同,AOF在運(yùn)行效率上往往會(huì)慢于RDB??傊?,每秒同步策略的效率是比較高的,同步禁用策略的效率和RDB一樣高效。
2.2.4 aof文件配置

在Redis的配置文件中存在三種同步方式,它們分別是:

#是否開啟aof持久化。默認(rèn)no,要打開

appendonly yes

#位置

appendfilename "appendonly.aof"

#每次有數(shù)據(jù)修改發(fā)生時(shí)都會(huì)寫入AOF文件

#命令寫入aof_buf后調(diào)用系統(tǒng)fsync操作同步AOF文件,fsync完成后線程返回

appendfsync always

#每秒鐘同步一次,該策略為AOF的缺省策略

#命令寫入aof_buf后調(diào)用系統(tǒng)write操作,write完成后線程返回。fsync同步文件操作由專門線程每秒調(diào)用一次

#這個(gè)模式兼顧了效率的同時(shí)也保證了數(shù)據(jù)的完整性,即使在服務(wù)器宕機(jī)也只會(huì)丟失一秒內(nèi)對(duì)redis數(shù)據(jù)庫(kù)做的修改

appendfsync everysec

#不加入緩沖區(qū),直接寫到硬盤,速度最快,不安全

#命令寫入aof_buf后調(diào)用系統(tǒng)write操作,不對(duì)aof文件做fsync同步,同步硬盤操作由操作系統(tǒng)負(fù)責(zé),通常同步周期最長(zhǎng)30秒

#這種模式下效率是最快的,但對(duì)數(shù)據(jù)來說也是最不安全的,如果redis里的數(shù)據(jù)都是從后臺(tái)數(shù)據(jù)庫(kù)如mysql中取出來的,屬于隨時(shí)可以找回或者不重要的數(shù)據(jù),那么可以考慮設(shè)置成這種模式。

appendfsync no

復(fù)制

2.2.5 aof命令配置

aof文件重寫手動(dòng)觸發(fā) bgrewriteaof

aof文件重寫自動(dòng)觸發(fā),配置文件

#新的aof文件大小是上次的aof文件的大小2倍(100)時(shí),進(jìn)行重寫

auto-aof-rewrite-percentage 100

#表示運(yùn)行AOF重寫時(shí)文件最小體積, 默認(rèn)為64MB

auto-aof-rewrite-min-size 64mb

復(fù)制

2.2.6 aof數(shù)據(jù)恢復(fù)
  • 將AOF備份放到配置文件指定的數(shù)據(jù)目錄下,啟動(dòng)redis將會(huì)自動(dòng)恢復(fù)。加載期間將會(huì)阻塞,無法進(jìn)行其它操作。
  • 上述方法不行,或者恢復(fù)的集群,可以使用redis-migrate-tool工具進(jìn)行恢復(fù)。
  • 可以使用pipline方式批量硬寫入,但效率會(huì)低

2.3.RDB&AOF對(duì)比

二者選擇的標(biāo)準(zhǔn),就是看系統(tǒng)是愿意犧牲一些性能,換取更高的緩存一致性(aof),還是愿意寫操作頻繁的時(shí)候,不啟用備份來換取更高的性能,待手動(dòng)運(yùn)行save的時(shí)候,再做備份(rdb)。

啟動(dòng)加載流程:

  • AOF持久化開啟且存在AOF文件時(shí), 優(yōu)先加載AOF文件
  • AOF關(guān)閉或者AOF文件不存在時(shí), 加載RDB文件
  • 加載AOF/RDB文件成功后, Redis啟動(dòng)成功
  • AOF/RDB文件存在錯(cuò)誤時(shí), Redis啟動(dòng)失敗并打印錯(cuò)誤信息

三、Redis高階

3.1 Redis高階之緩存擊穿

3.1.1 緩存擊穿定義

緩存擊穿,是指緩存中沒有但數(shù)據(jù)庫(kù)中有的數(shù)據(jù),并且某一個(gè)key非常熱點(diǎn),在不停的扛著大并發(fā),大并發(fā)集中對(duì)這一個(gè)點(diǎn)進(jìn)行訪問,當(dāng)這個(gè)key在失效的瞬間(一般是緩存時(shí)間到期),持續(xù)的大并發(fā)就穿破緩存,直接請(qǐng)求數(shù)據(jù)庫(kù),就像在一個(gè)屏障上鑿開了一個(gè)洞。

緩存擊穿看著有點(diǎn)像,其實(shí)它兩區(qū)別是,緩存雪奔是指數(shù)據(jù)庫(kù)壓力過大甚至down機(jī),緩存擊穿只是大量并發(fā)請(qǐng)求到了DB數(shù)據(jù)庫(kù)層面??梢哉J(rèn)為擊穿是緩存雪奔的一個(gè)子集吧。有些文章認(rèn)為它倆區(qū)別,是區(qū)別在于擊穿針對(duì)某一熱點(diǎn)key緩存,雪奔則是很多key。

3.1.2?緩存擊穿產(chǎn)生原因

可以看成緩存雪崩的一個(gè)特殊子集。

比如xxx塌房哩、xxx商品活動(dòng),這時(shí)候大量用戶都在訪問該熱點(diǎn)事件,但是可能優(yōu)于某種原因,redis的這個(gè)熱點(diǎn)key過期了,那么這時(shí)候大量高并發(fā)對(duì)于該key的請(qǐng)求就得不到redis的響應(yīng),那么就會(huì)將請(qǐng)求直接打在DB服務(wù)器上,導(dǎo)致整個(gè)DB癱瘓。

3.1.3?緩存擊穿解決方案
  1. 使用互斥鎖方案。緩存失效時(shí),不是立即去加載db數(shù)據(jù),而是先使用某些帶成功返回的原子操作命令,如(Redis的setnx)去操作,成功的時(shí)候,再去加載db數(shù)據(jù)庫(kù)數(shù)據(jù)和設(shè)置緩存。否則就去重試獲取緩存。
  2. ?“永不過期”,是指沒有設(shè)置過期時(shí)間,但是熱點(diǎn)數(shù)據(jù)快要過期時(shí),異步線程去更新和設(shè)置過期時(shí)間。
3.1.4?緩存擊穿解決方案之互斥鎖詳解

業(yè)界比較常用的做法,是使用mutex。簡(jiǎn)單地來說,就是在緩存失效的時(shí)候(判斷拿出來的值為空),不是立即去load db,而是先使用緩存工具的某些帶成功操作返回值的操作(比如Redis的SETNX或者M(jìn)emcache的ADD)去set一個(gè)mutex key,當(dāng)操作返回成功時(shí),再進(jìn)行l(wèi)oad db的操作并回設(shè)緩存;否則,就重試整個(gè)get緩存的方法。

SETNX,是「SET if Not eXists」的縮寫,也就是只有不存在的時(shí)候才設(shè)置,可以利用它來實(shí)現(xiàn)鎖的效果。

public String get(key) {
      String value = redis.get(key);
      if (value == null) { //代表緩存值過期
          //設(shè)置3min的超時(shí),防止del操作失敗的時(shí)候,下次緩存過期一直不能load db
      		if (redis.setnx(key_mutex, 1, 3 * 60) == 1) {  //代表設(shè)置成功
               value = db.get(key);
               redis.set(key, value, expire_secs);
               redis.del(key_mutex);
          } else {  //這個(gè)時(shí)候代表同時(shí)候的其他線程已經(jīng)load db并回設(shè)到緩存了,這時(shí)候重試獲取緩存值即可
               sleep(50);
               get(key);  //重試
              }
      } else {
          return value;      
   }
 }

3.2 Redis高階之緩存穿透

3.2.1 緩存穿透定義

緩存穿透是指查詢一個(gè)數(shù)據(jù)庫(kù)一定不存在的數(shù)據(jù)。正常的使用緩存流程大致是,數(shù)據(jù)查詢先進(jìn)行緩存查詢,如果key不存在或者key已經(jīng)過期,再對(duì)數(shù)據(jù)庫(kù)進(jìn)行查詢,并把查詢到的對(duì)象,放進(jìn)緩存。如果數(shù)據(jù)庫(kù)查詢對(duì)象為空,則不放進(jìn)緩存。

這里需要注意緩存擊穿的區(qū)別,緩存擊穿,緩存擊穿是指緩存中沒有但數(shù)據(jù)庫(kù)中有的數(shù)據(jù),并且某一個(gè)key非常熱點(diǎn),在不停的扛著大并發(fā),大并發(fā)集中對(duì)這一個(gè)點(diǎn)進(jìn)行訪問,當(dāng)這個(gè)key在失效的瞬間(一般是緩存時(shí)間到期),持續(xù)的大并發(fā)就穿破緩存,直接請(qǐng)求數(shù)據(jù)庫(kù),就像在一個(gè)屏障上鑿開了一個(gè)洞。

通俗點(diǎn)說,讀請(qǐng)求訪問時(shí),緩存和數(shù)據(jù)庫(kù)都沒有某個(gè)值,這樣就會(huì)導(dǎo)致每次對(duì)這個(gè)值的查詢請(qǐng)求都會(huì)穿透到數(shù)據(jù)庫(kù),這就是緩存穿透。

3.2.2?緩存穿透產(chǎn)生的原因
  1. 業(yè)務(wù)不合理的設(shè)計(jì),比如大多數(shù)用戶都沒開守護(hù),但是你的每個(gè)請(qǐng)求都去緩存,查詢某個(gè)userid查詢有沒有守護(hù)。
  2. 業(yè)務(wù)/運(yùn)維/開發(fā)失誤的操作,比如緩存和數(shù)據(jù)庫(kù)的數(shù)據(jù)都被誤刪除了。
  3. 黑客非法請(qǐng)求攻擊,比如黑客故意捏造大量非法請(qǐng)求,以讀取不存在的業(yè)務(wù)數(shù)據(jù)。
3.2.3?緩存穿透的三種解決方案
  1. 如果是非法請(qǐng)求,我們?cè)贏PI入口,對(duì)參數(shù)進(jìn)行校驗(yàn),過濾非法值。
  2. 如果查詢數(shù)據(jù)庫(kù)為空,我們可以給緩存設(shè)置個(gè)空值,或者默認(rèn)值。但是如有有寫請(qǐng)求進(jìn)來的話,需要更新緩存哈,以保證緩存一致性,同時(shí),最后給緩存設(shè)置適當(dāng)?shù)倪^期時(shí)間。(業(yè)務(wù)上比較常用,簡(jiǎn)單有效)
  3. 使用布隆過濾器快速判斷數(shù)據(jù)是否存在。即一個(gè)查詢請(qǐng)求過來時(shí),先通過布隆過濾器判斷值是否存在,存在才繼續(xù)往下查。

布隆過濾器原理:它由初始值為0的位圖數(shù)組和N個(gè)哈希函數(shù)組成。一個(gè)對(duì)一個(gè)key進(jìn)行N個(gè)hash算法獲取N個(gè)值,在比特?cái)?shù)組中將這N個(gè)值散列后設(shè)定為1,然后查的時(shí)候如果特定的這幾個(gè)位置都為1,那么布隆過濾器判斷該key存在。

3.2.4?緩存穿透解決方案之布隆過濾器詳解

布隆過濾器是一個(gè)bit向量或者bit,如果我們要映射一個(gè)值到布隆過濾器中,我們使用多個(gè)不同的哈希函數(shù)生成多個(gè)哈希值,并將每個(gè)生成的哈希值指向的bit位設(shè)置為1,如下baidu一詞設(shè)置了三個(gè)位置為1。

原理:對(duì)一個(gè)key進(jìn)行k個(gè)hash算法獲取k個(gè)值,在比特?cái)?shù)組中將這k個(gè)值散列后設(shè)定為1,然后查的時(shí)候如果特定的這幾個(gè)位置都為1,那么布隆過濾器判斷該key存在。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

“tencent”一詞,對(duì)應(yīng)的情況

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化


可以看到,不同的詞對(duì)應(yīng)的bit位置可能相同,當(dāng)詞很多的情況時(shí),可能大部分bit位置都是1,這時(shí)查詢taobao可能對(duì)應(yīng)的位置都為1,只能說明taobao一詞可能存在,不是一定存在的,這時(shí)1就被覆蓋了,這就是布隆過濾器的誤判。如果它說不存在那肯定不存在,如果它說存在,那數(shù)據(jù)有可能實(shí)際不存在。

Redis的bitmap只支持2^32大小,對(duì)應(yīng)到內(nèi)存也就是512MB,誤判率萬分之一,可以放下2億左右的數(shù)據(jù),性能高,空間占用率及小,省去了大量無效的數(shù)據(jù)庫(kù)連接。

因此我們可以通過布隆過濾器,將Redis緩存穿透控制在一個(gè)可容范圍內(nèi)。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

使用布隆過濾器:
導(dǎo)入依賴

<dependency>
     <groupId>com.google.guava</groupId>
     <artifactId>guava</artifactId>
     <version>19.0</version>
</dependency>

代碼:

public class Test {

    private static int size = 1000000;//預(yù)計(jì)要插入多少數(shù)據(jù)

    private static double fpp = 0.01;//期望的誤判率

    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, fpp);

    public static void main(String[] args) {
        //插入數(shù)據(jù)
        for (int i = 0; i < 1000000; i++) {
            bloomFilter.put(i);
        }
        int count = 0;
        for (int i = 1000000; i < 2000000; i++) {
            if (bloomFilter.mightContain(i)) {
                count++;
                System.out.println(i + "誤判了");
            }
        }
        System.out.println("總共的誤判數(shù):" + count);
    }
}

應(yīng)用:

@Cacheable(value="key1")
public String get(String key) {
    String value = redis.get(key);  
    // redis中不存在該緩存
    if (value  == null) {
    //布隆過濾器也沒有,直接返回
        if(!bloomfilter.mightContain(key)){
            return null; 
        }else{
            //布隆過濾器中能查到,不代表一定有,查出來放入redis,同樣也可以避免緩存穿透
            value = db.get(key);
            redis.set(key, value); 
        }    
    }
    return value;
}

(2)、緩存空對(duì)象
當(dāng)存儲(chǔ)層不命中后,即使返回的空對(duì)象也將其緩存起來,同時(shí)會(huì)設(shè)置一個(gè)過期時(shí)間,之后再訪問這個(gè)數(shù)據(jù)將會(huì)從緩存中獲取,保護(hù)了后端數(shù)據(jù)源。

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化


但是這種方法會(huì)存在兩個(gè)問題:

● 如果空值能夠被緩存起來,這就意味著緩存需要更多的空間存儲(chǔ)更多的鍵,因?yàn)檫@當(dāng)中可能會(huì)有很多的空值的鍵;

● 即使對(duì)空值設(shè)置了過期時(shí)間,還是會(huì)存在緩存層和存儲(chǔ)層的數(shù)據(jù)會(huì)有一段時(shí)間窗口的不一致,這對(duì)于需要保持一致性的業(yè)務(wù)會(huì)有影響

3.3 Redis高階之緩存雪崩

3.3.1?緩存雪奔定義

?指緩存中數(shù)據(jù)大批量到過期時(shí)間,而查詢數(shù)據(jù)量巨大,請(qǐng)求都直接訪問數(shù)據(jù)庫(kù),引起數(shù)據(jù)庫(kù)壓力過大甚至down機(jī)。

  1. 緩存雪奔一般是由于大量數(shù)據(jù)同時(shí)過期造成的,對(duì)于這個(gè)原因,可通過均勻設(shè)置過期時(shí)間解決,即讓過期時(shí)間相對(duì)離散一點(diǎn)。如采用一個(gè)較大固定值+一個(gè)較小的隨機(jī)值,5小時(shí)+0到1800秒醬紫。
  2. Redis 故障宕機(jī)也可能引起緩存雪奔。這就需要構(gòu)造Redis高可用集群啦。
3.3.2?產(chǎn)生雪崩的原因

假如馬上就要到雙十一零點(diǎn),很快就會(huì)迎來一波搶購(gòu),這波商品時(shí)間比較集中的放入了緩存,假設(shè)緩存一個(gè)小時(shí)。那么到了凌晨一點(diǎn)鐘的時(shí)候,這批商品的緩存就都過期了。而對(duì)這批商品的訪問查詢,都落到了數(shù)據(jù)庫(kù)上,對(duì)于數(shù)據(jù)庫(kù)而言,就會(huì)產(chǎn)生周期性的壓力波峰。

3.3.3 緩存雪崩的四種解決方案
  1. 采取不同分類商品,緩存不同周期。在同一分類中的商品,加上一個(gè)隨機(jī)因子。這樣能盡可能分散緩存過期時(shí)間,而且,熱門類目的商品緩存時(shí)間長(zhǎng)一些,冷門類目的商品緩存時(shí)間短一些,也能節(jié)省緩存服務(wù)的資源。
  2. 如果緩存數(shù)據(jù)庫(kù)是分布式部署,將 熱點(diǎn)數(shù)據(jù)均勻分布在不同的緩存數(shù)據(jù)庫(kù)中。
  3. 設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期。
  4. 使用加鎖限流的方式。
3.3.4 緩存雪崩解決方案之加鎖限流詳解

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

Redis常見面試問題

互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解,互聯(lián)網(wǎng)大廠技術(shù),redis架構(gòu),緩存擊穿,redis,cluster,持久化

Redis有哪些特性?

  1. 性能高, 讀的速度是100000次/s,寫的速度是80000次/s;
  2. 數(shù)據(jù)持久化,支持RDB 、AOF;
  3. 支持事務(wù)。通過MULTI和EXEC指令包起來;
  4. 多種數(shù)據(jù)結(jié)構(gòu)類型;
  5. 主從復(fù)制;
  6. 其他特性:發(fā)布/訂閱、通知、key過期等;

Redis為什么這么快?

  1. 完全基于內(nèi)存,沒有磁盤IO上的開銷,異步持久化除外
  2. 單線程,避免多個(gè)線程切換的性能損耗
  3. 非阻塞的IO多路復(fù)用機(jī)制
  4. 底層的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)優(yōu)化,使用原生的數(shù)據(jù)結(jié)構(gòu)提升性能。

Redis底層的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)有哪些?

  1. 字符串。沒有采用C語言的傳統(tǒng)字符串,而是自己實(shí)現(xiàn)的一個(gè)簡(jiǎn)單動(dòng)態(tài)字符串SDS的抽象類型,并保存了?度
  2. 信息。
  3. 鏈表(linkedlist)。雙向無環(huán)鏈表結(jié)構(gòu),每個(gè)鏈表的節(jié)點(diǎn)由一個(gè)listNode結(jié)構(gòu)來表示,每個(gè)節(jié)點(diǎn)都有前置和
  4. 后置節(jié)點(diǎn)的指針
  5. 字典(hashtable)。保存鍵值對(duì)的抽象數(shù)據(jù)結(jié)構(gòu),底層使用hash表,每個(gè)字典帶有兩個(gè)hash表,供平時(shí)使
  6. 用和rehash時(shí)使用。
  7. 跳躍表(skiplist)。跳躍表是有序集合的底層實(shí)現(xiàn)之一。redis跳躍表由zskiplist和zskiplistNode組成,
  8. zskiplist用于保存跳躍表 信息(表頭、表尾節(jié)點(diǎn)、?度等),zskiplistNode用于表示表跳躍節(jié)點(diǎn),每個(gè)跳躍表的
  9. 層高都是1- 32的隨機(jī)數(shù),在同一個(gè)跳躍表中,多個(gè)節(jié)點(diǎn)可以包含相同的分值,但是每個(gè)節(jié)點(diǎn)的成員對(duì)象必須
  10. 是唯一的,節(jié)點(diǎn)按照分值大小排序,如果分值相同,則按照成員對(duì)象的大小排序。
  11. 整數(shù)集合(intset)。用于保存整數(shù)值的集合抽象數(shù)據(jù)結(jié)構(gòu),不會(huì)出現(xiàn)重復(fù)元素,底層實(shí)現(xiàn)為數(shù)組。
  12. 壓縮列表(ziplist)。為節(jié)約內(nèi)存而開發(fā)的順序性數(shù)據(jù)結(jié)構(gòu),可以包含多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)可以保存一個(gè)字節(jié)
  13. 數(shù)組或者整數(shù)值。

Redis支持哪些數(shù)據(jù)類型?

  1. 五種常用數(shù)據(jù)類型:String、Hash、Set、List、SortedSet。
  2. 三種特殊的數(shù)據(jù)類型:Bitmap、HyperLogLog、Geospatial,其中Bitmap 、HyperLogLog的底層都是 String 數(shù)據(jù)類型,Geospatial 底層是 Sorted Set 數(shù)據(jù)類型;
  3. 字符串對(duì)象string:int整數(shù)、embstr編碼的簡(jiǎn)單動(dòng)態(tài)字符串、raw簡(jiǎn)單動(dòng)態(tài)字符串
  4. 列表對(duì)象list:ziplist、linkedlist
  5. 哈希對(duì)象hash:ziplist、hashtable
  6. 集合對(duì)象set:intset、hashtable
  7. 有序集合對(duì)象zset:ziplist、skiplist

Redis常用的5種數(shù)據(jù)結(jié)構(gòu)和應(yīng)用場(chǎng)景?

  1. String:緩存、計(jì)數(shù)器、分布式鎖等
  2. List:鏈表、隊(duì)列、微博關(guān)注人時(shí)間軸列表等
  3. Hash:用戶信息、Hash 表等
  4. Set:去重、贊、踩、共同好友等
  5. Zset:訪問量排行榜、點(diǎn)擊量排行榜等

Redis為什么采用單線程?
官方回復(fù),CPU不會(huì)成為Redis的制約瓶頸,Redis主要受內(nèi)存、網(wǎng)絡(luò)限制。

例如,在一個(gè)普通的 Linux 系統(tǒng)上,使用pipelining 可以每秒傳遞 100 萬個(gè)請(qǐng)求,所以如果您的應(yīng)用程序主要使用 O(N) 或 O(log(N)) 命令,則幾乎不會(huì)使用太多 CPU,屬于IO密集型系統(tǒng)。

Redis6.0之后又改用多線程呢
Redis的多線程主要是處理數(shù)據(jù)的讀寫、協(xié)議解析。執(zhí)行命令還是采用單線程順序執(zhí)行。
主要是因?yàn)閞edis的性能瓶頸在于網(wǎng)絡(luò)IO而非CPU,使用多線程進(jìn)行一些周邊預(yù)處理,提升了IO的讀寫效率,從而提高了整體的吞吐量。antirez 在 RedisConf 2019 分享時(shí)提到,Redis 6 引入的多線程 IO 對(duì)性能提升至少一倍以上。

Redis過期鍵Key 的刪除策略有哪些?
有3種過期刪除策略。惰性刪除、定期刪除、定時(shí)刪除

  1. 惰性刪除:使用key時(shí)才進(jìn)行檢查,如果已經(jīng)過期,則刪除,缺點(diǎn):過期的key如果沒有被訪問到,一直無法刪除,一直占用內(nèi)存,造成空間浪費(fèi)。
  2. 定期刪除:每隔一段時(shí)間做一次檢查,刪除過期的key,每次只是隨機(jī)取一些key去檢查。
  3. 定時(shí)刪除:為每個(gè)key設(shè)置過期時(shí)間,同時(shí)創(chuàng)建一個(gè)定時(shí)器。一旦到期,立即執(zhí)行刪除。缺點(diǎn):如果過期鍵比較多時(shí),占用CPU較多,對(duì)服務(wù)的性能有很大影響。

如果Redis的內(nèi)存空間不足,淘汰機(jī)制?

  1. volatile-lru:從已設(shè)置過期時(shí)間的key中,移出最近最少使用的key進(jìn)行淘汰
  2. allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,移除最近最少使用的key(這個(gè)是最常用的)
  3. volatile-ttl:從已設(shè)置過期時(shí)間的key中,移出將要過期的key
  4. volatile-random:從已設(shè)置過期時(shí)間的key中,隨機(jī)選擇key淘汰
  5. allkeys-random:從key中隨機(jī)選擇key進(jìn)行淘汰
  6. no-eviction:禁止淘汰數(shù)據(jù)。當(dāng)內(nèi)存達(dá)到閾值的時(shí)候,新寫入操作報(bào)錯(cuò)
  7. volatile-lfu:從已設(shè)置過期時(shí)間的數(shù)據(jù)集(server.db[i].expires)中挑選最不經(jīng)常使用的數(shù)據(jù)淘汰(LFU(Least
  8. Frequently Used)算法,也就是最頻繁被訪問的數(shù)據(jù)將來最有可能被訪問到)
  9. allkeys-lfu:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時(shí),在鍵空間中,移除最不經(jīng)常使用的key。

Redis突然掛了怎么解決?

  1. 從系統(tǒng)可用性?度思考,Redis Cluster引入主備機(jī)制,當(dāng)主節(jié)點(diǎn)掛了后,自動(dòng)切換到備用節(jié)點(diǎn),繼續(xù)提供服務(wù)。
  2. Client端引入本地緩存,通過開關(guān)切換,避免Redis突然掛掉,高并發(fā)流量把數(shù)據(jù)庫(kù)打掛。?

Redis持久化有哪些方式?

  1. 快照RDB。將某個(gè)時(shí)間點(diǎn)上的數(shù)據(jù)庫(kù)狀態(tài)保存到 RDB文件 中,RDB文件是一個(gè)壓縮的二進(jìn)制文件,保存在磁盤上。當(dāng)Redis崩潰時(shí),可用于恢復(fù)數(shù)據(jù)。通過 SAVE 或 BGSAVE 來生成RDB文件。
    1. SAVE:會(huì)阻塞redis進(jìn)程,直到RDB文件創(chuàng)建完畢,在進(jìn)程阻塞期間,redis不能處理任何命令請(qǐng)求。
    2. BGSAVE:會(huì)fork出一個(gè)子進(jìn)程,然后由子進(jìn)程去負(fù)責(zé)生成RDB文件,父進(jìn)程還可以繼續(xù)處理命令請(qǐng)求,不會(huì)阻塞進(jìn)程。
  2. 只追加文件AOF。以日志的形式記錄每個(gè)寫操作(非讀操作)。當(dāng)不同節(jié)點(diǎn)同步數(shù)據(jù)時(shí),讀取日志文件的內(nèi)容將寫指令從前到后執(zhí)行一次,即可完成數(shù)據(jù)恢復(fù)。

Redis常用場(chǎng)景

  1. 緩存,有句話說的好,「性能不夠,緩存來湊」
  2. 分布式鎖,利用Redis 的 setnx
  3. 分布式session
  4. 計(jì)數(shù)器,通過incr命令
  5. 排行榜,Redis 的 有序集合
  6. 其他

Redis 緩存要注意的七大經(jīng)典問題?
列舉了億級(jí)系統(tǒng),高訪問量情況下Redis緩存可能會(huì)遇到哪些問題?以及對(duì)應(yīng)的解決方案。

  1. 緩存集中失效
  2. 緩存穿透
  3. 緩存雪崩
  4. 緩存熱點(diǎn)
  5. 緩存大Key
  6. 緩存數(shù)據(jù)的一致性
  7. 數(shù)據(jù)并發(fā)競(jìng)爭(zhēng)預(yù)熱

Redis集群方案有哪幾種?

  1. 主從復(fù)制模式
  2. Sentinel(哨兵)模式
  3. Redis Cluster 模式

Redis主從數(shù)據(jù)同步(主從復(fù)制)的過程?

  1. slave啟動(dòng)后,向master發(fā)送sync命令
  2. master收到sync之后,執(zhí)行bgsave保存快照,生成RDB全量文件
  3. master把slave的寫命令記錄到緩存
  4. bgsave執(zhí)行完畢之后,發(fā)送RDB文件到slave,slave執(zhí)行
  5. master發(fā)送緩沖區(qū)的寫命令給slave,slave接收命令并執(zhí)行,完成復(fù)制初始化。
  6. 此后,master每次執(zhí)行一個(gè)寫命令都會(huì)同步發(fā)送給slave,保持master與slave之間數(shù)據(jù)的一致性

Redis主從復(fù)制的優(yōu)缺點(diǎn)?

  1. 1、優(yōu)點(diǎn):master能自動(dòng)將數(shù)據(jù)同步到slave,可以進(jìn)行讀寫分離,分擔(dān)master的讀壓力master、slave之間的同步是以非阻塞的方式進(jìn)行的,同步期間,客戶端仍然可以提交查詢或更新請(qǐng)求
  2. 缺點(diǎn):不具備自動(dòng)容錯(cuò)與恢復(fù)功能,master 節(jié)點(diǎn)宕機(jī)后,需要手動(dòng)指定新的 master,master宕機(jī),如果宕機(jī)前數(shù)據(jù)沒有同步完,則切換IP后會(huì)存在數(shù)據(jù)不一致的問題,難以支持在線擴(kuò)容,Redis的容量受限于單機(jī)配置

Redis Sentinel(哨兵)模式的優(yōu)缺點(diǎn)?
哨兵模式基于主從復(fù)制模式,增加了哨兵來監(jiān)控與自動(dòng)處理故障。

  1. 優(yōu)點(diǎn):哨兵模式基于主從復(fù)制模式,所以主從復(fù)制模式有的優(yōu)點(diǎn),哨兵模式也有master 掛掉可以自動(dòng)進(jìn)行切換,系統(tǒng)可用性更高
  2. 缺點(diǎn):Redis的容量受限于單機(jī)配置需要額外的資源來啟動(dòng)sentinel進(jìn)程

Redis Cluster 模式的優(yōu)缺點(diǎn)?
實(shí)現(xiàn)了Redis的分布式存儲(chǔ),即每臺(tái)節(jié)點(diǎn)存儲(chǔ)不同的內(nèi)容,來解決在線擴(kuò)容的問題。

  1. 優(yōu)點(diǎn):
    1. 無中心架構(gòu),數(shù)據(jù)按照slot分布在多個(gè)節(jié)點(diǎn)
    2. 集群中的每個(gè)節(jié)點(diǎn)都是平等的,每個(gè)節(jié)點(diǎn)都保存各自的數(shù)據(jù)和整個(gè)集群的狀態(tài)。
    3. 每個(gè)節(jié)點(diǎn)都和其他所有節(jié)點(diǎn)連接,而且這些連接保持活躍,這樣就保證了我們只需要連接集群中的任意一個(gè)節(jié)點(diǎn),就可以獲取到其他節(jié)點(diǎn)的數(shù)據(jù)。
    4. 可線性擴(kuò)展到1000多個(gè)節(jié)點(diǎn),節(jié)點(diǎn)可動(dòng)態(tài)添加或刪除。
    5. 能夠?qū)崿F(xiàn)自動(dòng)故障轉(zhuǎn)移,節(jié)點(diǎn)之間通過gossip協(xié)議交換狀態(tài)信息,用投票機(jī)制完成slave到master的?色轉(zhuǎn)換。
  2. 缺點(diǎn):
    1. 數(shù)據(jù)通過異步復(fù)制,不保證數(shù)據(jù)的強(qiáng)一致性。
    2. slave充當(dāng) “冷備”,不對(duì)外提供讀、寫服務(wù),只作為故障轉(zhuǎn)移使用。
    3. 批量操作限制,目前只支持具有相同slot值的key執(zhí)行批量操作,對(duì)mset、mget、sunion等操作支持不友好
    4. key事務(wù)操作支持有限,只支持多key在同一節(jié)點(diǎn)的事務(wù)操作,多key分布在不同節(jié)點(diǎn)時(shí)無法使用事務(wù)功能
    5. 不支持多數(shù)據(jù)庫(kù)空間,一臺(tái)redis可以支持16個(gè)db,集群模式下只能使用一個(gè),即db0 。
    6. Redis Cluster模式不建議使用pipeline和multi-keys操作,減少max redirect產(chǎn)生的場(chǎng)景。

Redis 如何做擴(kuò)容?
為了避免數(shù)據(jù)遷移失效,通常使用一致性哈希 實(shí)現(xiàn)動(dòng)態(tài)擴(kuò)容縮容,有效減少需要遷移的Key數(shù)量。
但是Cluster 模式,采用固定Slot槽位方式(16384個(gè)),對(duì)每個(gè)key計(jì)算CRC16值,然后對(duì)16384取模,然后根據(jù)slot值找到目標(biāo)機(jī)器,擴(kuò)容時(shí),我們只需要遷移一部分的slot到新節(jié)點(diǎn)即可。

Redis的集群原理?
一個(gè)redis集群由多個(gè)節(jié)點(diǎn)node組成,而多個(gè)node之間通過 cluster meet命令來進(jìn)行連接,組成一個(gè)集群。
數(shù)據(jù)存儲(chǔ)通過分片的形式,整個(gè)集群分成了16384個(gè)slot,每個(gè)節(jié)點(diǎn)負(fù)責(zé)一部分槽位。整個(gè)槽位的信息會(huì)同步到所有節(jié)點(diǎn)中。
key與slot的映射關(guān)系:健值對(duì) key,進(jìn)行 CRC16 計(jì)算,計(jì)算出一個(gè)16bit的值,將16bit的值對(duì)16384取模,得到0~16383的數(shù)表示 key 對(duì)應(yīng)的哈希槽

Redis 如何做到高可用?
哨兵機(jī)制。具有自動(dòng)故障轉(zhuǎn)移、集群監(jiān)控、消息通知等功能。
哨兵可以同時(shí)監(jiān)視所有的主、從服務(wù)器,當(dāng)某個(gè)master下線時(shí),自動(dòng)提升對(duì)應(yīng)的slave為master,然后由新master對(duì)外提供服務(wù)。

什么是Redis 事務(wù)?
Redis事務(wù)是一組命令的集合,將多個(gè)命令打包,然后把這些命令按順序添加到隊(duì)列中,并且按順序執(zhí)行這些命令。
Redis事務(wù)中沒有像Mysql關(guān)系型數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別的概念,不能保證原子性操作,也沒有像Mysql那樣執(zhí)行事務(wù)失敗會(huì)進(jìn)行回滾操作

Redis事務(wù)執(zhí)行流程?
通過MULTI 、EXEC、WATCH等命令來實(shí)現(xiàn)事務(wù)機(jī)制,事務(wù)執(zhí)行過程將一系列多個(gè)命令按照順序一次性執(zhí)行,在執(zhí)行期間,事務(wù)不會(huì)被中斷,也不會(huì)去執(zhí)行客戶端的其他請(qǐng)求,直到所有命令執(zhí)行完畢。
具體過程:服務(wù)端收到客戶端請(qǐng)求,事務(wù)以MULTI 開始如果正處于事務(wù)狀態(tài)時(shí),則會(huì)把后續(xù)命令放入隊(duì)列同時(shí)返回給客戶端 QUEUED ,反之則直接執(zhí)行這個(gè)命令
當(dāng)收到客戶端的EXEC命令時(shí),才會(huì)將隊(duì)列里的命令取出、順序執(zhí)行,執(zhí)行完將當(dāng)前狀態(tài)從事務(wù)狀態(tài)改為非事務(wù)狀態(tài)
如果收到DISCARD命令,放棄執(zhí)行隊(duì)列中的命令,可以理解為Mysql的回滾操作,并且將當(dāng)前的狀態(tài)從事務(wù)狀態(tài)改為非事務(wù)狀態(tài)
WATCH 監(jiān)視某個(gè)key,該命令只能在MULTI命令之前執(zhí)行。如果監(jiān)視的key被其他客戶端修改,EXEC將會(huì)放棄執(zhí)行隊(duì)列中的所有命令。 UNWATCH 取消監(jiān)視之前通過WATCH 命令監(jiān)視的key。通過執(zhí)行EXEC、DISCARD 兩個(gè)命令之前監(jiān)視的key也會(huì)被取消監(jiān)視。

Redis與Guava、Caffeine 有什么區(qū)別?
緩存分為本地緩存和分布式緩存。

  1. Caffeine、Guava,屬于本地緩存,特點(diǎn):
    1. 直接訪問內(nèi)存,速度快,受內(nèi)存限制,無法進(jìn)行大數(shù)據(jù)存儲(chǔ)。
    2. 無網(wǎng)絡(luò)通訊開銷,性能更高。
    3. 只支持本地應(yīng)用進(jìn)程訪問,同步更新所有節(jié)點(diǎn)的本地緩存數(shù)據(jù)成本較高。
    4. 應(yīng)用進(jìn)程重啟,數(shù)據(jù)會(huì)丟失。
    5. 所以,本地緩存適合存儲(chǔ)一些不易改變或者低頻改變的高熱點(diǎn)數(shù)據(jù)。
  2. Redis屬于分布式緩存,特點(diǎn):
    1. 集群模式,支持大數(shù)據(jù)量存儲(chǔ)
    2. 數(shù)據(jù)集中存儲(chǔ),保證數(shù)據(jù)的一致性
    3. 數(shù)據(jù)跨網(wǎng)絡(luò)傳輸,性能低于本地緩存。但同一個(gè)機(jī)房,兩臺(tái)服務(wù)器之間請(qǐng)求跑一個(gè)來回也就需要500微秒,比
    4. 起其優(yōu)勢(shì),這點(diǎn)損耗完全可以忽略,這也是分布式緩存受歡迎的原因。
    5. 支持副本機(jī)制,有效的保證了高可用性。


如何實(shí)現(xiàn)一個(gè)分布式鎖?文章來源地址http://www.zghlxwxcb.cn/news/detail-570394.html

  1. 數(shù)據(jù)庫(kù)表,性能比較差
  2. 使用Lua腳本 (包含 SETNX + EXPIRE 兩條指令)
  3. SET的擴(kuò)展命令(SET key value [EX][PX] [NX|XX])
  4. Redlock 框架
  5. Zookeeper Curator 框架提供了現(xiàn)成的分布式

到了這里,關(guān)于互聯(lián)網(wǎng)大廠技術(shù)-Redis-集群模型、架構(gòu)原理、難點(diǎn)應(yīng)用場(chǎng)景、高頻面試問題詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包