概述
Redis作為緩存的高效中間件,在我們日常的開發中被頻繁的使用,今天就來說一說Redis的四種模式,分別是「單機版、主從復制、哨兵、以及集群模式」。
可能,在一般公司的程序員使用單機版基本都能解決問題,在Redis的官網給出的數據是10W QPS,這對于應付一般的公司綽綽有余了,再不行就來個主從模式,實現讀寫分離,性能又大大提高。
但是,我們作為有抱負的程序員,僅限于單機版和主從模式的crud是不行的,至少也要了解「哨兵」和「集群模式」的原理,這樣面試的時候才能和面試官扯皮啊。
之前對于Redis方面也是寫了比較多的文章,如:「Redis的基本數據類型和底層的實現原理、事務、持久化、分布式鎖、訂閱預發布」等,可以說是比較全面的教程了,這篇講完基本就全了,我會把文章系統的整理成pdf,分享給大家。
先來個整理的Redis大綱,可能還有不完整的地方,若是有不完整的,可以在留言區補充,我后續會加進去。
單機
單機版的Redis就比較簡單了,基本90%的程序員都是用過,官網推薦操作Redis的第三方依賴庫是Jedis,在SpringBoot項目中,引入下面依賴就可以直接使用了:
優點
單機版的Redis也有很多優點,比如實現實現簡單、維護簡單、部署簡單、維護成本非常低,不需要其它額外的開支。
缺點
但是,因為是單機版的Redis所以也存在很多的問題,比如最明顯的單點故障問題,一個Redis掛了,所有的請求就會直接打在了DB上。
并且一個Redis抗并發數量也是有限的,同時要兼顧讀寫兩種請求,只要訪問量一上來,Redis就受不了了,另一方面單機版的Redis數據量存儲也是有限的,數據量一大,再重啟Redis的時候,就會非常的慢,所以局限性也是比較大的。
實操搭建
單機版的搭建教程,在網上有非常多的全面的教程,基本就是傻瓜式操作,特別是在本地搭建的話,基本使用yum快捷方便,幾句命令就搞定了,這里推薦一個搭建教程:https://www.cnblogs.com/zuidongfeng/p/8032505.html。
上面這個教程講的非常的詳細,環境的搭建本來是運維的工作,但是作為程序員嘗試自己去搭建環境還是有必要的,而且搭建環境這種東西,基本就是一勞永逸,搭建一次,可能下次換電腦或者重裝虛擬機才會再次搭建。
這里也放出redis常用的redis.conf的配置項,并且附帶注釋,看我是不是很暖男:
daemonizeyes//設置后臺啟動,一般設置yes pidfile/var/run/redis.pid//edis以守護進程方式運行時,
redis默認會把pid寫入/var/run/redis.pid文件 port6379//默認端口為6379 bind127.0.0.1 //主機地址,
設置0.0.0.0表示都可以訪問。127.0.0.1表示只允許本機訪問 timeout900//客戶端閑置多長時間后關閉連接,
如果指定為0,表示關閉該功能 logfilestdout//日志記錄方式,
默認為標準輸出 logfile"./redis7001.log"#指明日志文件名 databases16//設置數據庫的數量,
默認數據庫為0 save//有多少次更新操作,就將數據同步到數據文件
Redis默認配置文件中提供了三個條件: save9001//900秒(15分鐘)內有1個更改 save30010//300秒(5分鐘)內
有10個更改 save6010000//60秒內有10000個更改 rdbcompressionyes//指定存儲至本地數據庫時是否壓縮數據 dbfilenamedump.rdb//指定本地數據庫文件名 dir.///指定本地數據庫存放目錄 slaveof//主從同步設置,
設置主數據庫的ip和端口 #如果非零,則設置SO_KEEPALIVE選項來向空閑連接的客戶端發送ACK tcp-keepalive60 #默認如果開啟RDB快照(至少一條save指令)并且最新的后臺保存失敗,
Redis將會停止接受寫操作 #這將使用戶知道數據沒有正確的持久化到硬盤,
否則可能沒人注意到并且造成一些災難 stop-writes-on-bgsave-erroryes #默認如果開啟RDB快照(至少一條save指令)并且最新的后臺保存失敗,
Redis將會停止接受寫操作。 stop-writes-on-bgsave-erroryes #當導出到.rdb數據庫時是否用LZF壓縮字符串對象 rdbcompressionyes #版本5的RDB有一個CRC64算法的校驗和放在了文件的最后。
這將使文件格式更加可靠。 rdbchecksumyes #持久化數據庫的文件名 dbfilenamedump-master.rdb #工作目錄 dir/usr/local/redis-4.0.8/redis_master/ #slav服務連接master的密碼 masterauthtestmaster123 #當一個slave失去和master的連接,
或者同步正在進行中,slave的行為可以有兩種: #1)如果 slave-serve-stale-data 設置為"yes"(默認值),slave會繼續響應客戶端請求,
可能是正常數據,或者是過時了的數據,也可能是還沒獲得值的空數據。 #2)如果slave-serve-stale-data設置為"no",slave會回復"正在從master同步 #(SYNC with master in progress)"來處理各種請求,
除了 INFO 和 SLAVEOF 命令。 slave-serve-stale-datayes #配置是否僅讀 slave-read-onlyyes #如果你選擇“yes”Redis將使用更少的TCP包和帶寬來向slaves發送數據。
但是這將使數據傳輸到slave上有延遲,Linux內核的默認配置會達到40毫秒 #如果你選擇了"no"數據傳輸到salve的延遲將會減少但要使用更多的帶寬 repl-disable-tcp-nodelayno #slave的優先級,
優先級數字小的salve會優先考慮提升為master slave-priority100 #密碼驗證 requirepasstestmaster123 # redis實例最大占用內存,
一旦內存使用達到上限,Redis會根據選定的回收策略(參見: #maxmemmory-policy)刪除key maxmemory3gb #最大內存策略:如果達到內存限制了,Redis如何選擇刪除key。
# volatile-lru ->根據LRU算法刪除帶有過期時間的key。 # allkeys-lru ->根據LRU算法刪除任何key。 # volatile-random ->根據過期設置來隨機刪除key, 具備過期時間的key。
# allkeys->random ->無差別隨機刪, 任何一個key。 #volatile-ttl->根據最近過期時間來刪除(輔以TTL),這是對于有過期時間的key # noeviction ->誰也不刪,直接在寫操作時返回錯誤。
maxmemory-policyvolatile-lru #AOF開啟 appendonlyno #aof文件名 appendfilename"appendonly.aof" # fsync()系統調用告訴操作系統把數據寫到磁盤上,而不是等更多的數據進入輸出緩沖區。
#有些操作系統會真的把數據馬上刷到磁盤上;有些則會盡快去嘗試這么做。 # Redis支持三種不同的模式: # no:不要立刻刷,只有在操作系統需要刷的時候再刷。比較快。 # always:每次寫操作都立刻寫入到aof文件。
慢,但是最安全。 # everysec:每秒寫一次。折中方案。 appendfsynceverysec #如果AOF的同步策略設置成"always"或者"everysec",并且后臺的存儲進程(后臺存儲或寫入AOF #日志)會產生很多磁盤I/O開銷。
某些Linux的配置下會使Redis因為 fsync()系統調用而阻塞很久。 #注意,目前對這個情況還沒有完美修正,甚至不同線程的 fsync()會阻塞我們同步的write(2)調用。 #為了緩解這個問題,可以用下面這個選項。
它可以在 BGSAVE 或 BGREWRITEAOF 處理時阻止主進程進行fsync()。 #這就意味著如果有子進程在進行保存操作,那么Redis就處于"不可同步"的狀態。 #這實際上是說,在最差的情況下可能會丟掉30秒鐘的日志數據。
(默認Linux設定) #如果你有延時問題把這個設置成"yes",否則就保持"no",這是保存持久數據的最安全的方式。
no-appendfsync-on-rewriteyes #自動重寫AOF文件 auto-aof-rewrite-percentage100 auto-aof-rewrite-min-size64mb #AOF文件可能在尾部是不完整的(這跟system關閉有問題,尤其是mountext4文件系統時 #沒有加上data=ordered選項。
只會發生在os死時,redis自己死不會不完整)。 #那redis重啟時load進內存的時候就有問題了。
#發生的時候,可以選擇redis啟動報錯,并且通知用戶和寫日志,或者load盡量多正常的數據。 #如果aof-load-truncated是yes,會自動發布一個log給客戶端然后load(默認)。
#如果是no,用戶必須手動redis-check-aof修復AOF文件才可以。 #注意,如果在讀取的過程中,發現這個aof是損壞的,服務器也是會退出的, #這個選項僅僅用于當服務器嘗試讀取更多的數據但又找不到相應的數據時。
aof-load-truncatedyes #Lua腳本的最大執行時間,毫秒為單位 lua-time-limit5000 #Redis慢查詢日志可以記錄超過指定時間的查詢 slowlog-log-slower-than10000 #這個長度沒有限制。只是要主要會消耗內存。
你可以通過 SLOWLOG RESET 來回收內存。 slowlog-max-len128 #客戶端的輸出緩沖區的限制,
可用于強制斷開那些因為某種原因從服務器讀取數據的速度不夠快的客戶端 client-output-buffer-limitnormal000 client-output-buffer-limitslave256mb64mb60 client-output-buffer-limitpubsub32mb8mb60 #當一個子進程重寫AOF文件時,
文件每生成32M數據會被同步 aof-rewrite-incremental-fsyncyes
由于,單機版的Redis在并發量比較大的時候,并且需要較高性能和可靠性的時候,單機版基本就不適合了,于是就出現了「主從模式」。
主從模式
原理
主從的原理還算是比較簡單的,一主多從,「主數據庫(master)可以讀也可以寫(read/write),從數據庫僅讀(only read)」。
但是,主從模式一般實現「讀寫分離」,「主數據庫僅寫(only write)」,減輕主數據庫的壓力,下面一張圖搞懂主從模式的原理:
主從模式原理就是那么簡單,那他執行的過程(工作機制)又是怎么樣的呢?再來一張圖:
當開啟主從模式的時候,他的具體工作機制如下:
當slave啟動后會向master發送SYNC命令,master節點收到從數據庫的命令后通過bgsave保存快照(「RDB持久化」),并且期間的執行的些命令會被緩存起來。
然后master會將保存的快照發送給slave,并且繼續緩存期間的寫命令。
slave收到主數據庫發送過來的快照就會加載到自己的數據庫中。
最后master講緩存的命令同步給slave,slave收到命令后執行一遍,這樣master與slave數據就保持一致了。
優點
之所以運用主從,是因為主從一定程度上解決了單機版并發量大,導致請求延遲或者redis宕機服務停止的問題。
從數據庫分擔主數據庫的讀壓力,若是主數據庫是只寫模式,那么實現讀寫分離,主數據庫就沒有了讀壓力了。
另一方面解決了單機版單點故障的問題,若是主數據庫掛了,那么從數據庫可以隨時頂上來,綜上來說,主從模式一定程度上提高了系統的可用性和性能,是實現哨兵和集群的基礎。
主從同步以異步方式進行同步,期間Redis仍然可以響應客戶端提交的查詢和更新的請求。
缺點
主從模式好是好,他也有自己的缺點,比如數據的一致性問題,假如主數據庫寫操作完成,那么他的數據會被復制到從數據庫,若是還沒有即使復制到從數據庫,讀請求又來了,此時讀取的數據就不是最新的數據。
若是從主同步的過程網絡出故障了,導致主從同步失敗,也會出現問題數據一致性的問題。
主從模式不具備自動容錯和恢復的功能,一旦主數據庫,從節點晉升為主數據庫的過程需要人為操作,維護的成本就會升高,并且主節點的寫能力、存儲能力都會受到限制。
實操搭建
下面的我們來實操搭建一下主從模式,主從模式的搭建還是比較簡單的,我這里一臺centos 7虛擬機,使用開啟redis多實例的方法搭建主從。
redis中開啟多實例的方法,首先創建一個文件夾,用于存放redis集群的配置文件:
mkdirredis
然后粘貼復制redis.conf配置文件:
cp/root/redis-4.0.6/redis.conf/root/redis/redis-6379.conf cp/root/redis-4.0.6/redis.conf/root/redis/redis-6380.conf cp/root/redis-4.0.6/redis.conf/root/redis/redis-6381.conf
復制三份配置文件,一主兩從,6379端口作為主數據庫(master),6380、6381作為從數據庫(slave)。
首先是配置主數據庫的配置文件:vi redis-6379.conf:
bind0.0.0.0#注釋掉或配置成0.0.0.0表示任意IP均可訪問。 protected-modeno#關閉保護模式,使用密碼訪問。
port6379#設置端口,6380、6381依次為6380、6381。 timeout30#客戶端連接空閑多久后斷開連接,單位秒,0表示禁用 daemonizeyes#在后臺運行 pidfile/var/run/redis_6379.pid#pid進程文件名,
6380、6381依次為redis_6380.pid、redis_6381.pid logfile/root/reids/log/6379.log#日志文件,
6380、6381依次為6380.log、6381.log save9001# 900s內至少一次寫操作則執行bgsave進行RDB持久化 save30010 save6010000 rdbcompressionyes#是否對RDB文件進行壓縮,
建議設置為no,以(磁盤)空間換(CPU)時間 dbfilenamedump.rdb#RDB文件名稱 dir/root/redis/datas#RDB文件保存路徑,
AOF文件也保存在這里 appendonlyyes#表示使用AOF增量持久化的方式 appendfsynceverysec#可選值always,everysec,no,建議設置為everysec requirepass123456#設置密碼
然后,就是修改從數據庫的配置文件,在從數據庫的配置文件中加入以下的配置信息:
slaveof127.0.0.16379#配置master的ip,port masterauth123456#配置訪問master的密碼 slaveof-serve-stale-datano
接下來就是啟動三個redis實例,啟動的命令,先cd到redis的src目錄下,然后執行:
./redis-server/root/redis/6379.conf ./redis-server/root/redis/6380.conf ./redis-server/root/redis/6381.conf
通過命令ps -aux | grep redis,查看啟動的redis進程:
如上圖所示,表示啟動成功,下面就開始進入測試階段。
測試
我這里使用SecureCRT作為redis連接的客戶端,同時啟動三個SecureCRT,分別連接redis1的三個實例,啟動時指定端口以及密碼:
./redis-cli-p6379-a123456
啟動后,在master(6379),輸入:set name 'ldc',在slave中通過get name,可以查看:
數據同步成功,這有幾個坑一個是redis.conf中沒有設置對bind,會導致非本機的ip被過濾掉,一般配置0.0.0.0就可以了。
另一個是沒有配置密碼requirepass 123456,會導致IO一直連接異常,這個是我遇到的坑,后面配置密碼后就成功了。
還有,就是查看redis的啟動日志可以發現有兩個warning,雖然不影響搭建主從同步,看著挺煩人的,但是有些人會遇到,有些人不會遇到。
但是,我這個人比較有強迫癥,百度也是有解決方案的,這里就不講了,交給你們自己解決,這里只是告訴你有這個問題,有些人看都不看日志的,看到啟動成功就認為萬事大吉了,也不看日志,這習慣并不好。
哨兵模式
原理
哨兵模式是主從的升級版,因為主從的出現故障后,不會自動恢復,需要人為干預,這就很蛋疼啊。
在主從的基礎上,實現哨兵模式就是為了監控主從的運行狀況,對主從的健壯進行監控,就好像哨兵一樣,只要有異常就發出警告,對異常狀況進行處理。
所以,總的概括來說,哨兵模式有以下的優點(功能點):
「監控」:監控master和slave是否正常運行,以及哨兵之間也會相互監控
「自動故障恢復」:當master出現故障的時候,會自動選舉一個slave作為master頂上去。
哨兵模式的監控配置信息,是通過配置從數據庫的sentinel monitor
//mymaster表示給master數據庫定義了一個名字,后面的是master的ip和端口,1表示至少需要一個Sentinel進程同意才能將master判斷為失效,如果不滿足這個條件,則自動故障轉移(failover)不會執行 sentinelmonitormymaster127.0.0.163791
節點通信
當然還有其它的配置信息,其它配置信息,在環境搭建的時候再說。當哨兵啟動后,會與master建立一條連接,用于訂閱master的_sentinel_:hello頻道。
該頻道用于獲取監控該master的其它哨兵的信息。并且還會建立一條定時向master發送INFO命令獲取master信息的連接。
「當哨兵與master建立連接后,定期會向(10秒一次)master和slave發送INFO命令,若是master被標記為主觀下線,頻率就會變為1秒一次。」
并且,定期向_sentinel_:hello頻道發送自己的信息,以便其它的哨兵能夠訂閱獲取自己的信息,發送的內容包含「哨兵的ip和端口、運行id、配置版本、master名字、master的ip端口還有master的配置版本」等信息。
以及,「定期的向master、slave和其它哨兵發送PING命令(每秒一次),以便檢測對象是否存活」,若是對方接收到了PING命令,無故障情況下,會回復PONG命令。
所以,哨兵通過建立這兩條連接、通過定期發送INFO、PING命令來實現哨兵與哨兵、哨兵與master之間的通信。
這里涉及到一些概念需要理解,INFO、PING、PONG等命令,后面還會有MEET、FAIL命令,以及主觀下線,當然還會有客觀下線,這里主要說一下這幾個概念的理解:
INFO:該命令可以獲取主從數據庫的最新信息,可以實現新結點的發現
PING:該命令被使用最頻繁,該命令封裝了自身節點和其它節點的狀態數據。
PONG:當節點收到MEET和PING,會回復PONG命令,也把自己的狀態發送給對方。
MEET:該命令在新結點加入集群的時候,會向老節點發送該命令,表示自己是個新人
FAIL:當節點下線,會向集群中廣播該消息。
上線和下線
當哨兵與master相同之后就會定期一直保持聯系,若是某一時刻哨兵發送的PING在指定時間內沒有收到回復(sentinel down-after-milliseconds master-name milliseconds配置),那么發送PING命令的哨兵就會認為該master「主觀下線」(Subjectively Down)。
因為有可能是哨兵與該master之間的網絡問題造成的,而不是master本身的原因,所以哨兵同時會詢問其它的哨兵是否也認為該master下線,若是認為該節點下線的哨兵達到一定的數量(「前面的quorum字段配置」),就會認為該節點「客觀下線」(Objectively Down)。
若是沒有足夠數量的sentinel同意該master下線,則該master客觀下線的標識會被移除;若是master重新向哨兵的PING命令回復了客觀下線的標識也會被移除。
選舉算法
當master被認為客觀下線后,又是怎么進行故障恢復的呢?原來哨兵中首先選舉出一個老大哨兵來進行故障恢復,選舉老大哨兵的算法叫做「Raft算法」:
發現master下線的哨兵(sentinelA)會向其它的哨兵發送命令進行拉票,要求選擇自己為哨兵大佬。
若是目標哨兵沒有選擇其它的哨兵,就會選擇該哨兵(sentinelA)為大佬。
若是選擇sentinelA的哨兵超過半數(半數原則),該大佬非sentinelA莫屬。
如果有多個哨兵同時競選,并且可能存在票數一致的情況,就會等待下次的一個隨機時間再次發起競選請求,進行新的一輪投票,直到大佬被選出來。
選出大佬哨兵后,大佬哨兵就會對故障進行自動回復,從slave中選出一名slave作為主數據庫,選舉的規則如下所示:
所有的slave中slave-priority優先級最高的會被選中。
若是優先級相同,會選擇偏移量最大的,因為偏移量記錄著數據的復制的增量,越大表示數據越完整。
若是以上兩者都相同,選擇ID最小的。
通過以上的層層篩選最終實現故障恢復,當選的slave晉升為master,其它的slave會向新的master復制數據,若是down掉的master重新上線,會被當作slave角色運行。
優點
哨兵模式是主從模式的升級版,所以在系統層面提高了系統的可用性和性能、穩定性。當master宕機的時候,能夠自動進行故障恢復,需不要人為的干預。
哨兵與哨兵之間、哨兵與master之間能夠進行及時的監控,心跳檢測,及時發現系統的問題,這都是彌補了主從的缺點。
缺點
哨兵一主多從的模式同樣也會遇到寫的瓶頸,已經存儲瓶頸,若是master宕機了,故障恢復的時間比較長,寫的業務就會受到影響。
增加了哨兵也增加了系統的復雜度,需要同時維護哨兵模式。
實操搭建
最后,我們進行一下哨兵模式的搭建,配置哨兵模式還是比較簡單的,在上面配置的主從模式的基礎上,同時創建一個文件夾用于存放三個哨兵的配置文件:
mkdir/root/redis-4.0.6/sentinel.conf/root/redis/sentinel/sentinel1.conf mkdir/root/redis-4.0.6/sentinel.conf/root/redis/sentinel/sentinel2.conf mkdir/root/redis-4.0.6/sentinel.conf/root/redis/sentinel/sentinel3.conf
分別在這三個文件中添加如下配置:
daemonizeyes#在后臺運行 sentinelmonitormymaster127.0.0.163791#給master起一個名字mymaster,并且配置master的ip和端口 sentinelauth-passmymaster123456#master的密碼 port26379#另外兩個配置36379,46379端口 sentineldown-after-millisecondsmymaster3000#3s未回復PING就認為master主觀下線 sentinelparallel-syncsmymaster2#執行故障轉移時,最多可以有2個slave實例在同步新的master實例 sentinelfailover-timeoutmymaster100000#如果在10s內未能完成故障轉移操作認為故障轉移失敗
配置完后分別啟動三臺哨兵:
./redis-serversentinel1.conf--sentinel ./redis-serversentinel2.conf--sentinel ./redis-serversentinel3.conf--sentinel
然后通過:ps -aux|grep redis進行查看:
可以看到三臺redis實例以及三個哨兵都已經正常啟動,現登陸6379,通過INFO Repliaction查看master信息:
當前master為6379,然后我們來測試一下哨兵的自動故障恢復,直接kill掉6379進程,然后通過登陸6380再次查看master的信息:
可以看到當前的6380角色是master,并且6380可讀可寫,而不是只讀模式,這說明我們的哨兵是起作用了,搭建成功,感興趣的可以自行搭建,也有可能你會踩一堆的坑。
Cluster模式
最后,Cluster是真正的集群模式了,哨兵解決和主從不能自動故障恢復的問題,但是同時也存在難以擴容以及單機存儲、讀寫能力受限的問題,并且集群之前都是一臺redis都是全量的數據,這樣所有的redis都冗余一份,就會大大消耗內存空間。
集群模式實現了Redis數據的分布式存儲,實現數據的分片,每個redis節點存儲不同的內容,并且解決了在線的節點收縮(下線)和擴容(上線)問題。
集群模式真正意義上實現了系統的高可用和高性能,但是集群同時進一步使系統變得越來越復雜,接下來我們來詳細的了解集群的運作原理。
數據分區原理
集群的原理圖還是很好理解的,在Redis集群中采用的是虛擬槽分區算法,會把redis集群分成16384 個槽(0 -16383)。
比如:下圖所示三個master,會把0 -16383范圍的槽可能分成三部分(0-5000)、(5001-11000)、(11001-16383)分別數據三個緩存節點的槽范圍。
當客戶端請求過來,會首先通過對key進行CRC16 校驗并對 16384 取模(CRC16(key)%16383)計算出key所在的槽,然后再到對應的槽上進行取數據或者存數據,這樣就實現了數據的訪問更新。
之所以進行分槽存儲,是將一整堆的數據進行分片,防止單臺的redis數據量過大,影響性能的問題。
節點通信
節點之間實現了將數據進行分片存儲,那么節點之間又是怎么通信的呢?這個和前面哨兵模式講的命令基本一樣。
首先新上線的節點,會通過 Gossip 協議向老成員發送Meet消息,表示自己是新加入的成員。
老成員收到Meet消息后,在沒有故障的情況下會恢復PONG消息,表示歡迎新結點的加入,除了第一次發送Meet消息后,之后都會發送定期PING消息,實現節點之間的通信。
通信的過程中會為每一個通信的節點開通一條tcp通道,之后就是定時任務,不斷的向其它節點發送PING消息,這樣做的目的就是為了了解節點之間的元數據存儲情況,以及健康狀況,以便即使發現問題。
數據請求
上面說到了槽信息,在Redis的底層維護了unsigned char myslots[CLUSTER_SLOTS/8]一個數組存放每個節點的槽信息。
因為他是一個二進制數組,只有存儲0和1值,如下圖所示:
這樣數組只表示自己是否存儲對應的槽數據,若是1表示存在該數據,0表示不存在該數據,這樣查詢的效率就會非常的高,類似于布隆過濾器,二進制存儲。
比如:集群節點1負責存儲0-5000的槽數據,但是此時只有0、1、2存儲有數據,其它的槽還沒有存數據,所以0、1、2對應的值為1。
并且,每個redis底層還維護了一個clusterNode數組,大小也是16384,用于儲存負責對應槽的節點的ip、端口等信息,這樣每一個節點就維護了其它節點的元數據信息,便于及時的找到對應的節點。
當新結點加入或者節點收縮,通過PING命令通信,及時的更新自己clusterNode數組中的元數據信息,這樣有請求過來也就能及時的找到對應的節點。
有兩種其它的情況就是,若是請求過來發現,數據發生了遷移,比如新節點加入,會使舊的緩存節點數據遷移到新結點。
請求過來發現舊節點已經發生了數據遷移并且數據被遷移到新結點,由于每個節點都有clusterNode信息,通過該信息的ip和端口。此時舊節點就會向客戶端發一個MOVED 的重定向請求,表示數據已經遷移到新結點上,你要訪問這個新結點的ip和端口就能拿到數據,這樣就能重新獲取到數據。
倘若正在發正數據遷移呢?舊節點就會向客戶端發送一個ASK 重定向請求,并返回給客戶端遷移的目標節點的ip和端口,這樣也能獲取到數據。
擴容和收縮
擴容和收縮也就是節點的上線和下線,可能節點發生故障了,故障自動回復的過程(節點收縮)。
節點的收縮和擴容時,會重新計算每一個節點負責的槽范圍,并發根據虛擬槽算法,將對應的數據更新到對應的節點。
還有前面的講的新加入的節點會首先發送Meet消息,詳細可以查看前面講的內容,基本一樣的模式。
以及發生故障后,哨兵老大節點的選舉,master節點的重新選舉,slave怎樣晉升為master節點,可以查看前面哨兵模式選舉過程。
優點
集群模式是一個無中心的架構模式,將數據進行分片,分布到對應的槽中,每個節點存儲不同的數據內容,通過路由能夠找到對應的節點負責存儲的槽,能夠實現高效率的查詢。
并且集群模式增加了橫向和縱向的擴展能力,實現節點加入和收縮,集群模式是哨兵的升級版,哨兵的優點集群都有。
缺點
緩存的最大問題就是帶來數據一致性問題,在平衡數據一致性的問題時,兼顧性能與業務要求,大多數都是以最終一致性的方案進行解決,而不是強一致性。
并且集群模式帶來節點數量的劇增,一個集群模式最少要6臺機,因為要滿足半數原則的選舉方式,所以也帶來了架構的復雜性。
slave只充當冷備,并不能緩解master的讀的壓力。
實操搭建
集群模式的部署比較簡單,只要在redis.conf加入下面的配置信息即可:
port6379#本示例6個節點端口分別為6379、6380、6381、6382、6383、6384 daemonizeyes#r后臺運行 pidfile/var/run/redis_6379.pid#分別對應6379、6380、6381、6382、6383、6384 cluster-enabledyes#開啟集群模式 masterauth123456#如果設置了密碼,需要指定master密碼 cluster-config-filenodes_6379.conf#集群的配置文件,同樣對應6379、6380、6381、6382、6383、6384六個節點 cluster-node-timeout10000#請求超時時間
同時開啟這六個實例,通過下面的命令將這六個實例以集群的方式運行
./redis-cli--clustercreate--cluster-replicas1127.0.0.1:6379127.0.0.1:6380127.0.0.1:6381127.0.0.1:6382127.0.0.1:6383127.0.0.1:6384-a123456
這樣就實現了集群的搭建,好了這一期就完成了,看了一下字數一共1.7W字,原創不易,看完點個在看和分享,不要白嫖我,傳承中華民族的良好美德。
- EOF -
推薦閱讀點擊標題可跳轉
1、還不懂 Redis?看完這個故事就明白了
2、Redis 秒殺實戰
3、天啊,為什么我的 Redis 如此的慢?
責任編輯:xj
原文標題:一文把 Redis 主從復制、哨兵、Cluster 三種模式摸透
文章出處:【微信公眾號:數據分析與開發】歡迎添加關注!文章轉載請注明出處。
-
Cluster
+關注
關注
0文章
7瀏覽量
9137 -
電子哨兵
+關注
關注
0文章
55瀏覽量
7024 -
Redis
+關注
關注
0文章
371瀏覽量
10846
原文標題:一文把 Redis 主從復制、哨兵、Cluster 三種模式摸透
文章出處:【微信號:DBDevs,微信公眾號:數據分析與開發】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論