這篇文章主要為大家詳細(xì)介紹了redis主從復(fù)制的含義和使用方法,圖文詳解容易學(xué)習(xí),配合代碼閱讀理解效果更佳,非常適合初學(xué)者入門,感興趣的小伙伴們可以參考一下。
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供君山網(wǎng)站建設(shè)、君山做網(wǎng)站、君山網(wǎng)站設(shè)計(jì)、君山網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、君山企業(yè)網(wǎng)站模板建站服務(wù),十載君山做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
redis的復(fù)制功能是支持多個(gè)服務(wù)器之間的數(shù)據(jù)同步。被復(fù)制的服務(wù)器稱為主服務(wù)器(master),對(duì)服務(wù)器進(jìn)行復(fù)制操作的為從服務(wù)器(slave),主服務(wù)器master可以進(jìn)行讀寫操作,當(dāng)發(fā)生寫操作的時(shí)候自動(dòng)將數(shù)據(jù)同步到從服務(wù)器,而從服務(wù)器一般是只讀的,并接收master同步過(guò)來(lái)的數(shù)據(jù),一個(gè)master可以有多個(gè)slave,而一個(gè)slave只能由一個(gè)master。
主從復(fù)制的過(guò)程:
1,從節(jié)點(diǎn)執(zhí)行slaveof命令;
2,從節(jié)點(diǎn)只是保存了slavef命令中主節(jié)點(diǎn)的信息,并沒(méi)有立即發(fā)起復(fù)制;
3,從節(jié)點(diǎn)內(nèi)部的定時(shí)任務(wù)發(fā)現(xiàn)由主節(jié)點(diǎn)的信息,開始使用socket連接主節(jié)點(diǎn);
4,連接建立成功后,發(fā)送ping命令,希望得到pong命令響應(yīng),否則會(huì)進(jìn)行重連;
5,如果主節(jié)點(diǎn)設(shè)置了權(quán)限,那么就需要進(jìn)行權(quán)限驗(yàn)證;如果驗(yàn)證失敗,復(fù)制終止;
6,權(quán)限驗(yàn)證通過(guò)后,進(jìn)行數(shù)據(jù)同步,這是耗時(shí)最長(zhǎng)的操作,主節(jié)點(diǎn)將把所有的數(shù)據(jù)全部發(fā)送給從節(jié)點(diǎn);
7,當(dāng)主節(jié)點(diǎn)把當(dāng)前的數(shù)據(jù)同步給從節(jié)點(diǎn)后,便完成了復(fù)制的建立流程,主節(jié)點(diǎn)就會(huì)持續(xù)的把寫命令發(fā)送給從主節(jié)點(diǎn),保證主從數(shù)據(jù)一致性;
主從復(fù)制的作用:
環(huán)境描述:
主機(jī) | 地址 | 端口 | 操作系統(tǒng) |
---|---|---|---|
主redis | 172.16.1.100 | 6379 | CentOS 7.3 |
從redis | 172.16.1.110 | 6379 | CentOS 7.3 |
1,部署主節(jié)點(diǎn)
1)安裝redis
官網(wǎng)下載地址: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
通過(guò)上圖,我們可以很容易的看出,redis安裝到/usr/local,/usr/local/bin,/usr/local/share,/usr/local/include,/usr/local/lib,/usr/local/share/man目錄下。
然后再切換到utisl目錄下,執(zhí)行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!
#上面全部默認(rèn)回車就好
過(guò)上面的安裝過(guò)程,我們可以看出redis初始化后redis配置文件為/etc/redis/6379.conf,日志文件為/var/log/redis_6379.log,數(shù)據(jù)文件dump.rdb存放到/var/lib/redis/6379目錄下,啟動(dòng)腳本為/etc/init.d/redis_6379。
#初始化完成后,默認(rèn)已經(jīng)啟動(dòng)redis服務(wù)了(默認(rèn)監(jiān)聽端口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))
#防火墻規(guī)則設(shè)置:
[root@redis-master ~]# firewall-cmd --add-port=6379/tcp --permanent
success
[root@redis-master ~]# firewall-cmd --reload
success
2),配置redis
[root@redis-master ~]# vim /etc/redis/6379.conf
#修改內(nèi)容如下(去掉注釋并修改):
70 bind 172.16.1.100 #將redis的監(jiān)聽地址修改為redis主機(jī)的ip
501 requirepass pwd@123 #考慮到安全性,需要啟動(dòng)redis的密碼驗(yàn)證功能requirepass參數(shù)。
137 daemonize yes #以守護(hù)進(jìn)程運(yùn)行redis實(shí)例
#修改完成后,重啟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))
#遠(yuǎn)程連接redis:
要在redis服務(wù)上執(zhí)行命令需要一個(gè)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 #該命令用于檢測(cè)redis服務(wù)是否啟動(dòng)
PONG
2,部署從節(jié)點(diǎn)
1)安裝redis的過(guò)程與上邊相同,這里不再重復(fù)。
2)配置redis
[root@redis-slave ~]# vim /etc/redis/6379.conf
70 bind 172.16.1.110 #修改為redis主機(jī)的ip
137 daemonize yes #后臺(tái)運(yùn)行
501 requirepass pwd@123 #設(shè)置redis的驗(yàn)證密碼
282 slaveof 172.16.1.100 6379 #這個(gè)配置項(xiàng)是主從復(fù)制的關(guān)鍵,指向master節(jié)點(diǎn)的地址和端口
289 masterauth pwd@123 #配置master的授權(quán)密碼(如果master沒(méi)有設(shè)置requirepass選項(xiàng),從服務(wù)器則無(wú)需配置)
實(shí)際上配置主從復(fù)制有三種方法:
① 配置文件中加 slaveof [masterHost] [masterPort]
② redis-server 啟動(dòng)時(shí)加--slaveof [masterHost] [masterPort]
③ 登錄redis直接使用命令 slaveof [masterHost] [masterPort]
#重啟redis服務(wù):
[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))
#可以看到多了一個(gè)主從復(fù)制的進(jìn)程
#配置防火墻:
[root@redis-slave ~]# firewall-cmd --add-port=6379/tcp --permanent
success
[root@redis-slave ~]# firewall-cmd --reload
success
3,測(cè)試數(shù)據(jù)同步
主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 #設(shè)置一個(gè)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 #數(shù)據(jù)成功同步
"abc"
4,測(cè)試讀寫分離(redis默認(rèn)就是讀寫分離)
#在從redis上測(cè)試:
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設(shè)置成主redis(關(guān)閉復(fù)制功能)
[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,測(cè)試從redis是否切換成主redis
#查看當(dāng)前主機(jī)的角色:
[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
#測(cè)試讀寫數(shù)據(jù):
[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,原來(lái)的主redis恢復(fù)正常了,要重新切換回去
1)將現(xiàn)在的主redis的數(shù)據(jù)進(jìn)行保存
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)將現(xiàn)在的主redis根目錄下dump.rdb文件拷貝覆蓋到原來(lái)主redis的根目錄 (確保重新運(yùn)行的master獲得redis中最新的數(shù)據(jù)):[root@redis-slave ~]# scp /var/lib/redis/6379/dump.rdb root@172.16.1.100:/var/lib/redis/6379/
3)啟動(dòng)原來(lái)的主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)在現(xiàn)在的主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
#查看狀態(tài):
可以看到現(xiàn)在主redis狀態(tài)已經(jīng)變成了slave
#查看主redis的狀態(tài):
可以看到狀態(tài)已經(jīng)變成了master,并且數(shù)據(jù)也是最新的數(shù)據(jù),但是這種人工操作的方法在生產(chǎn)環(huán)境中,肯定是稍顯不足,所以接下來(lái)介紹redis哨兵機(jī)制。
redis的主從復(fù)制模式下,一旦主節(jié)點(diǎn)由于故障不能提供服務(wù),需要人工將從節(jié)點(diǎn)晉升為主節(jié)點(diǎn),同時(shí)還要通知應(yīng)用方更新節(jié)點(diǎn)地址,對(duì)于很多應(yīng)用場(chǎng)景這種故障處理的方式是無(wú)法接受的;可喜的是redis從2.8開始開始正式提供了Redis Sentinel(哨兵)機(jī)制來(lái)解決這個(gè)問(wèn)題。
哨兵機(jī)制概述
redis的哨兵(sentinel)系統(tǒng)用于管理多個(gè)redis服務(wù)器,該系統(tǒng)執(zhí)行以下三個(gè)任務(wù):
1,監(jiān)控(Monitoring):哨兵會(huì)不斷的檢查你的master和slave是否運(yùn)行正常。
2,提醒(Notification):當(dāng)被監(jiān)控的某個(gè)redis出現(xiàn)問(wèn)題時(shí),哨兵可以通過(guò)API向管理員或這其他應(yīng)用程序發(fā)送通知;
3,自動(dòng)故障遷移(Automatic failover):當(dāng)一個(gè)master不能正常工作時(shí),哨兵會(huì)開始依次自動(dòng)故行遷移操作,它會(huì)將失效master的其中一個(gè)slave升級(jí)為新的master,并讓失效master的其他slave改為復(fù)制新的master,當(dāng)客戶端連接失效的master時(shí),集群也會(huì)向客戶端返回新master的地址,使得集群可以使用新的master代替失效的master。
哨兵本質(zhì)也是一個(gè)redis服務(wù),只是跟普通的redis服務(wù)提供了不一樣的功能,哨兵是一個(gè)分布式架構(gòu),因?yàn)槟阋WCredis高可用,首先要保證自己高可用,所以我們需要搭建哨兵的話,至少需要部署三個(gè)實(shí)例,最好是奇數(shù)個(gè),因?yàn)樵诤罄m(xù)的故障轉(zhuǎn)移中會(huì)涉及到投票。
部署sentinel 對(duì)redis主從架構(gòu)進(jìn)行監(jiān)控管理
上面我們的主從架構(gòu)環(huán)境是一主一從,根據(jù)哨兵的投票機(jī)制,至少要三個(gè)實(shí)例,所以在原有的環(huán)境中添加一臺(tái)slave從節(jié)點(diǎn)(172.16.1.120)。
步驟省略,參照上面部署從節(jié)點(diǎn)的方式進(jìn)行安裝配置,最終確保能夠同步master上面的數(shù)據(jù)。
2,配置sentinel(三臺(tái)主機(jī)操作相同)
配置3個(gè)哨兵,每個(gè)哨兵的配置都是一樣的。在redis安裝目錄下有一個(gè)sentinel.conf文件,copy一份進(jìn)行修改:
[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
修改內(nèi)容如下:
#綁定redis主機(jī)的ip地址,注意:這里其他兩臺(tái)slave從節(jié)點(diǎn)需要指向自己本機(jī)地址
bind 172.16.1.100
#端口號(hào),默認(rèn)是redis實(shí)例+20000,所以我們沿用這個(gè)規(guī)則就好了
port 26379
#添加守護(hù)進(jìn)程運(yùn)行
daemonize yes
#添加日志存放的位置,這個(gè)非常重要,通過(guò)日志可以查看故障轉(zhuǎn)移的過(guò)程
logfile "26379.log"
#工作目錄(sentinel的相關(guān)信息文件都會(huì)保存在這,包括日志文件),這里保持默認(rèn)(當(dāng)然你也可以自定義路徑)
dir /tmp
#指定sentinel要監(jiān)控的redis實(shí)例:監(jiān)視一個(gè)名為mymaster(名字可自定義)的redis服務(wù)器,這個(gè)地址為master ip地址 ,
#最后面的2代表著至少有兩個(gè)哨兵認(rèn)為主服務(wù)器出現(xiàn)故障才會(huì)進(jìn)行故障轉(zhuǎn)移,否則認(rèn)定主服務(wù)未失效,一般設(shè)置為N/2+1(N為哨兵總數(shù))。
sentinel monitor mymaster 172.16.1.100 6379 2
#定義服務(wù)的密碼,mymaster是服務(wù)的名稱,后面是redis服務(wù)器的密碼,如果你的redis沒(méi)有設(shè)置密碼,則需要關(guān)閉保護(hù)模式(protected-mode no)
sentinel auth-pass mymaster pwd@123
#sentinel判斷服務(wù)器失效的響應(yīng)時(shí)間,超過(guò)這個(gè)時(shí)間未接收到服務(wù)器的響應(yīng),就認(rèn)為該服務(wù)器失效了
sentinel down-after-milliseconds mymaster 3000
/#完成故障轉(zhuǎn)移之后,最多多少個(gè)從服務(wù)器可以同時(shí)發(fā)起數(shù)據(jù)復(fù)制(并發(fā)數(shù)),
#數(shù)字越小,說(shuō)明完成全部從服務(wù)數(shù)據(jù)復(fù)制的時(shí)間越長(zhǎng),數(shù)字越大,對(duì)主服務(wù)器的壓力就變大了
sentinel parallel-syncs mymaster 1
/#故障轉(zhuǎn)移超時(shí)時(shí)間,若sentinel在該配置值內(nèi)未能完成failover操作(即故障時(shí)master/slave自動(dòng)切換),則認(rèn)為本次failover失敗。
sentinel failover-timeout mymaster 180000
3,依次啟動(dòng)哨兵:(兩種方法)
方法1:
[root@redis-master ~]# redis-sentinel /etc/redis/sentinel.conf
方法2:
[root@redis-master ~]# redis-server /etc/redis/sentinel.conf --sentinel
查看端口是否正常:
其他兩個(gè)slave從節(jié)點(diǎn)依次啟動(dòng)。
注意啟動(dòng)順序:如果redis和sentinel同時(shí)啟動(dòng)的情況下,要先啟動(dòng)redis服務(wù),然后再啟動(dòng)sentinel。
#配置防火墻:(需要在各節(jié)點(diǎn)上開啟哨兵的監(jiān)聽端口)
[root@redis-slave2 ~]# firewall-cmd --add-port=26379/tcp --permanent
success
[root@redis-slave2 ~]# firewall-cmd --reload
fisuccess
#因?yàn)樯诒彩莚edis實(shí)例,所以我們通過(guò)以下命令查看當(dāng)前的哨兵監(jiān)控的信息:
[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
#可以看到當(dāng)前狀態(tài)為ok,并且監(jiān)聽的主機(jī)是當(dāng)前master節(jié)點(diǎn),2個(gè)從節(jié)點(diǎn),3個(gè)哨兵
4,模擬主redis服務(wù)器故障,是否正常自動(dòng)遷移至其他從服務(wù)器,并且從服務(wù)器自動(dòng)提升為主服務(wù)器
#關(guān)閉redis服務(wù)或者殺掉進(jìn)程
[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
#查看哨兵的監(jiān)控信息:
[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
#可以發(fā)現(xiàn)當(dāng)前哨兵監(jiān)聽的master節(jié)點(diǎn)不是原來(lái)的了,而是從節(jié)點(diǎn)(172.16.1.110)了。
#查看sentinel的日志信息:
通過(guò)日志信息的可以知道,原來(lái)的master主機(jī)已經(jīng)掛掉了,并且通過(guò)sentinel哨兵機(jī)制,已經(jīng)自動(dòng)切換master到了172.16.1.110從節(jié)點(diǎn)了。
#驗(yàn)證原來(lái)從節(jié)點(diǎn)是否切換成功:
可以看到自己從原來(lái)的slave狀態(tài)切換成了master,并且172.16.1.20是作為自己的slave節(jié)點(diǎn)。
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"
//并且可以正常進(jìn)行讀寫操作
5,那么當(dāng)掛掉的master主節(jié)點(diǎn)恢復(fù)正常,sentine是否會(huì)重新推選為master呢? 讓我們來(lái)驗(yàn)證一下:
#重新啟動(dòng)redis服務(wù):
[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
#查看自己狀態(tài):
可以得知,重新恢復(fù)掛掉的mater后,無(wú)法成為master,只能作為當(dāng)前master的slave從節(jié)點(diǎn)。但需要注意的是,當(dāng)掛掉的主機(jī)恢復(fù)后,哨兵機(jī)制并不會(huì)幫你還原這段時(shí)間丟失的數(shù)據(jù),所以,還需將其他節(jié)點(diǎn)的dump.rdb文件做好備份工作,以再恢復(fù)后能夠?qū)雭G失的數(shù)據(jù)。
看完上述內(nèi)容,你們對(duì)redis的主從復(fù)制大概了解了嗎?如果想了解更多相關(guān)文章內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!