1.主从架构简介

  • 背景

    • 单机部署简单,但是可靠性低,且不能很好利用CPU多核处理能力
    • 生产环境必须要保证高可用,一般不可能单机部署
    • 读写分离是可用性要求不高、性能要求较高、数据规模小的情况
  • 目标

    • 读写分离,扩展主节点的读能力,分担主节点读压力
    • 容灾恢复,一旦主节点宕机,从节点作为主节点的备份可以随时顶上来
  • Redis主从架构介绍

2.Redis6.x主从复制一主二从实战搭建

  • 配置:6379端口为主节点,6380、6381为从节点

    # 新建配置文件目录mkdir -p /data/redis/master/datamkdir -p /data/redis/slave1/datamkdir -p /data/redis/slave2/data# 从节点开启只读模式(默认)replica-read-only yes# 从节点访问主节点的密码,和requirepass一样masterauth 123456# 哪个主节点进行复制replicaof 192.168.1.12 6379
  • 创建主节点配置文件vim /data/redis/master/data/master.conf

    bind 0.0.0.0port 6379daemonize yesrequirepass 123456logfile "/usr/local/redis6/log/redis_master.log"dbfilename dump_master.rdbdir /usr/local/redis6/dataappendonly yesappendfilename "appendonly_master.aof"masterauth 123456
  • 创建从节点1配置文件vim /data/redis/slave1/data/slave1.conf

    bind 0.0.0.0port 6380daemonize yesrequirepass 123456logfile "/usr/local/redis6/log/redis_slave1.log"dbfilename dump_slave1.rdbdir /usr/local/redis6/dataappendonly yesappendfilename "appendonly_slave1.aof"masterauth 123456replicaof 192.168.1.12 6379
  • 创建从节点2配置文件vim /data/redis/slave2/data/slave2.conf

    bind 0.0.0.0port 6381daemonize yesrequirepass 123456logfile "/usr/local/redis6/log/redis_slave2.log"dbfilename dump_slave2.rdbdir /usr/local/redis6/dataappendonly yesappendfilename "appendonly_slave2.aof"masterauth 123456replicaof 192.168.1.12 6379
  • 防火墙记得关闭,或者开放对应的端口;云服务器记得开放网络安全组

  • 启动服务

    # 启动主节点/usr/local/redis6/bin/redis-server /data/redis/master/data/master.conf# 启动从节点1/usr/local/redis6/bin/redis-server /data/redis/slave1/data/slave1.conf# 启动从节点2/usr/local/redis6/bin/redis-server /data/redis/slave2/data/slave2.conf
  • 客户端连接后info replication查看状态

3.主从架构-复制读写分离原理解析

  • 主从复制分两种(主从刚连接的时候,进行全量同步;全同步结束后,进行增量同步)

    • 全量复制
      • master服务器会开启一个后台进程用于将Redis中的数据生成一个RDB文件
      • 主服务器会缓存所有接收到的来自客户端的写命令,当后台保存进程处理完毕后,会将该RDB文件传递给slave服务器
      • slave服务器会将RDB文件保存在磁盘并通过读取该文件将数据加载到内存
      • 在此之后master服务器会将在此期间缓存的命令通过Redis传输协议发送给slave服务器
      • 然后slave服务器将这些命令依次作用于自己本地的数据集上,最终达成数据的一致性
    • 增量复制
      • slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程
      • 服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令
  • 特点

    • 主从复制对于 主/从 Redis服务器来说是非阻塞的,所以同步期间都可以正常处理外界请求
    • 一个主Redis可以含有多个从Redis,每个从Redis可以接收来自其他从Redis服务器的连接
    • 从节点不会让key过期,而是主节点的key过期删除后,成为del命令传输到从节点进行删除
      • 从节点开启sync看日志
  • 加速复制

    • 完全重新同步需要在磁盘上创建一个RDB文件,然后加载这个文件以便为从服务器发送数据
    • 在比较低速的磁盘,这种操作会给主服务器带来较大的压力
    • 新版支持无磁盘的复制,子进程直接将RDB通过网络发送给从服务器,不使用磁盘作为中间存储
    • repl-diskless-sync yes(默认是no)
  • 主从断开重连

    • 如果遭遇连接断开,重新连接之后可以从中断处继续进行复制,而不必重新同步
    • 2.8版本后,部分重新同步这个新特性内部使用psync命令,旧的实现中使用sync命令

