博文大綱:
1、Redis羣集相關概念
2、部署Redis羣集node
- 一、部署環境
- 二、配置Redis實例
- 三、配置node06主機的多Redis實例
- 四、主機node01安裝配置ruby的運行環境,便於管理Redis羣集
- 五、配置羣集中的各個節點
- 六、使用ruby安裝的命令管理Redis羣集
- 七、將node06的6380實例添加節點到Redis羣集中
- 八、爲新加入的master分配從節點
- 九、刪除主節點操做
Redis是從3.0版本開始支持cluter的,採用的是hash槽方式,能夠將多個Redis實例整合在一塊兒,造成一個羣集,也就是將數據分散存儲到羣集中的多個節點上。redis
Redis的cluster是一個無中心的結構,在羣集中,每一個master的身份是平等的,每一個節點都保存數據和整個羣集的狀態,而且知道其餘節點所負責的槽,也會定時發送心跳信息,可以及時感知羣集中異常的節點,而且採起投票的方式來決定該節點是否爲不可用,若票數爲羣集中節點的半數以上,則認爲該節點不可用,也正是由於此特色,因此要部署Redis羣集,節點數量最少要三個及以上。shell
羣集角色有master和slave,master之間分配slots(槽),槽點編號是0-16383(共16384個)。數據庫
默認狀況下,每一個羣集節點有兩個TCP端口在監聽,一個是6379(用於監聽客戶端的訪問鏈接),另外一個是16379(用於羣集之間的節點通訊)。注意,防火牆須要放行這兩個端口的流量。vim
Redis的全部數據都是保存在內存中,而後不按期的經過異步方式保存到磁盤上(這稱爲「半持久化模式」);也能夠把每一次數據變化都寫入到一個append only file(aof)裏面(這稱爲「全持久化模式」)。 centos
Redis提供的這兩種方式進行持久化,一種是RDB持久化(原理是將Redis在內存中的數據庫定時記錄dump到磁盤上的RDB持久化),另外一種是AOF(append only file)持久化(原理是將Redis的操做日誌以追加的方式寫入文件)安全
RDB的優勢與缺點ruby
RDB半持久化的優勢:服務器
- 只包含一個文件,有利於文件備份;
- 災難恢復比aof持久化要快;
- 性能最大化。對於Redis的服務進程而言,在開始持久化時,它惟一須要作的只是fork出子進程,以後再由子進程完成這些持久化的工做,這樣就能夠極大的避免服務進程執行IO操做了。
- 相比較AOF機制,若是數據集過大,RDB的啓動效率會更高。
RDB半持久化的缺點:- 因爲RDB是經過fork子進程來協助完成數據持久化工做的,所以,若是當數據集比較大時,可能會致使整個服務中止幾百毫秒,甚至是1秒鐘。
AOF的優勢與缺點app
AOF全持久化的優勢:
- 能夠保證數據的高可用性;
- 寫入過程當中及時出現宕機現象,也不會破壞日誌文件中已經存在的內容,若是在寫入過程當中宕機,重啓Redis後能夠經過redis-check-aof工具來解決;
- 若是日誌過大,Redis能夠自動啓用rewrite機制,生成新的文件存儲aof日誌;
- 該機制能夠帶來更高的數據安全性,及數據持久性。Redis中提供了三種同步策略,即每秒同步、每修改同步和不一樣步。
AOF全持久化的缺點:- 對於相同數量的數據集而言,AOF文件一般要大於RDB文件。RDB在恢復大數據集時的速度比AOF的恢復速度要快;
- 根據同步策略的不一樣,AOF在運行效率上每每會慢於RDM,總之,每秒同步策略的效率是比較高的,同步禁用策略的效率和RDB同樣高效。
若是RDB和AOF同時存在,則優先選擇AOF方式。
上面共六臺centos服務器,實現三臺master分別對應一臺slave(也能夠在一臺服務器上配置多個Redis實例,但不要master-slave在同一臺物理服務器,可使用交叉master-slave的方式進行主從複製,所謂交叉就是master在node01,但對應的slave在node02,node02上master對應的slave在node03,而node03對應的slave在node01,這樣作的好處是避免由於物理服務器的宕機而形成整個羣集崩潰,這裏只是稍微提示如下,自行研究便可)。
這裏爲了展現同一臺主機上配置多個Redis實例,因此將在node06上配置多個Redis實例,其他節點各負責一個Redis實例便可。
在進行接下來的配置前,請先下載我提供的源碼包(其實,這裏部署的版本是Redis4.0的,版本還低了些,有些方便的配置沒法進行,能夠參考下我那篇部署Redis 5.0的博文)。
這裏以node01的配置進行示例,其餘節點照搬進行配置便可。
[root@node01 ~]# ls | grep redis #在xshell使用rz命令上傳我提供的包,以下: redis-4.0.14.tar.gz [root@node01 ~]# tar zxf redis-4.0.14.tar.gz -C /usr/local/ #解包 [root@node01 ~]# cd /usr/local/ #切換至指定路徑 [root@node01 local]# mv redis-4.0.14 redis #更改目錄名稱 [root@node01 local]# cd redis/ #切換至解壓後的目錄 [root@node01 redis]# make && make install #無需配置,直接編譯安裝便可 [root@node01 redis]# ./utils/install_server.sh #對Redis進行初始化 #初始化的全部選項保持默認,一路回車確認便可 #是在確認監聽端口、配置文件、日誌文件、pid存放路徑等信息 .............#省略部份內容 Successfully added to chkconfig! Successfully added to runlevels 345! Starting Redis server... Installation successful! #出現上述內容,則表示初始化成功 #接下來進行一些優化,以下: [root@node01 redis]# echo "512" > /proc/sys/net/core/somaxconn [root@node01 redis]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf [root@node01 redis]# sysctl -p vm.overcommit_memory = 1 [root@node01 redis]# echo "never" > /sys/kernel/mm/transparent_hugepage/enabled [root@node01 redis]# vim /etc/redis/6379.conf #編輯配置文件,修改以下 bind 0.0.0.0 #找到沒有被註釋的這一行,修改成0.0.0.0 daemonize yes #如有註釋符號,須要刪除註釋符號,以便生效 cluster-enabled yes cluster-node-timeout 5000 appendonly yes #修改完成後,保存退出便可。 [root@node01 redis]# /etc/init.d/redis_6379 restart #重啓Redis服務 [root@node01 redis]# netstat -anpt | grep redis #肯定端口6379及16379處於監聽狀態
在其餘節點服務器上將上述配置依次進行以便,主機node06除外,由於稍後將在node06上展現單臺主機多Redis實例的配置。
node06這個節點上,我將配置其運行多個Redis數據庫實例,因此與前面五個節點的配置並非徹底同樣,請謹慎配置。
[root@node06 ~]# tar zxf redis-4.0.14.tar.gz -C /usr/local/ [root@node06 ~]# cd /usr/local/ [root@node06 local]# mv redis-4.0.14 redis [root@node06 local]# cd redis/ [root@node06 redis]# make && make install #編譯安裝後,無需進行初始化 [root@node06 redis]# redis-server #啓動查看須要優化的項 #在前面幾個節點的優化配置就是今後命令執行後的提示信息得到的 #接下里就優化這些提示的配置咯! [root@node06 redis]# echo "512" > /proc/sys/net/core/somaxconn [root@node06 redis]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf [root@node06 redis]# sysctl -p vm.overcommit_memory = 1 [root@node06 redis]# echo "never" > /sys/kernel/mm/transparent_hugepage/enabled [root@node06 redis]# vim redis.conf #編輯當前目錄下的模板配置文件如下幾項 bind 0.0.0.0 port 6379 daemonize yes #開啓後臺守護進程,以便後臺運行 cluster-enabled yes #開啓羣集 cluster-node-timeout 5000 #羣集節點間的超時時間,單位是毫秒 appendonly yes #是否開啓同步到磁盤 appendfilename "appendonly-6379.aof" #aof日誌的名字 #編輯完成後,保存退出便可 [root@node06 redis]# mkdir -p /usr/local/redis-cluster/{6379..6382} #以上是打算運行幾個Redis實例,就建立幾個目錄便可,這裏我以實例的端口號給目錄命名(暫時打算運行4個Redis實例) #如下是將修改後的配置文件複製到指定的目錄下一份 [root@node06 redis]# cp redis.conf /usr/local/redis-cluster/6379/ [root@node06 redis]# cp redis.conf /usr/local/redis-cluster/6380/ [root@node06 redis]# cp redis.conf /usr/local/redis-cluster/6381/ [root@node06 redis]# cp redis.conf /usr/local/redis-cluster/6382/ #而後下面將複製過去的各個配置文件中改成與Redis實例對應的端口號 [root@node06 redis]# cd /usr/local/redis-cluster/ [root@node06 redis-cluster]# sed -i s/6379/6380/g 6380/redis.conf [root@node06 redis-cluster]# sed -i s/6379/6381/g 6381/redis.conf [root@node06 redis-cluster]# sed -i s/6379/6382/g 6382/redis.conf [root@node06 redis-cluster]# cd 6379 #切換到6379目錄 [root@node06 6379]# redis-server redis.conf #啓動該目錄下的配置文件 101582:C 04 Nov 23:37:04.988 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 101582:C 04 Nov 23:37:04.988 # Redis version=4.0.14, bits=64, commit=00000000, modified=0, pid=101582, just started 101582:C 04 Nov 23:37:04.988 # Configuration loaded #接下來就是依次啓動各個實例 [root@node06 6379]# cd ../6380 [root@node06 6380]# redis-server redis.conf [root@node06 6380]# cd ../6381 [root@node06 6381]# redis-server redis.conf [root@node06 6381]# cd ../6382 [root@node06 6382]# redis-server redis.conf [root@node06 6382]# netstat -anpt | grep redis #查看Redis相關端口的監聽狀況
上述查看Redis端口監聽狀況的返回信息以下:
[root@node01 ~]# yum -y install rpm-build openssl openssl-devel #安裝依賴 [root@node01 ~]# ls | egrep "gem|ruby" #將下面的兩個包上傳至主機node01 redis-3.3.0.gem ruby-2.3.1.tar.gz [root@node01 ~]# tar zxf ruby-2.3.1.tar.gz -C /usr/src #解包 [root@node01 ~]# cd /usr/src/ruby-2.3.1/ #進入解壓後的目錄 [root@node01 ruby-2.3.1]# ./configure --prefix=/usr/local/ruby && make && make install #編譯安裝,時間較長 #下面是對生成的命令作軟鏈接 [root@node01 ruby-2.3.1]# ln -sf /usr/local/ruby/bin/* /usr/local/bin/ [root@node01 ruby-2.3.1]# ln -sf /usr/local/redis/src/redis-trib.rb /usr/local/bin/ [root@node01 ruby-2.3.1]# cd #回到 .gem文件所在目錄 [root@node01 ~]# gem install redis-3.3.0.gem #執行此命令 Successfully installed redis-3.3.0 Parsing documentation for redis-3.3.0 Installing ri documentation for redis-3.3.0 Done installing documentation for redis after 0 seconds 1 gem installed #返回上述信息則表示成功
[root@node01 ~]# redis-cli -p 6379 #登陸到本地Redis實例 #如下是將參與羣集的各個節點添加到羣集中 127.0.0.1:6379> CLUSTER MEET 192.168.20.3 6379 OK 127.0.0.1:6379> CLUSTER MEET 192.168.20.4 6379 OK 127.0.0.1:6379> CLUSTER MEET 192.168.20.5 6379 OK 127.0.0.1:6379> CLUSTER MEET 192.168.20.6 6379 OK 127.0.0.1:6379> CLUSTER MEET 192.168.20.7 6379 OK 127.0.0.1:6379> set a b #雖然節點添加完成,可是因爲沒有分配hash槽,因此沒法添加數據 (error) CLUSTERDOWN Hash slot not served 127.0.0.1:6379> CLUSTER INFO #查看羣集的狀態 cluster_state:fail #是失敗的 192.168.20.3:6379> exit #接下來爲羣集中的節點分配槽點 #必須當心分配,一旦分配錯誤,很麻煩 #雖然能夠將命令中的「add」換爲「del」,可是我沒有成功 #必定要將0至16383徹底分配出去,最好是等份分配 #只需給做爲master的節點分配便可,我這裏node01至node03爲master [root@node01 ~]# redis-cli -h 192.168.20.2 -p 6379 cluster addslots {0..5461} OK [root@node01 ~]# redis-cli -h 192.168.20.3 -p 6379 cluster addslots {5462..10922} OK [root@node01 ~]# redis-cli -h 192.168.20.4 -p 6379 cluster addslots {10923..16383} OK [root@node01 ~]# redis-cli -p 6379 -c #進入羣集,須要加「-c」選項 127.0.0.1:6379> CLUSTER NODES #查看羣集中的節點信息 #接下來是將各個slave從節點與master進行綁定 #node04做爲node01的從節點,node05做爲node02的從節點,node06的6379實例做爲node03的從節點 #須要配置哪一個從節點,就須要登陸到哪一個實例 127.0.0.1:6379> CLUSTER NODES #能夠先執行此命令,查看相應節點的ID,以便接下來指定 [root@node01 ~]# redis-cli -h 192.168.20.5 -p 6379 #登陸到node04 192.168.20.5:6379> CLUSTER REPLICATE 5cd3d0eec161a7bcc785202397fd8363074ae9c2 #上面指定的是node01節點的ID OK 192.168.20.5:6379> exit #退出實例 [root@node01 ~]# redis-cli -h 192.168.20.6 -p 6379 #登陸到node05 192.168.20.6:6379> CLUSTER REPLICATE e2de936c380eb2239f0a349dcbfba5daa74fa1d7 #上述指定的是node02的節點ID OK 192.168.20.6:6379> exit #退出實例 [root@node01 ~]# redis-cli -h 192.168.20.7 -p 6379 #登陸到node06的6379實例 192.168.20.7:6379> CLUSTER REPLICATE dd03b02213df3a91608d1f4ae8080c37f4790d7c #上述是指定node03的節點ID OK 192.168.20.7:6379> exit
配置至此,可再次查看羣集的節點信息,會發現主從之間都對應上了,以下:
至此,羣集便可正常讀寫數據了,以下:
[root@node01 ~]# redis-cli -h 192.168.20.2 -p 6379 -c #登陸到羣集 192.168.20.2:6379> set b c OK
[root@node01 ~]# redis-trib.rb check 127.0.0.1:6379 #檢查羣集的狀態
上述命令返回的信息以下:
[root@node01 ~]# redis-trib.rb add-node 192.168.20.7:6380 192.168.20.2:6379 #在添加節點時,不添加其餘配置,默認加入羣集後,角色是master
返回的提示信息以下則表示成功:
因爲一個羣集若要正常運行,必須將全部的槽點分配出去,因此當有新的節點加入後,須要從新給新加入的節點分配槽點,以下:
[root@node01 ~]# redis-trib.rb check 127.0.0.1:6379 #執行此命令進行確認新加入的節點時master [root@node01 ~]# redis-trib.rb reshard 192.168.20.2:6379 #指定羣集地址及端口 How many slots do you want to move (from 1 to 16384)? 4096 #如果四個master,那麼平均值爲4096,因此這裏輸入4096 What is the receiving node ID? 010752fb2527317a938fcb5b4e73822db805b3a1 #指定接收的節點,也就是新加入的node06主機上6380的那個實例的ID Source node #1:all #指定從哪一個節點的槽點分配,這裏輸入「all」選擇全部節點 Do you want to proceed with the proposed reshard plan (yes/no)? yes #輸入「yes」進行確認
至此,新的節點就添加完成了,而且分配了相應的槽點,可是...尚未從節點,因此接下來爲新加入的master分配一個從節點。
分配從節點的方式有兩種,一種是不指定爲哪一個master的從節點,自動綁定到沒有從節點的master上,一種是直接指定綁定到哪一個master上,這裏將這兩種方式都寫下來。
#方式一: [root@node01 ~]# redis-trib.rb add-node --slave 192.168.20.7:6381 192.168.20.7:6380 #將node06上的6381實例以slave的身份加入到羣集 #注意,返回的信息不可有紅色字樣,那就說明有錯誤 [root@node01 ~]# redis-trib.rb check 192.168.20.2:6379 #查看確認新加入的slave是否與node06的6380master實例綁定 #方式二: [root@node01 ~]# redis-trib.rb add-node --slave --master-id 010752fb2527317a938fcb5b4e73822db805b3a1 192.168.20.7:6382 192.168.20.2:6380 #上述命令指定的ID就是6380實例的master的ID,直接指定爲6380的slave節點 [root@node01 ~]# redis-trib.rb check 192.168.20.2:6379 #查看羣集狀態,能夠看到master6380有兩個slave了,都是上面新加入的slave
刪除主節點的操做其實就是把添加主節點的操做反了過了,須要先將要刪除的主節點上的槽點分配給其餘master,而後才能夠執行刪除操做,而且刪除主節點後,該master對應的slave也將會隨着slots槽進行轉移到新的master上。
這裏以移除node06上的6380實例爲例。
#移除6380實例上的槽點 [root@node01 ~]# redis-trib.rb reshard 192.168.20.2:6379 #指定羣集監聽地址 How many slots do you want to move (from 1 to 16384)? 4096 #輸入要刪除多少槽 What is the receiving node ID? 5cd3d0eec161a7bcc785202397fd8363074ae9c2 #這裏指定的是刪除主節點後,主節點上的槽分配給誰?這裏寫了node02的6379實例的ID Source node #1:010752fb2527317a938fcb5b4e73822db805b3a1 #這裏指定的是要刪除哪一個主節點?指定的ID是node06上6380實例的ID Source node #2:done #輸入done表示結束 Do you want to proceed with the proposed reshard plan (yes/no)? yes #輸入「yes」表示確認 #移除槽點後,接下來將6380實例從羣集中移除,以下: [root@node01 ~]# redis-trib.rb del-node 192.168.20.2:6379 010752fb2527317a938fcb5b4e73822db805b3a1 #上面指定的是6380實例的ID
至此,6380實例就被完全移除羣集了,而且本來與之對應的slave也隨着槽點轉移到node02也一塊兒成爲了node02的slave。如今查看羣集信息,node02的master應該是對應了三個slave。
———————— 本文至此結束,感謝閱讀 ————————