Redis 知識(shí)總結(jié)
在公眾號(hào)后臺(tái)回復(fù):JGNB,可獲取杰哥原創(chuàng)的 PDF 手冊(cè)。
1. Redis 概覽
Redis 和 memcache 的區(qū)別,Redis 支持的數(shù)據(jù)類型應(yīng)用場(chǎng)景
redis 支持的數(shù)據(jù)結(jié)構(gòu)更豐富(string,hash,list,set,zset)。memcache 只支持 key-value 的存儲(chǔ);
redis 原生支持集群,memcache 沒有原生的集群模式。
2. Redis 單線程模型
redis 單線程處理請(qǐng)求流程
redis 采用 IO 多路復(fù)用機(jī)制來(lái)處理請(qǐng)求,采用 reactor IO 模型, 處理流程如下:
首先接收到客戶端的 socket 請(qǐng)求,多路復(fù)用器將 socket 轉(zhuǎn)給連接應(yīng)答處理器;
連接應(yīng)答處理器將 AE_READABLE 事件與命令請(qǐng)求處理器關(guān)聯(lián)(這里是把 socket 事件放入一個(gè)隊(duì)列);
命令請(qǐng)求處理器從 socket 中讀到指令,再內(nèi)存中執(zhí)行,并將 AE_WRITEABLE 事件與命令回復(fù)處理器關(guān)聯(lián);
命令回復(fù)處理器將結(jié)果返回給 socket,并解除關(guān)聯(lián)。

redis 單線程效率高的原因
非阻塞 IO 復(fù)用(上圖流程), I/O 多路復(fù)用分派事件,事件處理器處理事件(這個(gè)可以理解為注冊(cè)的一段函數(shù),定義了事件發(fā)生的時(shí)候應(yīng)該執(zhí)行的動(dòng)作), 這里分派事件和處理事件其實(shí)都是同一個(gè)線程;
純內(nèi)存操作效率高;
單線程反而避免了多線程切換。
3. Redis 過期策略
對(duì) key 設(shè)置有效期,redis 的刪除策略: 定期刪除+惰性刪除。
定期刪除指的是 redis 默認(rèn)每 100ms 就隨機(jī)抽取一些設(shè)置了過期事件的 key ,檢查是否過期,如果過期就刪除。如果 redis 設(shè)置了 10 萬(wàn)個(gè) key 都設(shè)置了過期時(shí)間,每隔幾百毫秒就要檢查 10 萬(wàn)個(gè) key 那 CPU 負(fù)載就很高了,所以 redis 并不會(huì)每隔 100ms 就檢查所有的 key,而是隨機(jī)抽取一些 key 來(lái)檢查。
但這樣會(huì)導(dǎo)致有些 key 過期了并沒有被刪除,所以采取了惰性刪除。意思是在獲取某個(gè) key 的時(shí)候發(fā)現(xiàn)過期了,如果 key 過期了就刪除掉不會(huì)返回。
這兩個(gè)策略結(jié)合起來(lái)保證過期的 key 一定會(huì)被刪除。
最大內(nèi)存淘汰(maxmemory-policy)
如果 redis 內(nèi)存占用太多,就會(huì)進(jìn)行內(nèi)存淘汰。有如下策略:
noeviction: 如果內(nèi)存不足以寫入數(shù)據(jù), 新寫入操作直接報(bào)錯(cuò);
allkeys-lru: 內(nèi)存不足以寫入數(shù)據(jù),移除最近最少使用的 key(最常用的策略);
allkeys-random: 內(nèi)存不足隨機(jī)移除幾個(gè) key;
volatile-lru: 在設(shè)置了過期時(shí)間的 key 中,移除最近最少使用;
volatile-random: 設(shè)置了過期的時(shí)間的 key 中,隨機(jī)移除幾個(gè)。
4. Redis 主從模式保證高并發(fā)和高可用(哨兵模式)
讀寫分離
單機(jī)的 Redis 的 QPS 大概就在上萬(wàn)到幾萬(wàn)不等,無(wú)法承受更高的并發(fā)。
讀寫分離保證高并發(fā)(10W+ QPS):對(duì)于緩存來(lái)說(shuō)一般都是支撐高并發(fā)讀,寫請(qǐng)求都是比較少的。采用讀寫分離的架構(gòu)(一主多從),master 負(fù)責(zé)接收寫請(qǐng)求,數(shù)據(jù)同步到 slave 上提供讀服務(wù),如果遇到瓶頸只需要增加 slave 機(jī)器就可以水平擴(kuò)容
主從復(fù)制機(jī)制
redis replication 機(jī)制:
redis 采取異步復(fù)制到 slave 節(jié)點(diǎn);
slave 節(jié)點(diǎn)做復(fù)制操作的時(shí)候是不會(huì) block 自己的,它會(huì)使用舊的數(shù)據(jù)集來(lái)提供服務(wù),復(fù)制。完成后,刪除舊的數(shù)據(jù)集,加載新的數(shù)據(jù)集,這個(gè)時(shí)候會(huì)暫停服務(wù)(時(shí)間很短暫);
如果采用了主從架構(gòu),master 需要開啟持久化。如果 master 沒有開啟持久化(rdb 和 aof 都關(guān)閉了)。master 宕機(jī)重啟后數(shù)據(jù)是空的,然后經(jīng)過復(fù)制就把所有 slave 的數(shù)據(jù)也弄丟了。
即使采用高可用的的哨兵機(jī)制,可能 sentinal 還沒有檢測(cè)到 master failure,master 就自動(dòng)重啟了,還是會(huì)導(dǎo)致 slave 清空故障。
主從同步流程
當(dāng) slave 啟動(dòng)時(shí)會(huì)發(fā)送一個(gè) psync 命令給 master;
如果是重新連接 master,則 master node 會(huì)復(fù)制給 slave 缺少的那部分?jǐn)?shù)據(jù);
如果是 slave 第一次連接 master,則會(huì)觸發(fā)一次全量復(fù)制(full resynchronization)。開始 full resynchronization 的時(shí)候,master 會(huì)生成一份 rdb 快照,同時(shí)將客戶端命令緩存在內(nèi)存,rdb 生成完后,就發(fā)送給 slave,slave 先寫入磁盤在加載到內(nèi)存。然后 master 將緩存的命令發(fā)送給 slave。