4.Sentinel哨兵模式

  • 哨兵模式介绍

    • Redis提供了哨兵的命令,是一个独立的进程
    • 原理:哨兵通过发送命令给多个节点,等待Redis服务器响应,从而监控运行的多个Redis实例的运行情况
    • 当哨兵监测到master宕机,会自动将slave切换成master通过通知其他的从服务器,修改配置文件切换主机
  • Sentinel三大工作任务

    • 监控(Monitoring)
      • Sentinel会不断地检查你的主服务器和从服务器是否运行正常
    • 提醒(Notification)
      • 当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知
    • 自动故障迁移(Automatic failover)
      • 当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务区改为复制新的主服务器
      • 当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器
  • 问题:一个哨兵进程对Redis服务器进行监控,可能会出现问题;一般是使用多个哨兵进行监控,各个哨兵之间还会进行监控,形成多哨兵模式

  • 多哨兵模式下线名词介绍

    • 主观下线(Subjectively Down,简称SDOWN)
      • 是单个Sentinel实例对服务器做出的下线判断,比如网络问题接收不到通知等
      • 一个服务器没有在down-after-milliseconds选项所指定的时间内,对向它发送PING命令的Sentinel返回一个有效回复(valid reply),那么Sentinel就会将这个服务器标记为主观下线
    • 客观下线(Objectively Down,简称ODOWN)
      • 指的是多个Sentinel实例在对同一个服务器做出SDOWN判断,并且通过Sentinel is-master-down-by-addr命令互相交流之后,得出的服务器下线判断
      • 一个Sentinel可以通过向另一个Sentinel发送Sentinel is-master-down-by-addr命令来询问对方是否认为给定的服务器已下线
      • 客观下线条件只适用于主服务器
    • 仲裁(qurum)
      • Sentinel在给定的时间范围内,从其他Sentinel那里接收到了【足够数量】的主服务器下线报告,那么Sentinel就会将主服务器的状态从主观下线改变为客观下线
      • 这个【足够数量】就是配置文件里面的值,一般是Sentinel个数的一半+1,比如3个Sentinel则就设置为2
      • down-after-milliseconds是一个哨兵在超过规定时间依旧没有得到响应后,会自己认为主机不可用
      • 当拥有认为主观下线的哨兵达到sentinel monitor所配置的数量时,就会发起一次投票,进行failover

5.Sentinel哨兵模式流程解析和实战

  • 核心流程解析

    • 每秒ping,超过时间不响应则认为主观下线
    • 满足多个主观下线则认为是客观下线
    • 投票选择主节点
    • 如果没有足够的节点同意master下线,则状态会被移除
  • 环境准备

    • 配置3个哨兵,每个哨兵的配置都是一样的
    • 启动顺序,先启动主节点再启动从节点,最后启动3个哨兵
    • 哨兵端口记得开放
    # 不限制IPbind 0.0.0.0# 后台运行daemonize yes# 配置监听的主服务器,mymaster代表服务器的名称,自定义;2代表只有两个或两个以上的哨兵认为主服务器不可用的时候才会进行failover操作sentinel monitor mymaster 192.168.1.12 6379 2# 定义服务的密码sentinel auth-pass mymaster 123456# 超过5秒master还没有连接上,则认为master已经停止sentinel down-after-milliseconds mymaster 5000# 如果该时间内没完成failover操作,则认为本次failover失败sentinel failover-timeout mymaster 30000
  • vim /data/redis/sentinel1.conf

    port 26379bind 0.0.0.0daemonize yessentinel monitor mymaster 192.168.1.12 6379 2sentinel auth-pass mymaster 123456sentinel down-after-milliseconds mymaster 5000sentinel failover-timeout mymaster 30000pidfile /var/run/redis_sentinel1.pidlogfile "/usr/local/redis6/log/redis_sentinel1.log"dir /usr/local/redis6/data
  • vim /data/redis/sentinel2.conf

    port 26380bind 0.0.0.0daemonize yessentinel monitor mymaster 192.168.1.12 6379 2sentinel auth-pass mymaster 123456sentinel down-after-milliseconds mymaster 5000sentinel failover-timeout mymaster 30000pidfile /var/run/redis_sentinel2.pidlogfile "/usr/local/redis6/log/redis_sentinel2.log"dir /usr/local/redis6/data
  • vim /data/redis/sentinel3.conf

    port 26381bind 0.0.0.0daemonize yessentinel monitor mymaster 192.168.1.12 6379 2sentinel auth-pass mymaster 123456sentinel down-after-milliseconds mymaster 5000sentinel failover-timeout mymaster 30000pidfile /var/run/redis_sentinel3.pidlogfile "/usr/local/redis6/log/redis_sentinel3.log"dir /usr/local/redis6/data
  • 启动哨兵集群

    /usr/local/redis6/bin/redis-server /data/redis/sentinel1.conf --sentinel/usr/local/redis6/bin/redis-server /data/redis/sentinel2.conf --sentinel/usr/local/redis6/bin/redis-server /data/redis/sentinel3.conf --sentinel
  • 优点:主从可以自动切换,可用性更高

  • 缺点:主从切换会丢失短暂数据;主节点的写能力和存储能力受限

6.SpringCloud整合Redis哨兵模式

  • 配置文件

    spring:redis:password: 123456sentinel:master: mymasternodes: 192.168.1.12:26379,192.168.1.12:26380,192.168.1.12:26381