前言
這里來了解一下,Redis 中常見的集群方案
幾種常用的集群方案
- 主從集群模式
- 哨兵機制
- 切片集群(分片集群)
主從集群模式
主從集群,主從庫之間采用的是讀寫分離
- 主庫:所有的寫操作都在讀庫發(fā)生,然后主庫同步數(shù)據(jù)到從庫,同時也可以進行讀操作;
- 從庫:只負責(zé)讀操作;
主庫需要復(fù)制數(shù)據(jù)到從庫,主從雙方的數(shù)據(jù)庫需要保存相同的數(shù)據(jù),將這種情況稱為"數(shù)據(jù)庫狀態(tài)一致"
來看下如何同步之前先來了解下幾個概念
1、服務(wù)器的運行ID(run ID):每個 Redis 服務(wù)器在運行期間都有自己的run ID
,run ID
在服務(wù)器啟動的時候自動生成。
從服務(wù)器會記錄主服務(wù)器的run ID
,這樣如果發(fā)生斷網(wǎng)重連,就能判斷新連接上的主服務(wù)器是不是上次的那一個,這樣來決定是否進行數(shù)據(jù)部分重傳還是完整重新同步。
2、復(fù)制偏移量 offset:主服務(wù)器和從服務(wù)器都會維護一個復(fù)制偏移量
主服務(wù)器每次向從服務(wù)器中傳遞 N 個字節(jié)的時候,會將自己的復(fù)制偏移量加上 N。
從服務(wù)器中收到主服務(wù)器的 N 個字節(jié)的數(shù)據(jù),就會將自己額復(fù)制偏移量加上 N。
通過主從服務(wù)器的偏移量對比可以很清楚的知道主從服務(wù)器的數(shù)據(jù)是否處于一致。
如果不一致就需要進行增量同步了,具體參加下文的增量同步
全量同步
從服務(wù)器首次加入主服務(wù)器中發(fā)生的是全量同步
如何進行第一次同步?
1、從服務(wù)器連接到主服務(wù)器,然后發(fā)送 psync 到主服務(wù)器,因為第一次復(fù)制,不知道主庫run ID
,所以run ID
為?;
2、主服務(wù)器接收到同步的響應(yīng),回復(fù)從服務(wù)器自己的run ID
和復(fù)制進行進度 offset;
3、主服務(wù)器開始同步所有數(shù)據(jù)到從庫中,同步依賴 RDB 文件,主庫會通過 bgsave 命令,生成 RDB 文件,然后將 RDB 文件傳送到從庫中;
4、從庫收到 RDB 文件,清除自己的數(shù)據(jù),然后載入 RDB 文件;
5、主庫在同步的過程中不會被阻塞,仍然能接收到命令,但是新的命令是不能同步到從庫的,所以主庫會在內(nèi)存中用專門的 replication buffer
,記錄 RDB 文件生成后收到的所有寫操作,然后在 RDB 文件,同步完成之后,再將replication buffer
中的命令發(fā)送到從庫中,這樣就保證了從庫的數(shù)據(jù)同步。
增量同步
如果主從服務(wù)器之間發(fā)生了網(wǎng)絡(luò)閃斷,從從服務(wù)將會丟失一部分同步的命令。
在舊版本,Redis 2.8
之前,如果發(fā)生了網(wǎng)絡(luò)閃斷,就會進行一次全量復(fù)制。
在 2.8 版本之后,引入了增量同步的技術(shù),這里主要是用到了 repl_backlog_buffer
Redis 主庫接收到寫操作的命令,首先會寫入replication buffer
(主要用于主從數(shù)據(jù)傳輸?shù)臄?shù)據(jù)緩沖),同時也會把這些操作命令也寫入repl_backlog_buffer
這個緩沖區(qū)。
這里可能有點疑惑,已經(jīng)有了replication buffer
為什么還多余引入一個repl_backlog_buffer
呢?
-
repl_backlog_buffer
一個主庫對應(yīng)一個repl_backlog_buffer
,也就是所有從庫對應(yīng)一個repl_backlog_buffer
,從庫自己記錄自己的slave_repl_offset
。 -
replication buffer
用于主節(jié)點與各個從節(jié)點間,數(shù)據(jù)的批量交互。主節(jié)點為各個從節(jié)點分別創(chuàng)建一個緩沖區(qū),由于各個從節(jié)點的處理能力差異,各個緩沖區(qū)數(shù)據(jù)可能不同。
如何主從斷開了,當(dāng)然對應(yīng)的replication buffer
也就沒有了。這時候就依賴repl_backlog_buffer
進行數(shù)據(jù)的增量同步了。
repl_backlog_buffer
是一個環(huán)形緩沖區(qū),主庫會記錄自己寫到的位置,從庫則會記錄自己已經(jīng)讀到的位置。
這里借用Redis核心技術(shù)與實戰(zhàn)的一張圖片
剛開始主服務(wù)器的 master_repl_offset 和從服務(wù)器 slave_repl_offset 的位置是一樣的,在從庫因為網(wǎng)絡(luò)原因斷連之后,隨著主庫寫操作的進行,主從偏移量會出現(xiàn)偏移距離。
當(dāng)從服務(wù)器連上主服務(wù)器之后,從服務(wù)把自己當(dāng)前的 slave_repl_offset 告訴主服務(wù)器,然后主服務(wù)器根據(jù)自己的 master_repl_offset 計算出和從服務(wù)器之間的差距,然后把兩者之間相差的命令操作同步給從服務(wù)器。
舉個栗子
比如這里從服務(wù)器1,剛剛由于網(wǎng)絡(luò)原因斷連了一會,然后又恢復(fù)了連接,這時候,可能缺失了一段時間的命令同步,repl_backlog_buffer
的增量同步機制就登場了。
repl_backlog_buffer
會根據(jù)主服務(wù)器的master_repl_offset
和從服務(wù)器slave_repl_offset
,計算出兩者命令之間的差距,之后把差距同步給replication buffer
,然后發(fā)送到從服務(wù)器中。
repl_backlog_buffer
中的緩沖空間要設(shè)置的大一點,如果從庫讀的過慢,因為是環(huán)形緩沖區(qū),可能出現(xiàn)命令覆蓋的情況,如果出現(xiàn)命令被覆蓋了,從庫的增量同步就無法進行了,這時候會進行一次全量的復(fù)制。
緩沖空間的計算公式是:緩沖空間大小 = 主庫寫入命令速度 * 操作大小 - 主從庫間網(wǎng)絡(luò)傳輸命令速度 * 操作大小
。在實際應(yīng)用中,考慮到可能存在一些突發(fā)的請求壓力,我們通常需要把這個緩沖空間擴大一倍,即 repl_backlog_size = 緩沖空間大小 * 2,這也就是 repl_backlog_size 的最終值。
哨兵機制
對于主從集群模式,如果從庫發(fā)生了故障,還有主庫和其它的從庫可以接收請求,但是如果主庫掛了,就不能進行正常的數(shù)據(jù)寫入,同時數(shù)據(jù)同步也不能正常的進行了,當(dāng)然這種情況,我們需要想辦法避免,于是就引入了下面的哨兵機制。
什么是哨兵機制
sentinel(哨兵機制):是 Redis 中集群的高可用方式,哨兵節(jié)點是特殊的 Redis 服務(wù),不提供讀寫,主要來監(jiān)控 Redis 中的實例節(jié)點,如果監(jiān)控服務(wù)的主服務(wù)器下線了,會從所屬的從服務(wù)器中重新選出一個主服務(wù)器,代替原來的主服務(wù)器提供服務(wù)。
核心功能就是:監(jiān)控,選主,通知。
監(jiān)控:哨兵機制,會周期性的給所有主服務(wù)器發(fā)出 PING 命令,檢測它們是否仍然在線運行,如果在規(guī)定的時間內(nèi)響應(yīng)了 PING 通知則認為,仍在線運行;如果沒有及時回復(fù),則認為服務(wù)已經(jīng)下線了,就會進行切換主庫的動作。
選主:當(dāng)主庫掛掉的時候,會從從庫中按照既定的規(guī)則選出一個新的的主庫,
通知:當(dāng)一個主庫被新選出來,會通知其他從庫,進行連接,然后進行數(shù)據(jù)的復(fù)制。當(dāng)客戶端試圖連接失效的主庫時,集群也會向客戶端返回新主庫的地址,使得集群可以使用新的主庫。
如何保證選主的準確性
哨兵會通過 PING 命令檢測它和從庫,主庫之間的連接情況,如果發(fā)現(xiàn)響應(yīng)超時就會認為給服務(wù)已經(jīng)下線了。
當(dāng)然這會存在誤判的情況,如果集群的網(wǎng)絡(luò)壓力比較大,網(wǎng)路堵塞,這時候會存在誤判的情況。
如果誤判的節(jié)點是從節(jié)點,影響不會很大,拿掉一個從節(jié)點,對整體的服務(wù),影響不大,還是會不間斷的對外提供服務(wù)。
如果誤判的節(jié)點是主節(jié)點,影響就很大了,主節(jié)點被標注下線了,就會觸發(fā)后續(xù)的選主,數(shù)據(jù)同步,等一連串的動作,這一連串的動作很很消耗性能的。所以對于誤判,應(yīng)該去規(guī)避。
如何減少誤判呢?
引入哨兵集群,一個哨兵節(jié)點可能會進行誤判,引入多個少哨兵節(jié)點一起做決策,就能減少誤判了。
當(dāng)有多個哨兵節(jié)點的時候,大多數(shù)哨兵節(jié)點認為主庫下線了,主庫才會真正的被標記為下線了,一般來講當(dāng)有 N 個哨兵實例時,最好要有N/2 + 1
個實例判斷主庫下線了,才能最終判定主庫的下線狀態(tài)。當(dāng)然這個數(shù)值在 Redis 中是可以配置的。
如何選主
選舉主節(jié)點的規(guī)則
1、過濾掉已經(jīng)下線的服務(wù)器;
2、過濾掉最近5秒鐘沒有回復(fù)過主節(jié)點的 INFO(用于觀察服務(wù)器的角色) 命令的服務(wù)器,保證選中的服務(wù)器都是最近成功通過信的;
3、過濾掉和下線主服務(wù)器連接超過down-after-milliseconds*10
毫秒的從服務(wù)器,down-after-milliseconds
是主服務(wù)器下線的時間,這一操作避免從服務(wù)器與主服務(wù)器過早的斷開,影響到從庫中數(shù)據(jù)同步,因為斷開時間越久,從庫里面的數(shù)據(jù)就越老舊過時。
然后對這些服務(wù)器根據(jù)slave-priority
優(yōu)先級(這個優(yōu)先級是手動設(shè)置的,比如希望那個從服務(wù)器優(yōu)先變成主服務(wù)器,優(yōu)先級就設(shè)置的高一點) 進行排序。
如果幾臺從服務(wù)器優(yōu)先級相同,然后根據(jù)復(fù)制偏移量從大到小進行排序,如果還有相同偏移量的從服務(wù)器,然后按照 runID 從小到大進行排序,直到選出一臺從服務(wù)器。
哨兵進行主節(jié)點切換
當(dāng)根據(jù)選舉規(guī)則,選出了可以成為主節(jié)點的從節(jié)點,如何進行切換呢?
在哨兵中也是有一個 Leader 節(jié)點的,當(dāng)一個從庫被選舉出來,從庫的切換是由 Leader 節(jié)點完成的。
Leader 節(jié)點的選舉用的是 Raft 算法,關(guān)于什么是 Raft 算法可參考Raft一致性算法原理
在raft算法中,在任何時刻,每一個服務(wù)器節(jié)點都處于這三個狀態(tài)之一:
- Follower:追隨者,跟隨者都是被動的:他們不會發(fā)送任何請求,只是簡單的響應(yīng)來自領(lǐng)導(dǎo)者或者候選人的請求;
- Candidate:候選人,如果跟隨者接收不到消息,那么他就會變成候選人并發(fā)起一次選舉,獲得集群中大多數(shù)選票的候選人將成為領(lǐng)導(dǎo)者。
- Leader:領(lǐng)導(dǎo)者,系統(tǒng)中只有一個領(lǐng)導(dǎo)人并且其他的節(jié)點全部都是跟隨者,領(lǐng)導(dǎo)人處理所有的客戶端請求(如果一個客戶端和跟隨者聯(lián)系,那么跟隨者會把請求重定向給領(lǐng)導(dǎo)人)
哨兵節(jié)點的選舉總結(jié)起來就是:
1、每個做主觀下線的sentinel節(jié)點向其他sentinel節(jié)點發(fā)送命令,要求將自己設(shè)置為領(lǐng)導(dǎo)者;
2、接收到的sentinel可以同意或者拒絕;
3、如果該sentinel節(jié)點發(fā)現(xiàn)自己的票數(shù)已經(jīng)超過半數(shù)并且超過了 quorum,quorum 用來配置判斷主節(jié)點宕機的哨兵節(jié)點數(shù)。簡單點講就是:如果 Sentinel 集群有 quorum 個哨兵認為 master 宕機了,就「客觀」的認為 master 宕機了;
4、如果此過程選舉出了多個領(lǐng)導(dǎo)者,那么將等待一段時重新進行選舉;
故障轉(zhuǎn)移
- sentinel的領(lǐng)導(dǎo)者從從機中選舉出合適的叢機進行故障轉(zhuǎn)移;
-
對選取的從節(jié)點進行
slave of no one
命令,(這個命令用來讓從機關(guān)閉復(fù)制功能,并從從機變?yōu)橹鳈C); - 更新應(yīng)用程序端的鏈接到新的主節(jié)點;
- 對其他從節(jié)點變更 master 為新的節(jié)點;
- 修復(fù)原來的 master 并將其設(shè)置為新的 master 的從機。
消息通知
哨兵和哨兵之前,哨兵和從庫之間,哨兵和客戶端是如何相互發(fā)現(xiàn),進行消息傳遞?
哨兵和哨兵之間的相互發(fā)現(xiàn),通過 Redis 提供的pub/sub
機制實現(xiàn),因為每個哨兵節(jié)點都會和主庫進行連接,通過在主庫中發(fā)布信息,訂閱信息,就能找到其他實例的連接信息。
哨兵節(jié)點和從庫,通過哨兵向主庫發(fā)送 INFO 命令來完成,哨兵給主庫發(fā)送 INFO 命令,主庫接受到這個命令后,就會把從庫列表返回給哨兵。接著,哨兵就可以根據(jù)從庫列表中的連接信息,和每個從庫建立連接,并在這個連接上持續(xù)地對從庫進行監(jiān)控。
哨兵和客戶端之間:每個哨兵實例也提供pub/sub
機制,客戶端可以從哨兵訂閱消息,來獲知主從庫切換過程中的不同關(guān)鍵事件。
哨兵提升一個從庫為新主庫后,哨兵會把新主庫的地址寫入自己實例的 pubsub(switch-master)
中。客戶端需要訂閱這 個pubsub,當(dāng)這個 pubsub 有數(shù)據(jù)時,客戶端就能感知到主庫發(fā)生變更,同時可以拿到最新的主庫地址,然后把寫請求寫到這個新主庫即可,這種機制屬于哨兵主動通知客戶端。
如果客戶端因為某些原因錯過了哨兵的通知,或者哨兵通知后客戶端處理失敗了,安全起見,客戶端也需要支持主動去獲取最新主從的地址進行訪問。
切片集群
對于數(shù)據(jù)庫我們知道,如果數(shù)據(jù)量大會進行分庫分表,一般有兩種方案縱向拆分和橫向拆分。這在 Redis 中,同樣適用。
Redis 中的擴展
- 縱向擴展:更改節(jié)點類型以調(diào)整集群大小,升級單個Redis實例的資源配置,包括增加內(nèi)存容量、增加磁盤容量、使用更高配置的CPU。
- 橫向擴展:通過添加或刪除節(jié)點組(分片)來更改復(fù)制組中的節(jié)點組(分片)數(shù)量。
簡單點講就是:垂直擴容就是增加自身的容量,橫向擴容就是加機器。
缺點對比
縱向擴容:
1、如果一味的增加自身的容量,意味著自身存儲的數(shù)據(jù)將會越來越大,過大的數(shù)據(jù),持久化時間將會變得很長,影響自身的響應(yīng)速度;
2、同樣堆硬件總歸是有上線,達到一定量之后,還是要考慮進行橫向擴容;
橫向擴容:
橫向擴容要面臨的問題,如果發(fā)生了分片的擴容,就需要考慮數(shù)據(jù)的遷移,同時數(shù)據(jù)切片后,在多個實例之間如何分布?,客戶端如何知道訪問的數(shù)據(jù)在哪個實例中。。。
雖然有這些問題的存在,好在已經(jīng)有一些成熟的方案來處理橫向擴容所遇到的問題了
官方的集群解決方案就是Redis Cluster
;社區(qū)的解決方案有 Codis 和 Twemproxy,Codis 是由我國的豌豆莢團隊開源的,Twemproxy 是 Twitter 團隊的開源的。
這里主要看下Redis Cluster
是如何進行處理的
Redis Cluster方案
1、Redis Cluster
方案采用哈希槽來處理 KEY 在不同實例中的分布,一個切片集群共有16384個哈希槽,這些哈希槽類似于數(shù)據(jù)分區(qū),每個鍵值對都會根據(jù)它的key,被映射到一個哈希槽中。
2、一個 KEY ,首先會根據(jù)CRC16算法計算一個16 bit的值;然后,再用這個 16bit 值對 16384 取模,得到0~16383范圍內(nèi)的模數(shù),每個模數(shù)代表一個相應(yīng)編號的哈希槽。
3、然后把哈希槽分配到所有的實例中,例如,如果集群中有N個實例,那么,每個實例上的槽個數(shù)為16384/N個。
當(dāng)然這是平均分配的,如果平均分配額哈希槽中,某一個實例中 KEY,存儲的數(shù)據(jù)比較大,造成某一個實例的內(nèi)存過大,這時候可以通過cluster addslots
手動調(diào)節(jié)哈希槽的分配。
當(dāng)手動分配哈希槽時,需要把16384個槽都分配完,否則Redis集群無法正常工作。
客戶端中的 KEY 如何找到對應(yīng)的實例
在集群剛剛創(chuàng)建的時候,每個實例只知道自己被分配了哪些哈希槽,是不知道其他實例擁有的哈希槽信息的。但是,Redis 實例會把自己的哈希槽信息發(fā)給和它相連接的其它實例,來完成哈希槽分配信息的擴散。
所以當(dāng)客戶端和集群實例連接后,就可以知道所有的哈希槽的映射,客戶端會把哈希槽的映射保存在本地,這樣如果客戶端響應(yīng)一個 KEY ,計算出哈希槽,然后就可以向?qū)?yīng)的實例發(fā)送請求了。
哈希槽重新分配
數(shù)據(jù)在可能發(fā)生遷移,這時候哈希槽就會重新分配了
栗如:
1、集群中的實例,有增加或減少;
2、引入了負載均衡,需要重新分配哈希槽;
因為重新分配了哈希槽,所以原來的映射關(guān)系可能發(fā)生了改變,實例之間可以通過相互通知,快速的感知到映射關(guān)系的變化。但是,客戶端無法主動感知這些變化,客戶端對 KEY 的響應(yīng),可能依舊映射到了之前的實例節(jié)點,面對這種情況,如何處理呢?
1、如果數(shù)據(jù)已經(jīng)遷移完了
Redis Cluster
中提供重定向機制,如果一個實例接收到客戶端的請求,但是對應(yīng)的 KEY 已經(jīng)轉(zhuǎn)移到別的實例節(jié)點中了,這時候會計算出 KEY 當(dāng)前所處實例的地址,然后返回給客戶端,客戶端拿到最新的實例地址,重新發(fā)送請求就可以了。
$ GET hello (error) MOVED 12320 172.168.56.111:6379
2、數(shù)據(jù)遷移了一半
如果在遷移的過程中,只遷移了一半的數(shù)據(jù),這時候服務(wù)器端就會返回 ASK 告知客戶端
GET hello (error) ASK 1332 012320 172.168.56.111:6379
ASK 就表示當(dāng)前正在遷移中,客戶端需要訪問數(shù)據(jù),就還需要向返回的地址信息,發(fā)送一條 ASKING 命令,讓這個實例允許客戶端的訪問請求,然后客戶端再發(fā)送具體的業(yè)務(wù)操作命令。
避免 Hot Key
Hot Key
就是采用切片集群部署的 Redis ,出現(xiàn)的集群訪問傾斜。
切片集群中的 Key 最終會存儲到集群中的一個固定的 Redis 實例中。某一個 Key 在一段時間內(nèi)訪問遠高于其它的 Key,也就是該 Key 對應(yīng)的 Redis 實例,會收到過大的流量請求,該實例容易出現(xiàn)過載和卡頓現(xiàn)象,甚至還會被打掛掉。
常見引發(fā)熱點 Key 的情況:
1、新聞中的熱點事件;
2、秒殺活動中的,性價比高的商品;
如何發(fā)現(xiàn) Hot Key
1、提現(xiàn)預(yù)判;
根據(jù)業(yè)務(wù)經(jīng)驗進行提前預(yù)判;
2、在客戶端進行收集;
通過在客戶端增加命令的采集,來統(tǒng)計發(fā)現(xiàn)熱點 Key;
3、使用 Redis 自帶的命令排查;
使用monitor命令統(tǒng)計熱點key(不推薦,高并發(fā)條件下會有造成redis 內(nèi)存爆掉的隱患);
hotkeys參數(shù),redis 4.0.3提供了redis-cli的熱點key發(fā)現(xiàn)功能,執(zhí)行redis-cli時加上–hotkeys選項即可。但是該參數(shù)在執(zhí)行的時候,如果key比較多,執(zhí)行起來比較慢。
4、在Proxy層做收集
如果集群架構(gòu)引入了 proxy,可以在 proxy 中做統(tǒng)計
5、自己抓包評估
Redis客戶端使用TCP協(xié)議與服務(wù)端進行交互,通信協(xié)議采用的是RESP。自己寫程序監(jiān)聽端口,按照RESP協(xié)議規(guī)則解析數(shù)據(jù),進行分析。缺點就是開發(fā)成本高,維護困難,有丟包可能性。
Hot Key 如何解決
知道了Hot Key
如何來應(yīng)對呢
1、對 Key 進行分散處理;
舉個栗子
有一個熱 Key 名字為Hot-key-test
,可以將其分散為Hot-key-test1
,Hot-key-test2
...然后將這些 Key 分散到多個實例節(jié)點中,當(dāng)客戶端進行訪問的時候,隨機一個下標的 Key 進行訪問,這樣就能將流量分散到不同的實例中了,避免了一個緩存節(jié)點的過載。
一般來講,可以通過添加后綴或者前綴,把一個 hotkey 的數(shù)量變成 redis 實例個數(shù) N 的倍數(shù) M,從而由訪問一個redis key
變成訪問N * M
個redis key。 N*M
個redis key
經(jīng)過分片分布到不同的實例上,將訪問量均攤到所有實例。
const M = N * 2 //生成隨機數(shù) random = GenRandom(0, M) //構(gòu)造備份新key bakHotKey = hotKey + “_” + random data = redis.GET(bakHotKey) if data == NULL { data = GetFromDB() redis.SET(bakHotKey, expireTime + GenRandom(0,5)) }
2、使用本地緩存;
業(yè)務(wù)端還可以使用本地緩存,將這些熱 key 記錄在本地緩存,來減少對遠程緩存的沖擊。
避免 Big Key
什么是 Big Key
:我們將含有較大數(shù)據(jù)或含有大量成員、列表數(shù)的Key稱之為大Key。
- 一個STRING類型的Key,它的值為5MB(數(shù)據(jù)過大)
- 一個LIST類型的Key,它的列表數(shù)量為20000個(列表數(shù)量過多)
- 一個ZSET類型的Key,它的成員數(shù)量為10000個(成員數(shù)量過多)
- 一個HASH格式的Key,它的成員數(shù)量雖然只有1000個但這些成員的value總大小為100MB(成員體積過大)
Big Key 存在問題
- 內(nèi)存空間不均勻:如果采用切片集群的部署方案,容易造成某些實例節(jié)點的內(nèi)存分配不均勻;
- 造成網(wǎng)絡(luò)擁塞:讀取 bigkey 意味著需要消耗更多的網(wǎng)絡(luò)流量,可能會對 Redis 服務(wù)器造成影響;
- 過期刪除:big key 不單讀寫慢,刪除也慢,刪除過期 big key 也比較耗時;
- 遷移困難:由于數(shù)據(jù)龐大,備份和還原也容易造成阻塞,操作失敗;
如何發(fā)現(xiàn) Big Key
- 使用 redis-cli 客戶端的命令 --bigkeys;
- 生成 rdb 文件,離線分析 rdb 文件。比如:redis-rdb-cli,rdbtools;
- 通過 scan 命令,對掃描出來的key進行類型判斷,例如:string長度大于10K,list長度大于10240認為是big bigkeys;
Big Key 如何避免
對于Big Key
可以從以下兩個方面進行處理
合理優(yōu)化數(shù)據(jù)結(jié)構(gòu):
1、對較大的數(shù)據(jù)進行壓縮處理;
2、拆分集合:將大的集合拆分成小集合(如以時間進行分片)或者單個的數(shù)據(jù)。
選擇其他的技術(shù)來存儲 big key:
使用其他的存儲形式,考慮使用 cdn 或者文檔性數(shù)據(jù)庫 MongoDB。
Big Key 如何刪除
直接使用 DEL 命令會發(fā)生什么?危險:同步刪除 bigkey 會阻塞 Redis 其他命令,造成 Redis 阻塞。
推薦使用 UNLINK 命令,異步刪除 bigkey,不影響主線程執(zhí)行其他命令。
在業(yè)務(wù)的低峰期使用 scan 命令查找 big key,對于類型為集合的key,可以使用腳本逐一刪除里面的元素。
參考
【Redis核心技術(shù)與實戰(zhàn)】https://time.geekbang.org/column/intro/100056701
【Redis設(shè)計與實現(xiàn)】https://book.douban.com/subject/25900156/
【估算兩臺服務(wù)器同時故障的概率】https://disksing.com/failure-probability-analysis/
【Redis中哨兵選舉算法】https://blog.csdn.net/weixin_44324174/article/details/108939199
【如何處理redis集群中hot key和big key】https://juejin.cn/post/6844903743083773959
【談?wù)剅edis的熱key問題如何解決】https://www.cnblogs.com/rjzheng/p/10874537.html
【Redis 中常見的集群部署方案】https://boilingfrog.github.io/2022/02/20/redis中常見的集群部署方案/#主從集群模式
【Redis學(xué)習(xí)筆記】https://github.com/boilingfrog/Go-POINT/tree/master/redis
到此這篇關(guān)于Redis中常見的幾種集群部署方案的文章就介紹到這了,更多相關(guān)Redis 集群部署內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文地址:https://www.cnblogs.com/ricklz/p/15916014.html