哨兵(sentinal)模式介紹
哨兵是 redis 集群架構(gòu)的一個(gè)重要組件,主要提供如下功能:
集群監(jiān)控:負(fù)責(zé)監(jiān)控 master 和 slave 是否正常工作;
消息通知:如果某個(gè) redis 實(shí)例有故障, 哨兵負(fù)責(zé)發(fā)消息通知管理員;
故障轉(zhuǎn)移: 如果 master node 發(fā)生故障,會(huì)自動(dòng)切換到 slave;
配置中心:如果故障轉(zhuǎn)移發(fā)生了,通知客戶端新的 master 地址。
哨兵的核心知識(shí):
哨兵至少三個(gè),保證自己的高可用;
哨兵+主從的部署架構(gòu)是用來(lái)保證 redis 集群高可用的,并非保證數(shù)據(jù)不丟失;
哨兵(Sentinel)需要通過不斷的測(cè)試和觀察才能保證高可用。
為什么哨兵只有兩個(gè)節(jié)點(diǎn)無(wú)法正常工作

假設(shè)哨兵集群只部署了 2 個(gè)哨兵實(shí)例,quorum=1。
master 宕機(jī)的時(shí)候,s1 和 s2 只要有一個(gè)哨兵認(rèn)為 master 宕機(jī) j 就可以進(jìn)行切換,并且會(huì)從 s1 和 s2 中選取一個(gè)來(lái)進(jìn)行故障轉(zhuǎn)移。這個(gè)時(shí)候是需要滿足 majority,也就是大多數(shù)哨兵是運(yùn)行的,2 個(gè)哨兵的 majority 是 2,如果 2 個(gè)哨兵都運(yùn)行著就允許執(zhí)行故障轉(zhuǎn)移。如果 M1 所在的機(jī)器宕機(jī)了,那么 s1 哨兵也就掛了,只剩 s2 一個(gè),沒有 majorityl 來(lái)允許執(zhí)行故障轉(zhuǎn)移,雖然集群還有一臺(tái)機(jī)器 R1,但是故障轉(zhuǎn)移也不會(huì)執(zhí)行。
如果是經(jīng)典的三哨兵集群,如下:

