前言

redis的持久化功能在一定程度上保证了数据的安全性,即便时服务器宕机的情况下,也可以保证数据的丢失非常少,通常,为了避免服务的单点故障,会把数据复制到多个副本放在不同的服务器上,且这些拥有数据副本的服务器可以用于处理客户端的读请求,扩展整体的性能,下面将介绍redis的主从复制。

1,主从复制概述

redis的复制功能是支持多个服务器之间的数据同步。被复制的服务器称为主服务器(master),对服务器进行复制操作的为从服务器(slave),主服务器master可以进行读写操作,当发生写操作的时候自动将数据同步到从服务器,而从服务器一般是只读的,并接收master同步过来的数据,一个master可以有多个slave,而一个slave只能由一个master。
主从复制的过程:

1,从节点执行slaveof命令; 2,从节点只是保存了slavef命令中主节点的信息,并没有立即发起复制; 3,从节点内部的定时任务发现由主节点的信息,开始使用socket连接主节点; 4,连接建立成功后,发送ping命令,希望得到pong命令响应,否则会进行重连; 5,如果主节点设置了权限,那么就需要进行权限验证;如果验证失败,复制终止; 6,权限验证通过后,进行数据同步,这是耗时最长的操作,主节点将把所有的数据全部发送给从节点; 7,当主节点把当前的数据同步给从节点后,便完成了复制的建立流程,主节点就会持续的把写命令发送给从主节点,保证主从数据一致性;

主从复制的作用:

  • 数据冗余。实现数据的热备份;
  • 故障恢复。避免单点故障带来的服务不可用;
  • 读写分离,负载均衡。主节点负责读写,从节点负责读,提高服务器并发量;
  • 高可用基础。是哨兵和集群实现的基础;

2,主从部署

环境描述:

主机 地址 端口 操作系统
主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-主从复制(sentinel)
redis-主从复制(sentinel)
通过上图,我们可以很容易的看出,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))

#防火墙规则设置:

[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  #修改内容如下(去掉注释并修改):   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. 

3,主从切换

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-主从复制(sentinel)
可以看到现在主redis状态已经变成了slave

#查看主redis的状态:
redis-主从复制(sentinel)
可以看到状态已经变成了master,并且数据也是最新的数据,但是这种人工操作的方法在生产环境中,肯定是稍显不足,所以接下来介绍redis哨兵机制。

4,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

查看端口是否正常:
redis-主从复制(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的日志信息:
redis-主从复制(sentinel)
通过日志信息的可以知道,原来的master主机已经挂掉了,并且通过sentinel哨兵机制,已经自动切换master到了172.16.1.110从节点了。

#验证原来从节点是否切换成功:
redis-主从复制(sentinel)
可以看到自己从原来的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

#查看自己状态:
redis-主从复制(sentinel)
可以得知,重新恢复挂掉的mater后,无法成为master,只能作为当前master的slave从节点。但需要注意的是,当挂掉的主机恢复后,哨兵机制并不会帮你还原这段时间丢失的数据,所以,还需将其他节点的dump.rdb文件做好备份工作,以再恢复后能够导入丢失的数据。

  • 版权声明:文章来源于网络采集,版权归原创者所有,均已注明来源,如未注明可能来源未知,如有侵权请联系管理员删除。

发表回复

后才能评论