redis的持久化功能在必定程度上保證了數據的安全性,即使時服務器宕機的狀況下,也能夠保證數據的丟失很是少,一般,爲了不服務的單點故障,會把數據複製到多個副本放在不一樣的服務器上,且這些擁有數據副本的服務器能夠用於處理客戶端的讀請求,擴展總體的性能,下面將介紹redis的主從複製。linux
redis的複製功能是支持多個服務器之間的數據同步。被複制的服務器稱爲主服務器(master),對服務器進行復制操做的爲從服務器(slave),主服務器master能夠進行讀寫操做,當發生寫操做的時候自動將數據同步到從服務器,而從服務器通常是隻讀的,並接收master同步過來的數據,一個master能夠有多個slave,而一個slave只能由一個master。
主從複製的過程:redis
1,從節點執行slaveof命令; 2,從節點只是保存了slavef命令中主節點的信息,並無當即發起複製; 3,從節點內部的定時任務發現由主節點的信息,開始使用socket鏈接主節點; 4,鏈接創建成功後,發送ping命令,但願獲得pong命令響應,不然會進行重連; 5,若是主節點設置了權限,那麼就須要進行權限驗證;若是驗證失敗,複製終止; 6,權限驗證經過後,進行數據同步,這是耗時最長的操做,主節點將把全部的數據所有發送給從節點; 7,當主節點把當前的數據同步給從節點後,便完成了複製的創建流程,主節點就會持續的把寫命令發送給從主節點,保證主從數據一致性;
主從複製的做用:vim
環境描述:安全
主機 | 地址 | 端口 | 操做系統 |
---|---|---|---|
主redis | 172.16.1.100 | 6379 | CentOS 7.3 |
從redis | 172.16.1.110 | 6379 | CentOS 7.3 |
1,部署主節點
1)安裝redis
官網下載地址:http://download.redis.io/releases/
[root@redis-master ~]# tar zxf redis-4.0.14.tar.gz
[root@redis-master ~]# cd redis-4.0.14
[root@redis-master redis-4.0.14]# make && make install
經過上圖,咱們能夠很容易的看出,redis安裝到/usr/local,/usr/local/bin,/usr/local/share,/usr/local/include,/usr/local/lib,/usr/local/share/man目錄下。服務器
而後再切換到utisl目錄下,執行redis初始化腳本install_server.sh,以下:架構
[root@redis-master redis-4.0.14]# cd utils/ [root@redis-master utils]# ./install_server.sh Welcome to the redis service installer This script will help you easily set up a running redis server Please select the redis port for this instance: [6379] Selecting default: 6379 Please select the redis config file name [/etc/redis/6379.conf] Selected default - /etc/redis/6379.conf Please select the redis log file name [/var/log/redis_6379.log] Selected default - /var/log/redis_6379.log Please select the data directory for this instance [/var/lib/redis/6379] Selected default - /var/lib/redis/6379 Please select the redis executable path [/usr/local/bin/redis-server] Selected config: Port : 6379 Config file : /etc/redis/6379.conf Log file : /var/log/redis_6379.log Data dir : /var/lib/redis/6379 Executable : /usr/local/bin/redis-server Cli Executable : /usr/local/bin/redis-cli Is this ok? Then press ENTER to go on or Ctrl-C to abort. Copied /tmp/6379.conf => /etc/init.d/redis_6379 Installing service... Successfully added to chkconfig! Successfully added to runlevels 345! Starting Redis server... Installation successful! #上面所有默認回車就好
過上面的安裝過程,咱們能夠看出redis初始化後redis配置文件爲/etc/redis/6379.conf,日誌文件爲/var/log/redis_6379.log,數據文件dump.rdb存放到/var/lib/redis/6379目錄下,啓動腳本爲/etc/init.d/redis_6379。併發
#初始化完成後,默認已經啓動redis服務了(默認監聽端口6379):負載均衡
[root@redis-master ~]# /etc/init.d/redis_6379 status Redis is running (5693) [root@redis-master ~]# ss -anput | grep redis tcp LISTEN 0 128 127.0.0.1:6379 *:* users:(("redis-server",pid=5693,fd=6))
#防火牆規則設置:socket
[root@redis-master ~]# firewall-cmd --add-port=6379/tcp --permanent success [root@redis-master ~]# firewall-cmd --reload success
2),配置redistcp
[root@redis-master ~]# vim /etc/redis/6379.conf #修改內容以下(去掉註釋並修改): 70 bind 172.16.1.100 #將redis的監聽地址修改成redis主機的ip 501 requirepass pwd@123 #考慮到安全性,須要啓動redis的密碼驗證功能requirepass參數。 137 daemonize yes #以守護進程運行redis實例
#修改完成後,重啓redis:
[root@redis-master ~]# /etc/init.d/redis_6379 restart Stopping ... Waiting for Redis to shutdown ... Redis stopped Starting Redis server... [root@redis-master ~]# ss -anput | grep redis tcp LISTEN 0 128 172.16.1.100:6379 *:* users:(("redis-server",pid=5739,fd=6))
#遠程鏈接redis:
要在redis服務上執行命令須要一個redis客戶端,Redis 客戶端在咱們以前下載的的redis 的安裝包中。
[root@redis-master ~]# redis-cli --version redis-cli 4.0.14 [root@redis-master ~]# redis-cli -h 172.16.1.100 -p 6379 -a pwd@123 Warning: Using a password with '-a' option on the command line interface may not be safe. 172.16.1.100:6379> ping #該命令用於檢測redis服務是否啓動 PONG
2,部署從節點
1)安裝redis的過程與上邊相同,這裏再也不重複。
2)配置redis
[root@redis-slave ~]# vim /etc/redis/6379.conf 70 bind 172.16.1.110 #修改成redis主機的ip 137 daemonize yes #後臺運行 501 requirepass pwd@123 #設置redis的驗證密碼 282 slaveof 172.16.1.100 6379 #這個配置項是主從複製的關鍵,指向master節點的地址和端口 289 masterauth pwd@123 #配置master的受權密碼(若是master沒有設置requirepass選項,從服務器則無需配置)
實際上配置主從複製有三種方法:
① 配置文件中加 slaveof [masterHost] [masterPort] ② redis-server 啓動時加--slaveof [masterHost] [masterPort] ③ 登陸redis直接使用命令 slaveof [masterHost] [masterPort]
#重啓redis服務: [root@redis-slave ~]# /etc/init.d/redis_6379 restart Stopping ... Redis stopped Starting Redis server... [root@redis-slave ~]# ss -anput | grep redis tcp LISTEN 0 128 172.16.1.110:6379 *:* users:(("redis-server",pid=4886,fd=6)) tcp ESTAB 0 0 172.16.1.110:34105 172.16.1.100:6379 users:(("redis-server",pid=4886,fd=7)) #能夠看到多了一個主從複製的進程
#配置防火牆: [root@redis-slave ~]# firewall-cmd --add-port=6379/tcp --permanent success [root@redis-slave ~]# firewall-cmd --reload success
3,測試數據同步
主redis: [root@redis-master ~]# redis-cli -h 172.16.1.100 -p 6379 -a pwd@123 Warning: Using a password with '-a' option on the command line interface may not be safe. 172.16.1.100:6379> set name abc #設置一個key/value OK 172.16.1.100:6379> get name "abc"
從redis: [root@redis-slave ~]# redis-cli -h 172.16.1.110 -p 6379 -a pwd@123 Warning: Using a password with '-a' option on the command line interface may not be safe. 172.16.1.110:6379> get name #數據成功同步 "abc"
4,測試讀寫分離(redis默認就是讀寫分離)
#在從redis上測試: 172.16.1.110:6379> set age 20 (error) READONLY You can't write against a read only slave.
1,中止主redis,模擬故障
[root@redis-master ~]# redis-cli -h 172.16.1.100 -p 6379 -a pwd@123 shutdown [root@redis-master ~]# ss -anput | grep redis [root@redis-master ~]#
2,將從redis設置成主redis(關閉複製功能)
[root@redis-slave ~]# redis-cli -h 172.16.1.110 -p 6379 -a pwd@123 slaveof no one Warning: Using a password with '-a' option on the command line interface may not be safe. OK
3,測試從redis是否切換成主redis
#查看當前主機的角色:
[root@redis-slave ~]# redis-cli -h 172.16.1.110 -p 6379 -a pwd@123 info replication Warning: Using a password with '-a' option on the command line interface may not be safe. # Replication role:master //角色爲master connected_slaves:0 master_replid:51ca62c64f31a7adedfb942a95d01c922f42124b master_replid2:e5a32a89b7806f0fa7954cb0c422172ea889fff0 master_repl_offset:5583 second_repl_offset:5584 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:4607 repl_backlog_histlen:977
#測試讀寫數據:
[root@redis-slave ~]# redis-cli -h 172.16.1.110 -p 6379 -a pwd@123 Warning: Using a password with '-a' option on the command line interface may not be safe. 172.16.1.110:6379> keys * 1) "age" 2) "name" 172.16.1.110:6379> get name "abc" 172.16.1.110:6379> set name zhangsan OK 172.16.1.110:6379> get name "zhangsan"
4,原來的主redis恢復正常了,要從新切換回去
1)將如今的主redis的數據進行保存
172.16.1.110:6379> keys * 1) "age" 2) "name" 172.16.1.110:6379> save OK 172.16.1.110:6379> get name "zhangsan"
2)將如今的主redis根目錄下dump.rdb文件拷貝覆蓋到原來主redis的根目錄 (確保從新運行的master得到redis中最新的數據):[root@redis-slave ~]# scp /var/lib/redis/6379/dump.rdb root@172.16.1.100:/var/lib/redis/6379/
3)啓動原來的主redis:
[root@redis-master ~]# /etc/init.d/redis_6379 start Starting Redis server... [root@redis-master ~]# ss -anput | grep redis tcp LISTEN 0 128 172.16.1.100:6379 *:* users:(("redis-server",pid=19649,fd=6))
4)在如今的主redis中切換:
[root@redis-slave ~]# redis-cli -h 172.16.1.110 -p 6379 -a pwd@123 slaveof 172.16.1.100 6379 Warning: Using a password with '-a' option on the command line interface may not be safe. OK
#查看狀態:
能夠看到如今主redis狀態已經變成了slave
#查看主redis的狀態:
能夠看到狀態已經變成了master,而且數據也是最新的數據,可是這種人工操做的方法在生產環境中,確定是稍顯不足,因此接下來介紹redis哨兵機制。
redis的主從複製模式下,一旦主節點因爲故障不能提供服務,須要人工將從節點晉升爲主節點,同時還要通知應用方更新節點地址,對於不少應用場景這種故障處理的方式是沒法接受的;可喜的是redis從2.8開始開始正式提供了Redis Sentinel(哨兵)機制來解決這個問題。
哨兵機制概述
redis的哨兵(sentinel)系統用於管理多個redis服務器,該系統執行如下三個任務:
1,監控(Monitoring):哨兵會不斷的檢查你的master和slave是否運行正常。
2,提醒(Notification):當被監控的某個redis出現問題時,哨兵能夠經過API向管理員或這其餘應用程序發送通知;
3,自動故障遷移(Automatic failover):當一個master不能正常工做時,哨兵會開始依次自動故行遷移操做,它會將失效master的其中一個slave升級爲新的master,並讓失效master的其餘slave改成複製新的master,當客戶端鏈接失效的master時,集羣也會向客戶端返回新master的地址,使得集羣可使用新的master代替失效的master。
哨兵本質也是一個redis服務,只是跟普通的redis服務提供了不同的功能,哨兵是一個分佈式架構,由於你要保證redis高可用,首先要保證本身高可用,因此咱們須要搭建哨兵的話,至少須要部署三個實例,最好是奇數個,由於在後續的故障轉移中會涉及到投票。
部署sentinel 對redis主從架構進行監控管理
上面咱們的主從架構環境是一主一從,根據哨兵的投票機制,至少要三個實例,因此在原有的環境中添加一臺slave從節點(172.16.1.120)。
步驟省略,參照上面部署從節點的方式進行安裝配置,最終確保可以同步master上面的數據。
2,配置sentinel(三臺主機操做相同)
配置3個哨兵,每一個哨兵的配置都是同樣的。在redis安裝目錄下有一個sentinel.conf文件,copy一份進行修改:
[root@redis-master ~]# cp redis-4.0.14/sentinel.conf /etc/redis/ [root@redis-master ~]# ls /etc/redis/ 6379.conf sentinel.conf [root@redis-master ~]# vim /etc/redis/sentinel.conf 修改內容以下: #綁定redis主機的ip地址,注意:這裏其餘兩臺slave從節點須要指向本身本機地址 bind 172.16.1.100 #端口號,默認是redis實例+20000,因此咱們沿用這個規則就行了 port 26379 #添加守護進程運行 daemonize yes #添加日誌存放的位置,這個很是重要,經過日誌能夠查看故障轉移的過程 logfile "26379.log" #工做目錄(sentinel的相關信息文件都會保存在這,包括日誌文件),這裏保持默認(固然你也能夠自定義路徑) dir /tmp #指定sentinel要監控的redis實例:監視一個名爲mymaster(名字可自定義)的redis服務器,這個地址爲master ip地址 , #最後面的2表明着至少有兩個哨兵認爲主服務器出現故障纔會進行故障轉移,不然認定主服務未失效,通常設置爲N/2+1(N爲哨兵總數)。 sentinel monitor mymaster 172.16.1.100 6379 2 #定義服務的密碼,mymaster是服務的名稱,後面是redis服務器的密碼,若是你的redis沒有設置密碼,則須要關閉保護模式(protected-mode no) sentinel auth-pass mymaster pwd@123 #sentinel判斷服務器失效的響應時間,超過這個時間未接收到服務器的響應,就認爲該服務器失效了 sentinel down-after-milliseconds mymaster 3000 /#完成故障轉移以後,最多多少個從服務器能夠同時發起數據複製(併發數), #數字越小,說明完成所有從服務數據複製的時間越長,數字越大,對主服務器的壓力就變大了 sentinel parallel-syncs mymaster 1 /#故障轉移超時時間,若sentinel在該配置值內未能完成failover操做(即故障時master/slave自動切換),則認爲本次failover失敗。 sentinel failover-timeout mymaster 180000
3,依次啓動哨兵:(兩種方法)
方法1: [root@redis-master ~]# redis-sentinel /etc/redis/sentinel.conf 方法2: [root@redis-master ~]# redis-server /etc/redis/sentinel.conf --sentinel
查看端口是否正常:
其餘兩個slave從節點依次啓動。
注意啓動順序:若是redis和sentinel同時啓動的狀況下,要先啓動redis服務,而後再啓動sentinel。
#配置防火牆:(須要在各節點上開啓哨兵的監聽端口) [root@redis-slave2 ~]# firewall-cmd --add-port=26379/tcp --permanent success [root@redis-slave2 ~]# firewall-cmd --reload fisuccess
#由於哨兵也是redis實例,因此咱們經過如下命令查看當前的哨兵監控的信息:
[root@redis-master ~]# redis-cli -p 26379 -h 172.16.1.100 172.16.1.100:26379> info sentinel # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=172.16.1.100:6379,slaves=2,sentinels=3 #能夠看到當前狀態爲ok,而且監聽的主機是當前master節點,2個從節點,3個哨兵
4,模擬主redis服務器故障,是否正常自動遷移至其餘從服務器,而且從服務器自動提高爲主服務器
#關閉redis服務或者殺掉進程 [root@redis-master ~]# redis-cli -p 6379 -h 172.16.1.100 -a pwd@123 shutdown Warning: Using a password with '-a' option on the command line interface may not be safe. [root@redis-master ~]# ps -ef | grep redis root 19687 1 0 04:35 ? 00:00:00 redis-sentinel 172.16.1.100:26379 [sentinel] root 19700 2242 0 04:39 pts/0 00:00:00 grep --color=auto redis
#查看哨兵的監控信息:
[root@redis-master ~]# redis-cli -h 172.16.1.100 -p 26379 info sentinel # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=172.16.1.110:6379,slaves=2,sentinels=3 #能夠發現當前哨兵監聽的master節點不是原來的了,而是從節點(172.16.1.110)了。
#查看sentinel的日誌信息:
經過日誌信息的能夠知道,原來的master主機已經掛掉了,而且經過sentinel哨兵機制,已經自動切換master到了172.16.1.110從節點了。
#驗證原來從節點是否切換成功:
能夠看到本身從原來的slave狀態切換成了master,而且172.16.1.20是做爲本身的slave節點。
172.16.1.110:6379> keys * 1) "addr" 2) "age" 3) "name" 172.16.1.110:6379> set linux redis OK 172.16.1.110:6379> get linux "redis" //而且能夠正常進行讀寫操做
5,那麼當掛掉的master主節點恢復正常,sentine是否會從新推選爲master呢? 讓咱們來驗證一下:
#從新啓動redis服務: [root@redis-master ~]# /etc/init.d/redis_6379 start Starting Redis server... [root@redis-master ~]# ps -ef | grep redis root 19687 1 0 04:35 ? 00:00:02 redis-sentinel 172.16.1.100:26379 [sentinel] root 19713 1 0 04:57 ? 00:00:00 /usr/local/bin/redis-server 172.16.1.100:6379 root 19718 2242 0 04:57 pts/0 00:00:00 grep --color=auto redis
#查看本身狀態:能夠得知,從新恢復掛掉的mater後,沒法成爲master,只能做爲當前master的slave從節點。但須要注意的是,當掛掉的主機恢復後,哨兵機制並不會幫你還原這段時間丟失的數據,因此,還需將其餘節點的dump.rdb文件作好備份工做,以再恢復後可以導入丟失的數據。