Redis部署及主从集群架构

1)机器信息 Redis主从结构支持一主多从,这里使用一主一从 主节点 192.168.4.205 master-node 从节点 192.168.4.206 slave-node1

2)安装redis 两台节点机的安装步骤一样 (切换到根目录) [root@localhost ~]# wget http://download.redis.io/redis-stable.tar.gz [root@localhost ~]# tar -zvxf redis-stable.tar.gz
[root@localhost ~]# cd redis-stable [root@master-node redis-stable]# make [root@master-node redis-stable]# cd src/

然后新建目录,存放配置文件 [root@master-node src]# mkdir /etc/redis [root@master-node src]# mkdir /var/redis [root@master-node src]# mkdir /var/redis/log [root@master-node src]# mkdir /var/redis/run [root@master-node src]# mkdir /var/redis/redis

在redis解压根目录中找到配置文件模板 [root@master-node src]# cd ../ [root@master-node redis-stable]# cp redis.conf /etc/redis/redis.conf 设置启动脚本 [root@master-node redis-stable]# cp utils/redis_init_script /etc/init.d/redis [root@master-node redis-stable]# chmod 755 /etc/init.d/redis

修改脚本pid及conf路径为实际路径 [root@master-node redis-stable]# vim /etc/init.d/redis ...... REDISPORT=11205 EXEC=/usr/local/bin/redis-server CLIEXEC=/usr/local/bin/redis-cli

PIDFILE=/var/redis/run/redis_11205.pid CONF="/etc/redis/redis.conf" .......

3)主从复制配置 master-node [root@localhost ~]# vim /etc/redis/redis.conf ....... port 11205 ....... daemonize yes //这个修改为yes ....... bind 0.0.0.0 //绑定的主机地址。说明只能通过这个ip地址连接本机的redis。最好绑定0.0.0.0;注意这个不能配置成127.0.0.1,否则复制会失败!用0.0.0.0或者本机ip地址都可以 ....... pidfile /var/redis/run/redis_11205.pid ....... logfile /var/redis/log/redis_11205.log ....... dir /var/redis/redis #redis数据目录 .......
appendonly yes #启用AOF持久化方式 appendfilename "appendonly.aof" #AOF文件的名称,默认为appendonly.aof appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,是受推荐的方式。 ..... save 900 1 #启用RDB快照功能,默认就是启用的 save 300 10 save 60 10000 #即在多少秒的时间内,有多少key被改变的数据添加到.rdb文件里 ....... dbfilename dump.rdb #快照文件名称 ......

slave-node1和slave-node2两个从节点相比于master-node主节点的redis.conf配置,只是多了下面一行配置,其它都一样: slaveof 192.168.4.205 11205

启动三个节点的redis(启动命令一样) [root@localhost ~]# /etc/init.d/redis start Starting Redis server... [root@localhost ~]# lsof -i:11205 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME redis-ser 10475 root 4u IPv4 88640 0t0 TCP localhost:11205 (LISTEN)

登陆主节点master-node的redis,查看状态

[root@localhost ~]# redis-cli -h 127.0.0.1 -p 11205
127.0.0.1:11205> info ...... ......

Replication

role:master //节点在集群中的状态 connected_slaves:2 //slave节点的个数 slave0:ip=192.168.4.206,port=11206,state=online,offset=26325,lag=1 slave0:ip=192.168.4.207,port=11207,state=online,offset=26325,lag=1........

登录从节点slave-node1的redis,查看状态 [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 11206 127.0.0.1:11206> info ....... ....... #Replication role:slave master_host:192.168.4.205 master_port:11205 master_link_status:up ......

登录从节点slave-node2的redis,查看状态 [root@slave-node2 ~]# redis-cli -h 127.0.0.1 -p 11207 127.0.0.1:11207> info ...... #Replication role:slave master_host:192.168.4.205 master_port:11205 master_link_status:up ......

4)测试数据同步

主节点master-node上写入新数据 [root@localhost ~]# redis-cli -h 127.0.0.1 -p 11205 127.0.0.1:11205> set name liudehua OK 127.0.0.1:11205> get name "liudehua"