此時(shí) majority 也是 2,就算 M1 所在的機(jī)器宕機(jī)了,哨兵還是剩下兩個(gè) s2 和 s3,它們滿足 majority 就可以允許故障轉(zhuǎn)移執(zhí)行。
哨兵核心底層原理
sdown 和 odown 兩種失敗狀態(tài);
sdown 是主觀宕機(jī),就是一個(gè)哨兵覺得 master 宕機(jī)了,達(dá)成條件是如果一個(gè)哨兵 ping master 超過了 is-master-down-after-milliseconds 指定的毫秒數(shù)后就認(rèn)為主觀宕機(jī);
odown 是客觀宕機(jī),如果一個(gè)哨兵在指定時(shí)間內(nèi)收到了 majority(大多數(shù)) 數(shù)量的哨兵也認(rèn)為那個(gè) master 宕機(jī)了,就是客觀宕機(jī)。
哨兵之間的互相發(fā)現(xiàn):哨兵是通過 redis 的 pub/sub 實(shí)現(xiàn)的。
5. Redis 數(shù)據(jù)的恢復(fù)(Redis 的持久化)
RDB
RDB 原理
RDB(Redis DataBase)是將某一個(gè)時(shí)刻的內(nèi)存快照(Snapshot),以二進(jìn)制的方式寫入磁盤的過程。
RDB 有兩種方式 save 和 bgsave:
save: 執(zhí)行就會(huì)觸發(fā) Redis 的持久化,但同時(shí)也是使 Redis 處于阻塞狀態(tài),直到 RDB 持久化完成,才會(huì)響應(yīng)其他客戶端發(fā)來(lái)的命令;
bgsave: bgsave 會(huì) fork() 一個(gè)子進(jìn)程來(lái)執(zhí)行持久化,整個(gè)過程中只有在 fork() 子進(jìn)程時(shí)有短暫的阻塞,當(dāng)子進(jìn)程被創(chuàng)建之后,Redis 的主進(jìn)程就可以響應(yīng)其他客戶端的請(qǐng)求了。
RDB 配置
除了使用 save 和 bgsave 命令觸發(fā)之外, RDB 支持自動(dòng)觸發(fā)。
自動(dòng)觸發(fā)策略可配置 Redis 在指定的時(shí)間內(nèi),數(shù)據(jù)發(fā)生了多少次變化時(shí),會(huì)自動(dòng)執(zhí)行 bgsave 命令。在 redis 配置文件中配置:
在時(shí)間 m 秒內(nèi),如果 Redis 數(shù)據(jù)至少發(fā)生了 n 次變化,那么就自動(dòng)執(zhí)行BGSAVE命令。
save m n
RDB 優(yōu)缺點(diǎn)
RDB 的優(yōu)點(diǎn):
RDB 會(huì)定時(shí)生成多個(gè)數(shù)據(jù)文件,每個(gè)數(shù)據(jù)文件都代表了某個(gè)時(shí)刻的 redis 全量數(shù)據(jù),適合做冷備,可以將這個(gè)文件上傳到一個(gè)遠(yuǎn)程的安全存儲(chǔ)中,以預(yù)定好的策略來(lái)定期備份 redis 中的數(shù)據(jù);
RDB 對(duì) redis 對(duì)外提供讀寫服務(wù)的影響非常小,redis 是通過 fork 主進(jìn)程的一個(gè)子進(jìn)程操作磁盤 IO 來(lái)進(jìn)行持久化的;
相對(duì)于 AOF,直接基于 RDB 來(lái)恢復(fù) reids 數(shù)據(jù)更快。
RDB 的缺點(diǎn):
如果使用 RDB 來(lái)恢復(fù)數(shù)據(jù),會(huì)丟失一部分?jǐn)?shù)據(jù),因?yàn)?RDB 是定時(shí)生成的快照文件;
RDB 每次來(lái) fork 出子進(jìn)程的時(shí)候,如果數(shù)據(jù)文件特別大,可能會(huì)影響對(duì)外提供服務(wù),暫停數(shù)秒(主進(jìn)程需要拷貝自己的內(nèi)存表給子進(jìn)程, 實(shí)例很大的時(shí)候這個(gè)拷貝過程會(huì)很長(zhǎng))。latest_fork_usec 代表 fork 導(dǎo)致的延時(shí);Redis 上執(zhí)行 INFO 命令查看 latest_fork_usec;當(dāng) RDB 比較大的時(shí)候, 應(yīng)該在 slave 節(jié)點(diǎn)執(zhí)行備份, 并在低峰期執(zhí)行。
AOF
AOF 原理
redis 對(duì)每條寫入命令進(jìn)行日志記錄,以 append-only 的方式寫入一個(gè)日志文件,redis 重啟的時(shí)候通過重放日志文件來(lái)恢復(fù)數(shù)據(jù)集。(由于運(yùn)行久了 AOF 文件會(huì)越來(lái)越大,redis 提供一種 rewrite 機(jī)制,基于當(dāng)前內(nèi)存中的數(shù)據(jù)集,來(lái)構(gòu)建一個(gè)更小的 AOF 文件,將舊的龐大的 AOF 文件刪除)。rewrite 即把日志文件壓縮, 通過 bgrewriteaof 觸發(fā)重寫。AOF rewrite 后臺(tái)執(zhí)行的方式和 RDB 有類似的地方,fork 一個(gè)子進(jìn)程,主進(jìn)程仍進(jìn)行服務(wù),子進(jìn)程執(zhí)行 AOF 持久化,數(shù)據(jù)被 dump 到磁盤上。與 RDB 不同的是,后臺(tái)子進(jìn)程持久化過程中,主進(jìn)程會(huì)記錄期間的所有數(shù)據(jù)變更(主進(jìn)程還在服務(wù)),并存儲(chǔ)在 server.aof_rewrite_buf_blocks 中;后臺(tái)子進(jìn)程結(jié)束后,Redis 更新緩存追加到 AOF 文件中,是 RDB 持久化所不具備的。
AOF 的工作流程如下:
Redis 執(zhí)行寫命令后,把這個(gè)命令寫入到 AOF 文件內(nèi)存中(write 系統(tǒng)調(diào)用);
Redis 根據(jù)配置的 AOF 刷盤策略,把 AOF 內(nèi)存數(shù)據(jù)刷到磁盤上(fsync 系統(tǒng)調(diào)用);
根據(jù) rewrite 相關(guān)的配置觸發(fā) rewrite 流程。
AOF 配置
appendonly: 是否啟用 AOF(yes | no);
appendfsync: 刷盤的機(jī)制:
always:主線程每次執(zhí)行寫操作后立即刷盤,此方案會(huì)占用比較大的磁盤 IO 資源,但數(shù)據(jù)安全性最高;
everysec:主線程每次寫操作只寫內(nèi)存就返回,然后由后臺(tái)線程每隔 1 秒執(zhí)行一次刷盤操作(觸發(fā) fsync 系統(tǒng)調(diào)用),此方案對(duì)性能影響相對(duì)較小,但當(dāng) Redis 宕機(jī)時(shí)會(huì)丟失 1 秒的數(shù)據(jù);
no:主線程每次寫操作只寫內(nèi)存就返回,內(nèi)存數(shù)據(jù)什么時(shí)候刷到磁盤,交由操作系統(tǒng)決定,此方案對(duì)性能影響最小,但數(shù)據(jù)安全性也最低,Redis 宕機(jī)時(shí)丟失的數(shù)據(jù)取決于操作系統(tǒng)刷盤時(shí)機(jī)。
auto-aof-rewrite-percentage: 當(dāng) aof 文件相較于上一版本的 aof 文件大小的百分比達(dá)到多少時(shí)觸發(fā) AOF 重寫。舉個(gè)例子,auto-aof-rewrite-percentage 選項(xiàng)配置為 100,上一版本的 aof 文件大小為 100M,那么當(dāng)我們的 aof 文件達(dá)到 200M 的時(shí)候,觸發(fā) AOF 重寫;
auto-aof-rewite-min-size:最小能容忍 aof 文件大小,超過這個(gè)大小必須進(jìn)行 AOF 重寫;
no-appendfsync-on-rewrite: 設(shè)置為 yes 表示 rewrite 期間對(duì)新寫操作不 fsync,暫時(shí)存在內(nèi)存中,等 rewrite 完成后再寫入,默認(rèn)為 no。
AOF 優(yōu)缺點(diǎn)
AOF 的優(yōu)點(diǎn):
可以更好的保證數(shù)據(jù)不丟失,一般 AOF 每隔 1s 通過一個(gè)后臺(tái)線程來(lái)執(zhí)行 fsync(強(qiáng)制刷新磁盤頁(yè)緩存),最多丟失 1s 的數(shù)據(jù);
AOF 以 append-only 的方式寫入(順序追加),沒有磁盤尋址開銷,性能很高;
AOF 即使文件很大, 觸發(fā)后臺(tái) rewrite 的操作的時(shí)候一般也不會(huì)影響客戶端的讀寫,(rewrite 的時(shí)候會(huì)對(duì)其中指令進(jìn)行壓縮,創(chuàng)建出一份恢復(fù)需要的最小日志出來(lái))。
在創(chuàng)建新的日志文件的時(shí)候,老的文件還是照常寫入,當(dāng)新的文件創(chuàng)建完成后再交換新老日志。但是還是有可能會(huì)影響到主線程的寫入, 如:

