1.为什么需要使用主从复制/读写分离
一般对于高并发的系统来说,搭建一个健壮的缓存系统是不可避免的。单机的reids的QPS可能只能上万,如果有再高并发的场景,单机是不能搞定的,就会有它的系统瓶颈。一般来说缓存是用来支撑高并发读,这时候我们可能就会想到读写分离;读写分离是用来处理读的并发量大,而写的并发量小的场景。 我们知道数据库可以通过主从复制,读写分离,以及分库分表来减轻流量的压力,可以看下这篇文章数据库主从复制,读写分离,分库分表;那么下面来简单介绍下redis主从复制和读写分离的原理。
2.replication的核心机制
1.redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量
2.一个master node是可以配置多个slave node;slave node也可以连 接其他的slave node
3.slave node做复制的时候,不会影响master node的正常工作;也不会影响对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务。
4.slave node主要用来进行横向扩容,读写分离,扩容的slave node可以提高读的吞吐量
3.主从复制的核心流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A0Vou9bw-1575470519113)(D:\TinkingCat\Redis\assets\1574933301359.png)]
1. slave服务器配置master的连接信息(slaveof属性);
2. slave连接上master,发送psync指令
3. master判断是否为全量复制:如果是全量复制,则进入下一步;否则可以看增量复制的子流程。
4. master启动一个后台线程,生成一份RDB快照文件,同时将从客户端收到的所有写命令缓存在内存中。
5. RDB文件生成完毕之后,master会将RDB发送给slave。
6. slave收到RDB文件之后,清空自己的旧数据,然后持久化到本地磁盘,再从本地磁盘加载到内存中。
7. 最后salve node保存了RDB文件之后,master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。
8. 如果slave node开启了AOF,那么会立即执行BGREWRITEAOF,重写AOF
增量复制子流程:如果全量复制过程中,master-slave网络连接断掉,salve重新连接master时,会触发增量复制;master直接从自己的backlog中获取部分丢失的数据,发送给slave node,默认backlog就是1MB;msater就是根据slave发送的psync中的offset来从backlog中获取数据的
断点续传:从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份
master node会在内存中常见一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制;如果没有找到对应的offset,那么就会执行一次full resynchronization。
5.Redis实现主从复制
-
环境准备
系统环境:centos7.0 redis版本4.0.0 远程连接工具xshell 主从机器: master:192.168.126.143 slave1:192.168.126.149 slave2:192.168.126.150
-
下载地址
http://www.redis.cn/download.html
-
历史版本地址
http://download.redis.io/releases
-
下载4.0的版本
#没有wget yum install wget #获取安装包(其实可以使用网易镜像或者阿里镜像下载) wget -P /usr/local/src/ http://download.redis.io/releases/redis-4.0.0.tar.gz
-
下载、解压、编译Redis
#切换目录 cd /usr/local/src/ #查看 ls #解压 tar -zxvf redis-4.0.0.tar.gz #如果安装报错gcc:命令未cd 找到(因为redis基于c语言编写) #先查看是否安装c++的编译器 yum -y install gcc-c++ #进行编译 cd redis-4.0.0 make #如果报错 执行 make clean 后再次 执行 make make clean #致命错误:jemalloc/jemalloc.h:没有那个文件或目录 make MALLOC=libc
$ wget http://download.redis.io/releases/redis-4.0.0.tar.gz $ tar xzf redis-4.0.0.tar.gz $ cd redis-4.0.0 $ make
-
启动redis
#启动redis服务端 ./redis-server #启动redis客户端 ./redis-cli #测试(查询所有的键) keys * #守护进程启动 [root@localhost redis-4.0.0]# cp redis.conf ./src/ vi redis.conf # By default Redis does not run as a daemon. Use 'yes' if you need it. # Note that Redis will write a pid file in /var/run/redis.pid when daemonized. #1)打开配置文件把下面对应的注释掉 bind 127.0.0.1 #2)Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程,设置为no daemonize no #3)保护模式 protected-mode no #启动 $ redis-server redis.conf #将含有”redis”关键词的进程杀死: $ ps -ef | grep redis | awk ‘{print $2}’ | xargs kill -9 #再次启动 ./redis-server redis.conf [root@localhost src]# ./redis-cli 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> exit #结束进程 [root@localhost src]# ps -ef | grep redis root 5664 5645 0 17:08 pts/1 00:00:00 ./redis-cli root 5734 1 0 17:28 ? 00:00:00 ./redis-server 127.0.0.1:6379 root 5766 1327 0 17:33 pts/0 00:00:00 grep --color=auto redis [root@localhost src]# kill -9 5664 [root@localhost src]# kill -9 5734 [root@localhost src]# ps -ef | grep redis root 5768 1327 0 17:34 pts/0 00:00:00 grep --color=auto redis
-
主从关系配置
#关闭防火墙或者开放端口 systemctl stop firewalld #查看防火墙状态 systemctl status firewalld #配置主从信息 slaveof 192.168.126.143 6379 #重启服务 ./redis-server redis.conf #登录客户端 ./redis-cli #查看主从状态 info Replication