然后到两台从节点上查看是否同步了上面写入的数据 [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 11206 127.0.0.1:11206> get name "wangshibo"

[root@slave-node2 ~]# redis-cli -h 127.0.0.1 -p 11207 127.0.0.1:11207> get name "wangshibo"

redis主从复制默认是读写分离的,即: 主节点上可以读写操作;从节点上只能进行读操作,不能写数据 [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 11206 127.0.0.1:11206> set name liudehua (error) READONLY You can't write against a read only slave.

[root@slave-node2 ~]# redis-cli -h 127.0.0.1 -p 11207 127.0.0.1:11207> set name liudehua (error) READONLY You can't write against a read only slave.

5)主从切换

5.1)停止主节点master-node的redis [root@localhost ~]# redis-cli -h 127.0.0.1 -p 11205 shutdown [root@localhost ~]# redis-cli -h 127.0.0.1 -p 11205 Could not connect to Redis at 127.0.0.1:11205: Connection refused Could not connect to Redis at 127.0.0.1:11205: Connection refused

将从节点slave-node1的redis设成主redis [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 11206 slaveof NO ONE //这条命了只是临时将该节点设置为主节点;当redis重启后,就会失效;可以登录redis,通过info信息查看! OK [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 11206 //变为主redis后,slave-node1就可以进行写入操作了 127.0.0.1:11205> set name huanqiu OK 127.0.0.1:11205> info ...... #Replication role:master //可知已经变成master主节点了 connected_slaves:0 master_repl_offset:0

这时候master-node节点已经故障了,而另一个从节点slave-node2还跟它有主从关系。此时slave-node1已经变成主redis了,所以可以将slave-node2的主从关系中的主节点 配置修改为slave-node1(即192.168.4.205)

5.2)原来的主redis恢复正常了,要重新切换回去 比如原来的主redis节点master-node现在恢复了 [root@localhost ~]# /etc/init.d/redis start Starting Redis server... [root@localhost ~]# redis-cli -h 127.0.0.1 -p 11205 127.0.0.1:11205> info ...... #Replication role:master //原来的主节点恢复了,发现只有一个从节点save-node2。另一个从节点slave-node1在master-node故障期间临时变为主节点 connected_slaves:1
slave0:ip=192.168.4.207,port=11207,state=online,offset=1,lag=0 ......

那么现在要重新将主节点切换回去。步骤如下:

a)登录临时切换的主节点slave-node1 [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 11206 127.0.0.1:11206> set name zhangxueyou OK 127.0.0.1:11206> get name "zhangxueyou" 127.0.0.1:11206> save //将数据保存 OK

b)将现在的主redis(即slave-node1节点,临时设置的主节点)根目录下app文件和dump.rdb文件拷贝覆盖到原来主redis的根目录(覆盖前将原来主redis下的持久化文件备份下) [root@slave-node1 ~]# rsync -e "ssh -p22" -avpgolr /var/redis/redis/dump.rdb 192.168.4.205:/var/redis/redis/ [root@slave-node1 ~]# rsync -e "ssh -p22" -avpgolr /var/redis/redis/appendonly.aof 192.168.4.205:/var/redis/redis/

c)重启原来的主redis(即master-node节点) [root@localhost ~]# /etc/init.d/redis stop [root@localhost ~]# /etc/init.d/redis start

d)在现在的主redis(即slave-node1)中切换(或者直接重启该节点的redis,因为redis.conf文件中已经配置了;如果不想重启redis,就使用下面的命令) [root@slave-node1 ~]# redis-cli -h 127.0.0.1 -p 11206 slaveof 192.168.4.205 11205 OK

e)登录原来的主redis(也就是master-node)查看 [root@localhost ~]# redis-cli -h 127.0.0.1 -p 11205 127.0.0.1:11205> info ....... #Replication role:master connected_slaves:2 slave0:ip=192.168.4.206,port=11206,state=online,offset=1,lag=0 slave1:ip=192.168.4.207,port=11207,state=online,offset=1,lag=0 master_repl_offset:1 ......

注意事项 如果使用主从复制,那么要确保你的master激活了持久化,或者确保它不会在当掉后自动重启,原因: a)slave是master的完整备份,因此如果master通过一个空数据集重启,slave也会被清掉。 b)在配置redis复制功能的时候,如果主数据库设置了密码,需要在从数据的配置文件中通过masterauth参数设置主数据库的密码,这样从数据库在连接主数据库时就会自动使用auth命令认证了。相当于做了一个免密码登录。(我上面的例子中没有设置密码)