这篇文章主要为大家详细介绍了redis主从复制的含义和使用方法,图文详解容易学习,配合代码阅读理解效果更佳,非常适合初学者入门,感兴趣的小伙伴们可以参考一下。
redis的复制功能是支持多个服务器之间的数据同步。被复制的服务器称为主服务器(master),对服务器进行复制操作的为从服务器(slave),主服务器master可以进行读写操作,当发生写操作的时候自动将数据同步到从服务器,而从服务器一般是只读的,并接收master同步过来的数据,一个master可以有多个slave,而一个slave只能由一个master。
主从复制的过程:
1,从节点执行slaveof命令;
2,从节点只是保存了slavef命令中主节点的信息,并没有立即发起复制;
3,从节点内部的定时任务发现由主节点的信息,开始使用socket连接主节点;
4,连接建立成功后,发送ping命令,希望得到pong命令响应,否则会进行重连;
5,如果主节点设置了权限,那么就需要进行权限验证;如果验证失败,复制终止;
6,权限验证通过后,进行数据同步,这是耗时最长的操作,主节点将把所有的数据全部发送给从节点;
7,当主节点把当前的数据同步给从节点后,便完成了复制的建立流程,主节点就会持续的把写命令发送给从主节点,保证主从数据一致性;
主从复制的作用:
环境描述:
主机 | 地址 | 端口 | 操作系统 |
---|---|---|---|
主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))
#防火墙规则设置:
[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.
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文件做好备份工作,以再恢复后能够导入丢失的数据。
看完上述内容,你们对redis的主从复制大概了解了吗?如果想了解更多相关文章内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。