Redis在日常部署的时候,可以有多种部署模式:单机、主从、哨兵、集群(分区分片),因此本文将对上面这四种模式进行详细的讲解,特别是集群模式将进行最细致的讲解(现行普遍使用的方式)。
单机部署很简单,直接下载Redis进行安装即可,此处不作详细讲解,具体Redis的安装请参考:Mac下安装Redis及Redis Desktop Manager,Windows以及Linux下的安装没啥不同。
单机模式部署有自己的优缺点,可以根据自己需要进行使用,优点如下:
缺点如下:
为了避免单点Redis服务器故障,准备多台服务器,互相连通。将数据复制多个副本保存在不同的服务器上,连接在一起,并保证数据同步。这样即使是有一台服务器宕机,其他服务依然可以提供服务。实现Redis的高可用。同时实现数据的冗余备份。这种形式也就是主从复制架构。
Redis 多副本,采用主从(replication)部署结构,相较于单副本而言最大的特点就是主从实例间数据实时同步,并且提供数据持久化和备份策略。主从实例部署在不同的物理服务器上,根据公司的基础环境配置,可以实现同时对外提供服务和读写分离策略。
具体原理就是,部署多台redis节点,其中只有一台节点是主节点(master),其他的节点都是从节点(slave),也叫备份节点(replica)。只有master节点提供数据的事务性操作(增删改),slave节点只提供读操作。所有slave节点的数据都是从master节点同步过来的。该模式的架构图如下:
该图只是最简单的一种主从结构方式,所有的slave节点都挂在master节点上,这样做的好处是slave节点与master节点的数据延迟较小;缺点是如果slave节点数量很多,master同步一次数据的耗时就很长。针对这一问题,可以使用下图中的主从架构:
master下面只挂一个slave节点,其他的slave节点挂在这个slave节点下面,这样,master节点每次只需要把数据同步给它下面的那一个slave节点即可,后续slave节点的数据同步由这个slave节点完成。这样做虽然降低了master节点做数据同步的压力,但也导致slave节点与master节点数据不一致的延迟更高。
从主从模式的架构图可以看出,主从模式的核心就是master节点与slave节点之间的数据同步。需要注意的是,Redis和大部分中间件的主从模式中的数据同步都是由slave节点主动发起的,原因是主从模式中只有一个master节点,剩余的全是slave节点,如果由master节点主动推送数据到各个slave节点,首先维护成本太大,master节点上要维护所有slave的地址信息,而且在增加slave节点的时候,也要同步维护到master上,这样master才能将数据同步到所有的slave上面;其次master性能受影响,节点之间同步数据肯定要通过网络传输数据,由master节点建立所有slave节点的连接会对master的性能产生较大影响。而由slave发起数据同步则避免了上述问题,只需在每个slave中维护一个master的地址即可。
Redis中主从节点数据同步有两种方式:全量数据同步和增量数据同步。
全量数据同步一般发生在slave节点初始化阶段,需要将master上的所有数据全部复制过来。全量同步的流程图如下:
以上就是master-slave全量同步的原理,执行完上述动作后,slave节点就可以接受来自用户的读请求,同时,master节点与slave节点进入命令传播阶段,在该阶段master节点会将自己执行的写命令发送给slave节点,slave节点接受并执行写命令,从而保证master节点与slave节点的数据一致性。
Redis2.8版本之前,是不支持增量数据同步的,只支持全量同步。增量数据同步是指slave节点初始化完成后,master节点执行的写命令同步到slave节点的过程。该过程比较简单,master节点每执行一个写命令后就会将该命令发送给slave节点执行,从而达到数据同步的目的。
但有一点需要注意,当增量复制过程中发生了异常导致同步失败时,是要支持断点续传的,也就是在异常恢复之后,是要支持从上次断掉的地方继续同步的,而不是全量数据同步。这就需要在master节点和slave节点分别维护一个复制偏移量(offset),代表master向slave节点同步的字节数。master节点每次向slave节点发送N个字节后,master节点的offset增加N;slave节点每次接收到master节点发送过来的N个字节后,slave节点的offset增加N。master节点和slave节点的这两个偏移量分别保存在master_repl_offset和slave_repl_offset这两个字段中。
# redis设置密码的方式和连接方式
# 配置文件方式
master节点:redis.conf ==> requirepass
slave节点:redis.conf ==> masterauth
# 命令方式
master:config set requirepass
config get requirepass
slave:auth
客户端:redis-cli -a
2. 数据同步阶段(结果:slave包含有master端的全部数据,master端保存有slave当前数据同步的位置)
redis 1.0 :sync 指令
redis 2.8 :psync 指令
redis 4.0 :psync2 指令
上述的几个步骤统称为“全量复制”
1. slave接收aof指令,执行 bgrewriteaof,恢复数据
“全量复制”后的三步称之为 “增量复制”
3. 命令传播阶段(实时保证数据同步)
当master数据库状态被修改后,导致主从服务器数据库状态不一致,此时需要让主从数据同步到一致状态。master将接收到的数据变更命令发送给slave,slave接收命令后执行命令。
命令传播阶段,master和slave间的交换信息通过心跳机制进行维护,实现双方连接保持在线:
master 通过命令传播程序发送命令到slave节点时,可能会由于网络原因导致一部分slave节点没有接收到命令,通过复制缓冲区保存命令,并通过master节点和slave节点确认偏移量来保证数据的准确同步。
偏移量:同步信息,比对master和slave的差异,当slave断线后,恢复数据使用
psync2 ? -1
# psync2
# slave 节点第一次连接不知道master节点的runid所以为 “?”
# -1 :代表全部
+FULLRESYNC runid offset
# +FULLRESYNC:全量
通过socket发送RDB文件给到slave(发送RDB文件期间offset可能会发生变化)。
psync2 runid offset
+CONTINUE offset
通过socket发送复制缓冲区中的 master.offset 到 slave.offset 的数据。
+CONTINUE offset
通过socket发送复制缓冲区中的 master.offset 到 slave.offset 的数据。
# 调整复制缓冲区的大小
master节点: repl-backlog-size 1mb
连接slave节点,在slave节点的redis.conf配置文件中添加一行配置:
slaveof
# masterip: master节点的ip
# masterport: master节点的port
###网络相关###
# bind 127.0.0.1 # 绑定监听的网卡IP,注释掉或配置成0.0.0.0可使任意IP均可访问
protected-mode no # 关闭保护模式,使用密码访问
port 6379 # 设置监听端口,建议生产环境均使用自定义端口
timeout 30 # 客户端连接空闲多久后断开连接,单位秒,0表示禁用
###通用配置###
daemonize yes # 在后台运行
pidfile /var/run/redis_6379.pid # pid进程文件名
logfile /usr/local/redis/logs/redis.log # 日志文件的位置
###RDB持久化配置###
save 900 1 # 900s内至少一次写操作则执行bgsave进行RDB持久化
save 300 10
save 60 10000
# 如果禁用RDB持久化,可在这里添加 save ""
rdbcompression yes #是否对RDB文件进行压缩,建议设置为no,以(磁盘)空间换(CPU)时间
dbfilename dump.rdb # RDB文件名称
dir /usr/local/redis/datas # RDB文件保存路径,AOF文件也保存在这里
###AOF配置###
appendonly yes # 默认值是no,表示不使用AOF增量持久化的方式,使用RDB全量持久化的方式
appendfsync everysec # 可选值 always, everysec,no,建议设置为everysec
###设置密码###
requirepass 123456 # 设置复杂一点的密码
1. master节点重启,runid发生变化,带来的全量复制问题。
解决方案:(master内部的优化方案,不需要手动操作)master内部创建 master_replid 变量,在master关闭时执行shutdown save 命令。
2. 频繁全量复制,缓冲区设置太小导致 (调整缓冲区大小 通过repl-backlog-size命令)
如果从服务器断线重连,会根据新的主服务器id和之前的主服务器id进行对比来判定是否是之前的主服务器来选择进行完整重同步还是部分重同步。
由于网络原因导致slave节点间的数据不一致(slave 中的偏移量不相同)(分布式环境中很常见的问题,是否需要解决看业务容忍度),可以通过优化主从间的网络环境解决,同机房部署。或者通过监控 主从节点的延迟(比较slave节点的offset差异),暂时屏蔽延迟大的slave节点。(通过 slave-serve-stale-data yes|no ,这个命令执行后,slave节点的数据就不能访问了。)
运维:终于不用再背着数万实例的Redis集群了!_Cluster
Redis学习之4种模式实践及机制解析(单机、主从、哨兵、集群)
redis架构_剑八-的博客-CSDN博客
Redis高可用方案—主从(masterslave)架构
Redis高可用架构—哨兵(sentinel)机制详细介绍
Redis高可用架构—Redis集群(Redis Cluster)详细介绍
Redis学习之Redis集群模式缺陷及其处理