redis主从复制、高可用和集群
redis簡介:
??? redis是一個(gè)key-value存儲(chǔ)系統(tǒng).和Memcached類似,它支持存儲(chǔ)的value類型相對(duì)更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hashs(哈希類型);這些數(shù)據(jù)類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的;在此基礎(chǔ)上,redis支持各種不同方式的排序.與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中;區(qū)別的是redis會(huì)周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實(shí)現(xiàn)了master-slave(主從)同步。
Redis的優(yōu)點(diǎn):
性能極高 – Redis能支持超過 100K+ 每秒的讀寫頻率。豐富的數(shù)據(jù)類型 – Redis支持二進(jìn)制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數(shù)據(jù)類型操作。原子性 – Redis的所有操作都是原子性的,同時(shí)Redis還支持對(duì)幾個(gè)操作全并后的原子性執(zhí)行。豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性。
主從復(fù)制:
實(shí)驗(yàn)環(huán)境:
test1: 172.25.1.11????? 作主機(jī)
test2: 172.25.1.12????? 作備機(jī) ???????????????????
test3: 172.25.1.13????? 作備機(jī) ????????????????????????????
test1、test2、test3:
?tar zxf redis-4.0.8.tar.gz
cd redis-4.0.8
yum install gcc -y
make && make install
which redis-cli
cd utils/
./install_server.sh
redis-cli????????? //ctrl+c退出
netstat -antlp | grep redis
test1:
vim /etc/redis/6379.conf
/etc/init.d/redis_6379 restart
[root@test1 utils]# redis-cli
test2和test3:
[root@test2 redis]# vim 6379.conf??????????????? //這里的slaveof后的ip應(yīng)是test1(master)的ip,端口為6379,目的是:與master同步
[root@test2 redis]# /etc/init.d/redis_6379 restart
[root@test2 redis]# redis-cli
//test3和test2執(zhí)行相同的步驟
此時(shí),給test1執(zhí)行:
則test2和test3已經(jīng)同步過來了:
哨兵模式實(shí)現(xiàn)主從高可用
//做主從切換的時(shí)候只能有一個(gè)與主發(fā)起同步
redis提供了哨兵,實(shí)現(xiàn)高可用。哨兵節(jié)點(diǎn)進(jìn)行自主監(jiān)控主從節(jié)點(diǎn)以及其他哨兵節(jié)點(diǎn),當(dāng)發(fā)現(xiàn)主節(jié)點(diǎn)掛掉時(shí)自動(dòng)故障轉(zhuǎn)移。
哨兵節(jié)點(diǎn)最好為奇數(shù):
test1:
[root@test1 redis-4.0.8]# pwd
/root/redis-4.0.8
[root@test1 redis-4.0.8]# cp sentinel.conf /etc/redis/
[root@test1 redis-4.0.8]# vim /etc/redis/sentinel.conf
//這里的sentinel后跟的ip為哨兵節(jié)點(diǎn)的領(lǐng)導(dǎo)者,用來做故障轉(zhuǎn)移。
[root@test1 ~]# scp /etc/redis/sentinel.conf test2:/etc/redis/
[root@test1 ~]# scp /etc/redis/sentinel.conf test3:/etc/redis/
[root@test1 ~]# cd /etc/redis
test1:
[root@test1 redis]# redis-server /etc/redis/sentinel.conf --sentinel??????????????? //查看連接狀態(tài)
test2:
[root@test2 redis]# cd /etc/redis
[root@test2 redis]# redis-server /etc/redis/sentinel.conf --sentinel
1152:X 31 Mar 03:33:43.740 * +sentinel sentinel d5482bb57d42d1e217c5b4d794177aebd1d17173 172.25.1.11 26379 @ mymaster 172.25.1.11 6379
1152:X 31 Mar 03:34:49.031 * +sentinel sentinel f34d21c240b9903cbd6f51a3546ad87a2d84c89a 172.25.1.12 26379 @ mymaster 172.25.1.11 6379
1152:X 31 Mar 03:36:15.879 # +sdown sentinel f34d21c240b9903cbd6f51a3546ad87a2d84c89a 172.25.1.13 26379 @ mymaster 172.25.1.11 6379
test3:
[root@test3 redis]# cd /etc/redis/
[root@test3 redis]# redis-server /etc/redis/sentinel.conf --sentinel
1251:X 31 Mar 03:46:42.534 * +slave slave 172.25.1.12:6379 172.25.1.12 6379 @ mymaster 172.25.1.11 6379
1251:X 31 Mar 03:46:42.534 * +slave slave 172.25.1.11:6379 172.25.1.13 6379 @ mymaster 172.25.1.11 6379
1251:X 31 Mar 03:47:12.562 # +sdown slave 172.25.1.11:6379 172.25.1.11 6379 @ mymaster 172.25.1.11 6379
若此時(shí)將test1的sentinel關(guān)掉,假設(shè)出現(xiàn)故障:
[root@test1 redis]# redis-cli
127.0.0.1:6379> shutdown
not connected>
test2和test3監(jiān)控分別顯示:
此時(shí),test3接替test1作為哨兵節(jié)點(diǎn)的領(lǐng)導(dǎo)者,負(fù)責(zé)故障轉(zhuǎn)移。
查看哨兵配置文件:
test3:
test2:
配置文件自動(dòng)更新為172.25.1.13
若再次將test1的哨兵節(jié)點(diǎn)恢復(fù),則此時(shí):
[root@test1 redis]# /etc/init.d/redis_6379 start
可以看到test1的哨兵服務(wù)開啟后,test1并沒有恢復(fù)以前的master身份,而是轉(zhuǎn)為slave
[root@test3 redis]# redis-server /etc/redis/sentinel.conf --sentinel
可以在配置文件中查看:
[root@test1 redis]# vim 6379.conf
可以看出test1的配置文件的最后一行自動(dòng)添加了? slaveof 172.25.1.13 6379,即test3為master
test3配置文件中的? slaveof 172.25.1.11 6379已經(jīng)自動(dòng)消失
?
Redis集群搭建
//若某節(jié)點(diǎn)與其他節(jié)點(diǎn)通信時(shí)過半的master與其無法通信則該master掛掉。
//任意一個(gè)master掛掉,若該master沒有從節(jié)點(diǎn),則該集群掛掉。
//過半的 master掛掉,則該集群掛掉。
Redis集群簡介
??????? redis是一個(gè)開源的key value存儲(chǔ)系統(tǒng),受到了廣大互聯(lián)網(wǎng)公司的青睞。redis3.0版本之前只支持單例模式,在3.0版本及以后才支持集群;
??????? redis集群采用P2P模式,是完全去中心化的,不存在中心節(jié)點(diǎn)或者代理節(jié)點(diǎn);
?? ? ?? redis集群沒有統(tǒng)一的入口,客戶端連接集群的時(shí)候連接集群中的任意節(jié)點(diǎn)即可,集群內(nèi)部的節(jié)點(diǎn)是相互通信的(ping-pong機(jī)制),每個(gè)節(jié)點(diǎn)都是一個(gè)redis實(shí)例;
??????? 為了實(shí)現(xiàn)集群的高可用,即判斷節(jié)點(diǎn)能否正常使用,redis-cluster有一個(gè)投票容錯(cuò)機(jī)制:如果集群中超過半數(shù)的節(jié)點(diǎn)投票認(rèn)為某個(gè)節(jié)點(diǎn)掛了,則該結(jié)點(diǎn)就掛了(fail);
什么時(shí)候整個(gè)集群不可用?
?????? 1、 若集群中任意一個(gè)節(jié)點(diǎn)掛了且該節(jié)點(diǎn)沒有從節(jié)點(diǎn)(備份節(jié)點(diǎn)),則集群就掛了,即不可用 ;
?????? 2、如果集群超過半數(shù)以上master掛掉,無論是否有slave,集群進(jìn)入fail狀態(tài) 。
?? ? ?? 任意一個(gè)節(jié)點(diǎn)掛了且該結(jié)點(diǎn)沒有從節(jié)點(diǎn),則這個(gè)集群就掛了的原因 -> 因?yàn)榧簝?nèi)置了16384個(gè)哈希槽,并且把所有的物理節(jié)點(diǎn)映射到了這16384[0-16383]個(gè)哈希槽上,或者說把這些哈希槽均等的分配給了各個(gè)節(jié)點(diǎn)。當(dāng)需要在Redis集群存放一個(gè)數(shù)據(jù)(key-value)時(shí),redis會(huì)先對(duì)這個(gè)key進(jìn)行crc16(循環(huán)冗余碼校驗(yàn))算法,然后得到一個(gè)結(jié)果,再把這個(gè)結(jié)果對(duì)16384進(jìn)行求余,這個(gè)余數(shù)會(huì)對(duì)應(yīng)[0-16383]其中一個(gè)槽,從而決定key-value存儲(chǔ)到哪個(gè)節(jié)點(diǎn)中。所以一旦某個(gè)節(jié)點(diǎn)掛了,該節(jié)點(diǎn)對(duì)應(yīng)的哈希槽就無法使用,那么就會(huì)導(dǎo)致集群無法正常工作。
??????? 注:每個(gè)Redis集群理論上最多可以有16384個(gè)節(jié)點(diǎn)。
實(shí)驗(yàn)環(huán)境:
Redis集群至少需要3個(gè)節(jié)點(diǎn),因?yàn)橥镀比蒎e(cuò)機(jī)制要求超過半數(shù)節(jié)點(diǎn)認(rèn)為某個(gè)節(jié)點(diǎn)掛了該節(jié)點(diǎn)才是掛了,所以2個(gè)節(jié)點(diǎn)無法構(gòu)成集群。
為保證集群的高可用,需要每個(gè)節(jié)點(diǎn)都有從節(jié)點(diǎn),所以redis集群至少需要6臺(tái)服務(wù)器。因?yàn)槲覜]有那么多服務(wù)器,也啟動(dòng)不了那么多虛擬機(jī),所在這里搭建的是偽分布式集群,即一臺(tái)服務(wù)器虛擬運(yùn)行6個(gè)redis實(shí)例,修改端口號(hào)為(7001-7006)。
[root@test1 ~]# cd /usr/local/
[root@test1 local]# ls
bin? etc? games? include? lib? lib64? libexec? sbin? share? src
[root@test1 local]# mkdir cluster
[root@test1 local]# cd cluster/
[root@test1 cluster]# mkdir 700{1..6}
[root@test1 cluster]# ls
7001? 7002? 7003? 7004? 7005? 7006
[root@test1 cluster]# cd 7001/
[root@test1 7001]# vim redis.conf
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
[root@test1 7001]# cd
[root@test1 ~]# cd redis-4.0.8/src/
[root@test1 src]# cp redis-trib.rb /usr/local/bin/
[root@test1 src]# cd
[root@test1 ~]# yum install -y rubygems-1.3.7-5.el6.noarch.rpm ruby-2.2.3-1.el6.x86_64.rpm libyaml-0.1.3-4.el6_6.x86_64.rpm
[root@test1 ~]# gem install --local redis-4.0.1.gem????????????????????? //這些資源須自行下載
[root@test1 ~]# gem list --local
[root@test1 ~]# /etc/init.d/redis_6379 stop
Stopping ...
Redis stopped
[root@test1 ~]# chkconfig redis_6379 off
[root@test1 ~]# cd /usr/local/cluster
[root@test1 cluster]# cd 7001/
[root@test1 7001]# vim redis.conf
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes???????? //指定是否在每次更新操作后進(jìn)行日志記錄,redis在默認(rèn)情況下是異步的把數(shù)據(jù)寫入磁盤,如果不開啟,可能會(huì)在斷電 時(shí)導(dǎo)致一段時(shí)間內(nèi)數(shù)據(jù)丟失。因?yàn)閞edis本身同步數(shù)據(jù)文件是按上面save條件來同步的,所以有的數(shù)據(jù)會(huì)在一段時(shí)間內(nèi)置 存在于內(nèi)存中。默認(rèn)為no
daemonzie yes??????????????????? //redis默認(rèn)不是以守護(hù)進(jìn)程的方式運(yùn)行,可以通過該配置項(xiàng)修改,使用yes啟用守護(hù)進(jìn)程:
pidfile /var/run/redis.pid?????????? //當(dāng)redis以守護(hù)進(jìn)程方式運(yùn)行時(shí),redis默認(rèn)會(huì)把pid寫入/var/run/redis.pid文件,可以通過pidfile指定
logfile /usr/local/cluster/7001/redis.log
[root@test1 7001]# touch redis.log
[root@test1 7001]# redis-server redis.conf??????????? //啟動(dòng)服務(wù)
[root@test1 7001]# cat redis.log ?? //查看日志
[root@test1 7001]# cat /proc/sys/net/core/somaxconn
[root@test1 7001]# echo 511 > /proc/sys/net/core/somaxconn
[root@test1 7001]# sysctl -w vm.overcommit_memory=1
vm.overcommit_memory = 1
[root@test1 7001]# vim /etc/sysctl.conf
[root@test1 7001]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@test1 7001]# cp redis.conf ../7002/
[root@test1 7001]# cp redis.conf ../7003
[root@test1 7001]# cp redis.conf ../7004
[root@test1 7001]# cp redis.conf ../7005
[root@test1 7001]# cp redis.conf ../7006
[root@test1 7001]# cd ../7002
[root@test1 7002]# vim redis.conf??????????? //將端口改為7002
port 7002
[root@test1 7002]# touch redis.log
[root@test1 7002]# redis-server redis.conf
[root@test1 7001]# cat redis.log ?? //查看日志,是否有報(bào)錯(cuò)
//以此類推,切換到7003 7004 7005 7006 并將其對(duì)應(yīng)配置文件的端口改為7003 7004 7005 7006后重啟并查看配置文件是否有報(bào)錯(cuò)
[root@test1 7006]# ps ax??????????? //查看進(jìn)程是否打開
[root@test1 7006]# redis-trib.rb create --replicas 1 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
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
127.0.0.1:7001
127.0.0.1:7002
127.0.0.1:7003
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: ef39d7b9c63cfce969ba0fec6112d26a621a9ed4 127.0.0.1:7001
?? slots:0-5460 (5461 slots) master
M: 50164d159a1975dd509a65e441893883fa097159 127.0.0.1:7002
?? slots:5461-10922 (5462 slots) master
M: 6b2f4d1bd89a82160786e286e2dd81474cd7de38 127.0.0.1:7003
?? slots:10923-16383 (5461 slots) master
S: f451e795057133c384ad1d29993e22a190439afc 127.0.0.1:7004
?? replicates 6b2f4d1bd89a82160786e286e2dd81474cd7de38
S: e92729b4589d41be6b52fef2387a62b63ada606e 127.0.0.1:7005
?? replicates ef39d7b9c63cfce969ba0fec6112d26a621a9ed4
S: 3a8db69457f1c8f52f5c66e47fe48f92baff78f5 127.0.0.1:7006
?? replicates 50164d159a1975dd509a65e441893883fa097159
Can I set the above configuration? (type 'yes' to accept): 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: ef39d7b9c63cfce969ba0fec6112d26a621a9ed4 127.0.0.1:7001
?? slots:0-5460 (5461 slots) master
?? 1 additional replica(s)
S: f451e795057133c384ad1d29993e22a190439afc 127.0.0.1:7004
?? slots: (0 slots) slave
?? replicates 6b2f4d1bd89a82160786e286e2dd81474cd7de38
S: e92729b4589d41be6b52fef2387a62b63ada606e 127.0.0.1:7005
?? slots: (0 slots) slave
?? replicates ef39d7b9c63cfce969ba0fec6112d26a621a9ed4
M: 6b2f4d1bd89a82160786e286e2dd81474cd7de38 127.0.0.1:7003
?? slots:10923-16383 (5461 slots) master
?? 1 additional replica(s)
S: 3a8db69457f1c8f52f5c66e47fe48f92baff78f5 127.0.0.1:7006
?? slots: (0 slots) slave
?? replicates 50164d159a1975dd509a65e441893883fa097159
M: 50164d159a1975dd509a65e441893883fa097159 127.0.0.1:7002
?? slots:5461-10922 (5462 slots) master
?? 1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[root@test1 7006]# redis-trib.rb check 127.0.0.1:7001
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: ef39d7b9c63cfce969ba0fec6112d26a621a9ed4 127.0.0.1:7001?????????????? //replicates可以看出,7001是7005的master
?? slots:0-5460 (5461 slots) master
?? 1 additional replica(s)
S: f451e795057133c384ad1d29993e22a190439afc 127.0.0.1:7004??????
?? slots: (0 slots) slave
?? replicates 6b2f4d1bd89a82160786e286e2dd81474cd7de38
S: e92729b4589d41be6b52fef2387a62b63ada606e 127.0.0.1:7005?????????????
?? slots: (0 slots) slave
?? replicates ef39d7b9c63cfce969ba0fec6112d26a621a9ed4
M: 6b2f4d1bd89a82160786e286e2dd81474cd7de38 127.0.0.1:7003?????????????? //7003是7004的master
?? slots:10923-16383 (5461 slots) master
?? 1 additional replica(s)
S: 3a8db69457f1c8f52f5c66e47fe48f92baff78f5 127.0.0.1:7006
?? slots: (0 slots) slave
?? replicates 50164d159a1975dd509a65e441893883fa097159
M: 50164d159a1975dd509a65e441893883fa097159 127.0.0.1:7002??????????????? //7002是7006的master
?? slots:5461-10922 (5462 slots) master
?? 1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
7001 7002 7003是master
[root@test1 7006]# cd ../7001
[root@test1 7001]# redis-cli -c -p 7001?????????????? //登陸進(jìn)入7001
127.0.0.1:7001> set name westos???????? ? ? ? ?? //存入數(shù)據(jù)
-> Redirected to slot [5798] located at 127.0.0.1:7002??????????????? //數(shù)據(jù)自動(dòng)寫入7002
OK
127.0.0.1:7002> get name??????????? //查看數(shù)據(jù)
"westos"
127.0.0.1:7002>
[root@test1 7001]# redis-cli -c -p 7004 ?????????????? //登陸進(jìn)入7004
127.0.0.1:7004> get name???????????????? ? ? //查看name會(huì)跳轉(zhuǎn)到7002
-> Redirected to slot [5798] located at 127.0.0.1:7002
"westos"
127.0.0.1:7002>
[root@test1 7001]# redis-cli -c -p 7005??????????????? //登陸進(jìn)入7005
127.0.0.1:7005> get name???????????????? //查看name會(huì)跳轉(zhuǎn)到7002
-> Redirected to slot [5798] located at 127.0.0.1:7002????????
"westos"
[root@test1 7001]# ps ax????????????? //查看7002的進(jìn)程id
?1282 ???????? Ssl??? 0:02 redis-server *:7001 [cluster]
?1316 ???????? Ssl??? 0:02 redis-server *:7002 [cluster]
?1347 ???????? Ssl??? 0:02 redis-server *:7003 [cluster]
?1359 ???????? Ssl??? 0:02 redis-server *:7004 [cluster]
?1366 ???????? Ssl??? 0:02 redis-server *:7005 [cluster]
?1374 ???????? Ssl??? 0:02 redis-server *:7006 [cluster]
[root@test1 7001]#? kill?1316?????????? //殺死7002
[root@test1 7001]# redis-cli -c -p 7002??????? //登陸發(fā)現(xiàn)登陸不上
[root@test1 7001]# redis-cli -c -p 7005???????????? //此時(shí)集群是好的
127.0.0.1:7005> get name
-> Redirected to slot [5798] located at 127.0.0.1:7006
"westos"
127.0.0.1:7006>
[root@test1 7001]# cd ../7002/
[root@test1 7002]# redis-server redis.conf??????????????? //重啟7002
[root@test1 7002]# redis-trib.rb check 127.0.0.1:7001?????????????????? //此時(shí)7002由master變?yōu)閟lave
[root@test1 7002]# ps -ax???????????????? //查看進(jìn)程id
[root@test1 7002]# kill 1374????????????? //殺死7006
[root@test1 7002]# kill 1409????????????? //殺死7002
[root@test1 7002]# redis-cli -c -p 7001????? //登陸7001
127.0.0.1:7001> get name?????????????? //發(fā)現(xiàn)集群已經(jīng)掛掉
(error) CLUSTERDOWN The cluster is down
127.0.0.1:7001>
[root@test1 7002]# redis-server redis.conf?????????? //重啟7002
[root@test1 7002]# cd ../7006
[root@test1 7006]# redis-cli -c -p 7001????????????? //發(fā)現(xiàn)集群狀態(tài)恢復(fù)
127.0.0.1:7001> get name
-> Redirected to slot [5798] located at 127.0.0.1:7002
"westos"
127.0.0.1:7002>
[root@test1 7006]# redis-server redis.conf???????????????????????????? //重啟7006
[root@test1 7006]# redis-cli -c -p 7001
127.0.0.1:7001> get name
-> Redirected to slot [5798] located at 127.0.0.1:7002
"westos"
若將兩個(gè)redis的master掛掉,掛掉7001和7003,則發(fā)現(xiàn)此時(shí)集群掛掉:
總結(jié)
以上是生活随笔為你收集整理的redis主从复制、高可用和集群的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LVS_NAT实现负载均衡
- 下一篇: nginx源码编译、负载均衡及模块的扩展