當(dāng)磁盤的 IO 負(fù)載很高,那這個(gè)后臺(tái)線程在執(zhí)行 AOF fsync 刷盤操作(fsync 系統(tǒng)調(diào)用)時(shí)就會(huì)被阻塞住, ,緊接著,主線程又需要把數(shù)據(jù)寫到文件內(nèi)存中(write 系統(tǒng)調(diào)用),但此時(shí)的后臺(tái)子線程由于磁盤負(fù)載過高,導(dǎo)致 fsync 發(fā)生阻塞,遲遲不能返回,那主線程在執(zhí)行 write 系統(tǒng)調(diào)用時(shí),也會(huì)被阻塞住,直到后臺(tái)線程 fsync 執(zhí)行完成后,主線程執(zhí)行 write 才能成功返回。這時(shí)候主線程就無(wú)法響應(yīng)客戶端的請(qǐng)求, 可能會(huì)導(dǎo)致客戶端請(qǐng)求 redis 超時(shí)。具體類似: https://blog.csdn.net/mmgithub123/article/details/124507846。
AOF 日志文件通過非??勺x的方式進(jìn)行記錄,這個(gè)特性適合做災(zāi)難性的誤操作的緊急恢復(fù),比如不小心使用 flushall 清空了所有數(shù)據(jù),只要 rewrite 沒有發(fā)生,就可以立即拷貝 AOF,將最后一條 flushall 命令刪除,再回放 AOF 恢復(fù)數(shù)據(jù)。
AOF 的缺點(diǎn):
同一份數(shù)據(jù),因?yàn)?AOF 記錄的命令會(huì)比 RDB 快照文件更大;
AOF 開啟后,支持寫的 QPS 會(huì)比 RDB 支持寫的 QPS 要低,畢竟 AOF 有寫磁盤的操作。
總結(jié)
總結(jié) AOF 和 RDB 該如何選擇:兩者綜合使用,將 AOF 配置成每秒 fsync 一次。RDB 作為冷備,AOF 用來(lái)保證數(shù)據(jù)不丟失的恢復(fù)第一選擇,當(dāng) AOF 文件損壞或不可用的時(shí)候還可以使用 RDB 來(lái)快速恢復(fù)。
6. Redis 集群模式(redis cluster)
在主從部署模式上,雖然實(shí)現(xiàn)了一定程度的高并發(fā),并保證了高可用,但是有如下限制:
master 數(shù)據(jù)和 slave 數(shù)據(jù)一模一樣,master 的數(shù)據(jù)量就是集群的限制瓶頸;
redis 集群的寫能力也受到了 master 節(jié)點(diǎn)的單機(jī)限制。
在高版本的 Redis 已經(jīng)原生支持集群(cluster)模式,可以多 master 多 slave 部署,橫向擴(kuò)展 Redis 集群的能力。Redis Cluster 支持 N 個(gè) master node ,每個(gè) master node 可以掛載多個(gè) slave node。
redis cluster 介紹
自動(dòng)將數(shù)據(jù)切片,每個(gè) master 上放一部分?jǐn)?shù)據(jù);
提供內(nèi)置的高可用支持,部分 master 不可用時(shí)還是能夠工作;
redis cluster 模式下,每個(gè) redis 要開放兩個(gè)端口:6379 和 10000+以后的端口(如 16379)。16379 是用來(lái)節(jié)點(diǎn)之間通信的,使用的是 cluster bus 集群總線。cluster bus 用來(lái)做故障檢測(cè),配置更新,故障轉(zhuǎn)移授權(quán)。
redis cluster 負(fù)載均衡
redis cluster 采用 一致性 hash+虛擬節(jié)點(diǎn) 來(lái)負(fù)載均衡。redis cluster 有固定的 16384 個(gè) slot (2^14),對(duì)每個(gè) key 做 CRC16 值計(jì)算,然后對(duì) 16384 mod??梢垣@取每個(gè) key 的 slot。redis cluster 每個(gè) master 都會(huì)持有部分 slot,比如 三個(gè) master 那么 每個(gè) master 就會(huì)持有 5000 多個(gè) slot。hash slot 讓 node 的添加和刪除變得很簡(jiǎn)單,增加一個(gè) master,就將其他 master 的 slot 移動(dòng)部分過去,減少一個(gè)就分給其他 master,這樣讓集群擴(kuò)容的成本變得很低。
cluster 基礎(chǔ)通信原理(gossip 協(xié)議)
與集中式不同(如使用 zookeeper 進(jìn)行分布式協(xié)調(diào)注冊(cè)),redis cluster 使用的是 gossip 協(xié)議進(jìn)行通信。并不是將集群元數(shù)據(jù)存儲(chǔ)在某個(gè)節(jié)點(diǎn)上,而是不斷的互相通信,保持整個(gè)集群的元數(shù)據(jù)是完整的。gossip 協(xié)議所有節(jié)點(diǎn)都持有一份元數(shù)據(jù),不同節(jié)點(diǎn)的元數(shù)據(jù)發(fā)生了變更,就不斷的將元數(shù)據(jù)發(fā)送給其他節(jié)點(diǎn),讓其他節(jié)點(diǎn)也進(jìn)行元數(shù)據(jù)的變更。
集中式的好處:元數(shù)據(jù)的讀取和更新時(shí)效性很好,一旦元數(shù)據(jù)變化就更新到集中式存儲(chǔ),缺點(diǎn)就是元數(shù)據(jù)都在一個(gè)地方,可能導(dǎo)致元數(shù)據(jù)的存儲(chǔ)壓力。
對(duì)于 gossip 來(lái)說(shuō):元數(shù)據(jù)的更新會(huì)有延時(shí),會(huì)降低元數(shù)據(jù)的壓力,缺點(diǎn)是操作是元數(shù)據(jù)更新可能會(huì)導(dǎo)致集群的操作有一些滯后。
redis cluster 主備切換與高可用
判斷節(jié)點(diǎn)宕機(jī):如果有一個(gè)節(jié)點(diǎn)認(rèn)為另外一個(gè)節(jié)點(diǎn)宕機(jī),那就是 pfail,主觀宕機(jī)。如果多個(gè)節(jié)點(diǎn)認(rèn)為一個(gè)節(jié)點(diǎn)宕機(jī),那就是 fail,客觀宕機(jī)。跟哨兵的原理一樣;
對(duì)宕機(jī)的 master,從其所有的 slave 中選取一個(gè)切換成 master node,再次之前會(huì)進(jìn)行一次過濾,檢查每個(gè) slave 與 master 的斷開時(shí)間,如果超過了 cluster-node-timeout * cluster-slave-validity-factor 就沒有資格切換成 master;
從節(jié)點(diǎn)選?。好總€(gè)從節(jié)點(diǎn)都會(huì)根據(jù)從 master 復(fù)制數(shù)據(jù)的 offset,來(lái)設(shè)置一個(gè)選舉時(shí)間,offset 越大的從節(jié)點(diǎn),選舉時(shí)間越靠前,master node 開始給 slave 選舉投票,如果大部分 master(n/2+1)都投給了某個(gè) slave,那么選舉通過(與 zk 有點(diǎn)像,選舉時(shí)間類似于 epochid);
整個(gè)流程與哨兵類似,可以說(shuō) redis cluster 集成了哨兵的功能,更加的強(qiáng)大;
Redis 集群部署相關(guān)問題 redis 機(jī)器的配置,多少臺(tái)機(jī)器,能達(dá)到多少 qps?
機(jī)器標(biāo)準(zhǔn):8 核+32G
集群: 5 主+5 從(每個(gè) master 都掛一個(gè) slave)
效果: 每臺(tái)機(jī)器最高峰每秒大概 5W,5 臺(tái)機(jī)器最多就是 25W,每個(gè) master 都有一個(gè)從節(jié)點(diǎn),任何一個(gè)節(jié)點(diǎn)掛了都有備份可切換成主節(jié)點(diǎn)進(jìn)行故障轉(zhuǎn)移
腦裂問題哨兵模式下:
master 下 掛載了 3 個(gè) slave,如果 master 由于網(wǎng)絡(luò)抖動(dòng)被哨兵認(rèn)為宕機(jī)了,執(zhí)行了故障轉(zhuǎn)移,從 slave 里面選取了一個(gè)作為新的 master,這個(gè)時(shí)候老的 master 又恢復(fù)了,剛好又有 client 連的還是老的 master,就會(huì)產(chǎn)生腦裂,數(shù)據(jù)也會(huì)不一致,比如 incr 全局 id 也會(huì)重復(fù)。
redis 對(duì)此的解決方案是:min-slaves-to-write 1 至少有一個(gè) slave 連接 min-slaves-max-lag 10 slave 與 master 主從復(fù)制延遲時(shí)間如果連接到 master 的 slave 數(shù)小于最少 slave 的數(shù)量,并且主從復(fù)制延遲時(shí)間超過配置時(shí)間,master 就拒絕寫入 12。client 連接 redis 多 tcp 連接的考量首先 redis server 雖然是單線程來(lái)處理請(qǐng)求, 但是他是多路復(fù)用的, 單 tcp 連接肯定是沒有多 tcp 連接性能好, 多路復(fù)用一個(gè) io 周期得到的就緒 io 事件越多, 處理的就越多。這也不是絕對(duì)的, 如果使用 pipeline 的方式傳輸, 單連接會(huì)比多連接性能好, 因?yàn)槊恳粋€(gè) pipeline 的單次請(qǐng)求過多也會(huì)導(dǎo)致單周期到的命令太多, 性能下降多少個(gè)連接比較合適這個(gè)問題, redis cluser 控制在每個(gè)節(jié)點(diǎn) 100 個(gè)連接以內(nèi)。
推薦閱讀
50 個(gè) Redis 必備知識(shí):基礎(chǔ)知識(shí),架構(gòu)、調(diào)優(yōu)和監(jiān)控知識(shí)及難點(diǎn)解決
學(xué)會(huì)這幾個(gè) Redis 技巧,讓你的程序快如閃電!
一口氣說(shuō)出 Redis 16 個(gè)常見使用場(chǎng)景
萬(wàn)字總結(jié),Redis 性能問題排查解決手冊(cè)!

