最近在面試過程當中被面試官問到 Redis 集羣數據是如何複製的,因爲以前沒有準備直接懵了。過後查了查這個問題其實也挺簡單,若是你以前也不知道,沒問題,趕忙淺嘗輒止,速度3遍便可入門。html
閱讀本文,你可能會有哪些收穫呢?前端
Redis 支持三種集羣方案node
經過持久化功能,Redis保證了即便在服務器重啓的狀況下也不會丟失(或少許丟失)數據,由於持久化會把內存中數據保存到硬盤上,重啓會從硬盤上加載數據。 可是因爲數據是存儲在一臺服務器上的,若是這臺服務器出現硬盤故障等問題,也會致使數據丟失。linux
爲了不單點故障,一般的作法是將數據庫複製多個副本以部署在不一樣的服務器上,這樣即便有一臺服務器出現故障,其餘服務器依然能夠繼續提供服務。nginx
爲此, Redis 提供了複製(replication)功能,能夠實現當一臺數據庫中的數據更新後,自動將更新的數據同步到其餘數據庫上。面試
在複製的概念中,數據庫分爲兩類,一類是主數據庫(master),另外一類是從數據庫(slave)。主數據庫能夠進行讀寫操做,當寫操做致使數據變化時會自動將數據同步給從數據庫。而從數據庫通常是隻讀的,並接受主數據庫同步過來的數據。一個主數據庫能夠擁有多個從數據庫,而一個從數據庫只能擁有一個主數據庫。redis
總結:引入主從複製機制的目的有兩個算法
主從複製優勢shell
主從複製缺點數據庫
第一種主從同步/複製的模式,當主服務器宕機後,須要手動把一臺從服務器切換爲主服務器,這就須要人工干預,費事費力,還會形成一段時間內服務不可用。這不是一種推薦的方式,更多時候,咱們優先考慮哨兵模式。
哨兵模式是一種特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一個獨立的進程,做爲進程,它會獨立運行。其原理是哨兵經過發送命令,等待Redis服務器響應,從而監控運行的多個 Redis 實例。
然而一個哨兵進程對Redis服務器進行監控,也可能會出現問題,爲此,咱們可使用多個哨兵進行監控。各個哨兵之間還會進行監控,這樣就造成了多哨兵模式。
假設主服務器宕機,哨兵1先檢測到這個結果,系統並不會立刻進行 failover 過程,僅僅是哨兵1主觀的認爲主服務器不可用,這個現象成爲主觀下線。當後面的哨兵也檢測到主服務器不可用,而且數量達到必定值時,那麼哨兵之間就會進行一次投票,投票的結果由一個哨兵發起,進行 failover 操做。切換成功後,就會經過發佈訂閱模式,讓各個哨兵把本身監控的從服務器實現切換主機,這個過程稱爲客觀下線。這樣對於客戶端而言,一切都是透明的。
優勢:
缺點:
Redis Cluster是一種服務器 Sharding 技術,3.0版本開始正式提供。
Redis 的哨兵模式基本已經能夠實現高可用,讀寫分離 ,可是在這種模式下每臺 Redis 服務器都存儲相同的數據,很浪費內存,因此在 redis3.0上加入了 Cluster 集羣模式,實現了 Redis 的分佈式存儲,也就是說每臺 Redis 節點上存儲不一樣的內容。
在這個圖中,每個藍色的圈都表明着一個 redis 的服務器節點。它們任何兩個節點之間都是相互連通的。客戶端能夠與任何一個節點相鏈接,而後就能夠訪問集羣中的任何一個節點。對其進行存取和其餘操做。
Redis 集羣沒有使用一致性 hash,而是引入了哈希槽【hash slot】的概念。
Redis 集羣有16384 個哈希槽,每一個 key 經過 CRC16 校驗後對 16384 取模來決定放置哪一個槽。集羣的每一個節點負責一部分hash槽,舉個例子,好比當前集羣有3個節點,那麼:
這種結構很容易添加或者刪除節點。好比若是我想新添加個節點 D , 我須要從節點 A, B, C 中得部分槽到 D 上。若是我想移除節點 A ,須要將 A 中的槽移到 B 和 C 節點上,而後將沒有任何槽的 A 節點從集羣中移除便可。因爲從一個節點將哈希槽移動到另外一個節點並不會中止服務,因此不管添加刪除或者改變某個節點的哈希槽的數量都不會形成集羣不可用的狀態。
在 Redis 的每個節點上,都有這麼兩個東西,一個是插槽(slot),它的的取值範圍是:0-16383。還有一個就是 cluster,能夠理解爲是一個集羣管理的插件。當咱們的存取的 Key到達的時候,Redis 會根據 CRC16 的算法得出一個結果,而後把結果對 16384 求餘數,這樣每一個 key 都會對應一個編號在 0-16383 之間的哈希槽,經過這個值,去找到對應的插槽所對應的節點,而後直接自動跳轉到這個對應的節點上進行存取操做。
爲了保證高可用,redis-cluster集羣引入了主從複製模型,一個主節點對應一個或者多個從節點,當主節點宕機的時候,就會啓用從節點。當其它主節點 ping 一個主節點 A 時,若是半數以上的主節點與 A 通訊超時,那麼認爲主節點 A 宕機了。若是主節點 A 和它的從節點 A1 都宕機了,那麼該集羣就沒法再提供服務了。
理論課結束了,不如實操下感覺一下?
前提條件
# redis 準備 $ cd /opt $ wget http://download.redis.io/releases/redis-5.0.5.tar.gz $ tar xzf redis-5.0.5.tar.gz $ cd redis-5.0.5 $ make $ make install
生產環境作集羣通常會採用多個獨立主機,這裏作演示在一臺虛擬機上同時運行多個節點的,這點注意一下。
主要有兩步
節點 | 配置文件 | 端口 |
---|---|---|
master | redis6379.conf | 6379 |
slave1 | redis6380.conf | 6380 |
slave1 | redis6381.conf | 6380 |
內容以下
# redis6379.conf master # 包含命令,有點複用的意思 include /opt/redis-5.0.5/redis.conf pidfile /var/run/redis_6379.pid port 6379 dbfilename dump6379.rdb logfile "my-redis-6379.log" # redis6380.conf slave1 include /opt/redis-5.0.5/redis.conf pidfile /var/run/redis_6380.pid port 6380 dbfilename dump6380.rdb logfile "my-redis-6380.log" # 最後一行設置了主節點的 ip 端口 replicaof 127.0.0.1 6379 # redis6381.conf slave2 include /opt/redis-5.0.5/redis.conf pidfile /var/run/redis_6381.pid port 6381 dbfilename dump6381.rdb logfile "my-redis-6381.log" # 最後一行設置了主節點的 ip 端口 replicaof 127.0.0.1 6379 ## 注意 redis.conf 要調整一項,設置後臺運行,對我們操做比較友好 daemonize yes
啓動節點,而後查看節點信息
# 順序啓動節點 $ redis-server redis6379.conf $ redis-server redis6380.conf $ redis-server redis6381.conf # 進入redis 客戶端,開多個窗口查看方便些 $ redis-cli -p 6379 $ info replication
info replication 命令能夠查看鏈接該數據庫的其它庫的信息,可看到有兩個 slave 鏈接到 master
在 master 節點設置值,在 slave1/slave2 節點能夠查看數據同步狀況
# master $ redis-cli -p 6379 127.0.0.1:6379> set k1 v1 OK # slave1 $ redis-cli -p 6380 127.0.0.1:6380> get k1 "v1"
上面也說了哨兵其實主動複製的自動版,因此須要先配置好主從複製,不一樣點在於要增長几個哨兵進行監控。
主要有兩步:
通常來講,哨兵模式的集羣是:一主,二從,三哨兵。
那我們就來演示一下三個哨兵的集羣。
節點 | 配置 | 端口 |
---|---|---|
master | redis6379.conf | 6379 |
slave1 | redis6380.conf | 6380 |
slave2 | redis6381.conf | 6381 |
sentinel1 | sentinel1.conf | 26379 |
sentinel2 | sentinel2.conf | 26380 |
sentinel3 | sentinel3.conf | 26381 |
哨兵的配置其實跟 redis.conf 有點像,能夠看一下自帶的 sentinel.conf
這裏我們建立三個哨兵文件, 哨兵文件的區別在於啓動端口不一樣
# 文件內容 # sentinel1.conf port 26379 sentinel monitor mymaster 127.0.0.1 6379 1 # sentinel2.conf port 26380 sentinel monitor mymaster 127.0.0.1 6379 1 # sentinel3.conf port 26381 sentinel monitor mymaster 127.0.0.1 6379 1
先把 master-slave 啓動!
而後,挨個把三個都啓動了
$ redis-sentinel sentinel1.conf $ redis-sentinel sentinel2.conf $ redis-sentinel sentinel3.conf
啓動以後日誌以下,能夠看到監聽到的主/從節點狀況以及哨兵集羣狀況
咱們在 master(6379) 節點 執行 shutdown
,而後觀察哨兵會幫我作什麼?
能夠看到哨兵掃描到了 master 下線, 而後通過一系列判斷,投票等操做從新選舉了master(6381) 節點
能夠查看到,6381 已成爲 master
而後咱們能夠看到, 即便咱們把原 master 節點恢復運行, 它也只是 slave 身份了存在了, 失去了大哥的身份, 可謂是風水輪流轉了
Redis 的 Cluster 集羣模式, 啓動還挺簡單
主要有兩步
根據官方推薦,集羣部署至少要 3 臺以上的master節點,最好使用 3 主 3 從六個節點的模式。
節點 | 配置 | 端口 |
---|---|---|
cluster-master1 | redis7001.conf | 7001 |
cluster-master2 | redis7002.conf | 7002 |
cluster-master3 | redis7003.conf | 7003 |
cluster-slave1 | redis7004.conf | 7004 |
cluster-slave2 | redis7006.conf | 7005 |
cluster-slave3 | redis7006.conf | 7006 |
我們準備 6 個配置文件 ,端口 7001,7002,7003,7004,7005,7006
分別命名成 redis7001.conf ......redis7006.conf
redis7001.conf 配置文件內容以下(記得複製6份並替換端口號)
# 端口 port 7001 # 啓用集羣模式 cluster-enabled yes # 根據你啓用的節點來命名,最好和端口保持一致,這個是用來保存其餘節點的名稱,狀態等信息的 cluster-config-file nodes_7001.conf # 超時時間 cluster-node-timeout 5000 appendonly yes # 後臺運行 daemonize yes # 非保護模式 protected-mode no pidfile /var/run/redis_7001.pid
redis-server redis7001.conf ... redis-server redis7006.conf
看如下啓動狀況
# 執行命令 # --cluster-replicas 1 命令的意思是建立master的時候同時建立一個slave $ redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluste r-replicas 1
# 執行成功結果以下 # 咱們能夠看到 7001,7002,7003 成爲了 master 節點, # 分別佔用了 slot [0-5460],[5461-10922],[10923-16383] >>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 127.0.0.1:7005 to 127.0.0.1:7001 Adding replica 127.0.0.1:7006 to 127.0.0.1:7002 Adding replica 127.0.0.1:7004 to 127.0.0.1:7003 >>> Trying to optimize slaves allocation for anti-affinity [WARNING] Some slaves are in the same host as their master M: 0313641a28e42014a48cdaee47352ce88a2ae083 127.0.0.1:7001 slots:[0-5460] (5461 slots) master M: 4ada3ff1b6dbbe57e7ba94fe2a1ab4a22451998e 127.0.0.1:7002 slots:[5461-10922] (5462 slots) master M: 719b2f9daefb888f637c5dc4afa2768736241f74 127.0.0.1:7003 slots:[10923-16383] (5461 slots) master S: 987b3b816d3d1bb07e6c801c5048b0ed626766d4 127.0.0.1:7004 replicates 4ada3ff1b6dbbe57e7ba94fe2a1ab4a22451998e S: a876e977fc2ff9f18765a89c12fbd2c5b5b1f3bf 127.0.0.1:7005 replicates 719b2f9daefb888f637c5dc4afa2768736241f74 S: ac8d6c4067dec795168ca705bf16efaa5f04095a 127.0.0.1:7006 replicates 0313641a28e42014a48cdaee47352ce88a2ae083 Can I set the above configuration? (type 'yes' to accept): yes # 這裏有個要手動輸入 yes 確認的過程 >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join ... >>> Performing Cluster Check (using node 127.0.0.1:7001) M: 0313641a28e42014a48cdaee47352ce88a2ae083 127.0.0.1:7001 slots:[0-5460] (5461 slots) master 1 additional replica(s) M: 4ada3ff1b6dbbe57e7ba94fe2a1ab4a22451998e 127.0.0.1:7002 slots:[5461-10922] (5462 slots) master 1 additional replica(s) S: ac8d6c4067dec795168ca705bf16efaa5f04095a 127.0.0.1:7006 slots: (0 slots) slave replicates 0313641a28e42014a48cdaee47352ce88a2ae083 S: a876e977fc2ff9f18765a89c12fbd2c5b5b1f3bf 127.0.0.1:7005 slots: (0 slots) slave replicates 719b2f9daefb888f637c5dc4afa2768736241f74 M: 719b2f9daefb888f637c5dc4afa2768736241f74 127.0.0.1:7003 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: 987b3b816d3d1bb07e6c801c5048b0ed626766d4 127.0.0.1:7004 slots: (0 slots) slave replicates 4ada3ff1b6dbbe57e7ba94fe2a1ab4a22451998e [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
# 注意 集羣模式下要帶參數 -c,表示集羣,不然不能正常存取數據!!! [root@localhost redis-5.0.5]# redis-cli -p 7100 -c # 設置 k1 v1 127.0.0.1:7001> set k1 v1 -> Redirected to slot [12706] located at 127.0.0.1:7003 OK # 這能夠看到集羣的特色:把數據存到計算得出的 slot,這裏還自動跳到了 7003 127.0.0.1:7003> get k1 "v1" # 咱們還回到 7001 獲取 k1 試試 [root@localhost redis-5.0.5]# redis-cli -p 7001 -c 127.0.0.1:7001> get k1 -> Redirected to slot [12706] located at 127.0.0.1:7003 "v1" # 咱們能夠看到重定向的過程 127.0.0.1:7003>
Docker 版 ?
也許會弄
B站-尚硅谷周陽老師的視頻課--推薦新手看一看,對實操有幫助
到這裏關於 Redis 的集羣模式就瞭解的差很少了,完結,撒花 ~不要只看不敲哦,只看或者只收藏不敲等於耍流氓 !