• Redis之主从复制、哨兵模式、集群模式


    Redis之主从复制、哨兵模式、集群模式

    一、Redis主从复制

    1、Redis主从复制什么?
    • 主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器,前者称为主节点(Master),后者称为从节点(Slave)
    • 数据的复制是单向的,只能由主节点到从节点
    • 默认情况下,每台 Redis 服务器都是主节点,且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点
    2、Redis主从复制做什么的?

    **数据冗余:**主从复制实现了数据的热备份,是持久化之外的一个种数据冗余方式。

    **故障恢复:**解决单点故障,当主节点出现故障时,可以让从节点提供服务,实现快速的故障恢复

    **读写分离:**可以用于实现读写分离,主库写、从库读,读写分离不仅可以提高服务器的负载均衡能力,同时可以根据需要的变化,改变从库的数量。

    **负载均衡:**在主从复制的基础上,配合读写分离,可以又主节点提供数据的修改,由从节点提供读服务(即写redis数据时应用连接主节点),读redis数据时应用连通多个从节点分担读负载,可以大大提高redis服务器的并发量。

    **高可用基础:**redis的主从复制和MySQL主从复制一样,是其他高可用解决方案的基础。

    3、Redis主从复制的工作过程

    主从复制工作分为建立连接阶段、数据同步阶段和命令传播阶段。

    建立连接阶段:建立slave到master的连接,使master能够识别slave,并保存slave端口号。

    数据同步阶段:在slave初次连接master后,会复制master中的所有数据到slave。

    命令传播阶段:当master数据库被修改后,导致主从服务器数据数据不一致,此时需要让主从数据同步到一致的状态,同步的动作称为命令传播。

    3.1 建立连接阶段流程:

    image-20220822165819777

    首先在slave设置master的地址和端口,由slave向master发送请求
    然后master与slave建立socket连接
    只有slave开始周期性的给master发送ping命令,master响应ping命令,确保期间slave和master连通性。
    如果由认证的话,则需要slave向master发送认证信息,master给slave进行授权。
    最后slave将自己的接口信息发送个master,master将slave接口信息保存。
    最终目的实现:master保存slave信息,slave保存了master信息。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    3.2、数据同步阶段和命令传播阶段

    image-20220822171855697

    slave向master发送sync同步数据请求
    master会fork一个子进程,然后产生RDB文件(完备)的过程
    在完备的阶段,master是在持续写入数据的,这个阶段会使用AOF进行备份
    slave接受到RDB文件后,会将RDB文件载入的内存中,实现与master的数据同步。
    RDB持久化完成后,master会将AOF缓存起来的命令发送给slave,复制推送完成后,master会持续的同步操作命令。
    slave将接收到的AOF缓存的命令执行,实现与主库的实时同步。
    在下一台Redis接入主从复制的集群之前,会持续利用AOF的方式进行备份。
    
    从设备新接入主设备后的数据同步的过程就是数据同步阶段,在后续主设备使用AOF对从设备进行实时同步的过程是命令传播阶段。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    4、部署Redis主从复制
    4.1、三台主机都需要安装Redis

    Redis官网:https://redis.io/

    这里安装的是redis-5.0.7版本
    
    systemctl stop firewalld
    systemctl disable firewalld
    setenforce 0
    
    yum -y install gcc gcc-c++ make
    
    cd /opt
    #将软件包传至该目录下
    tar zxvf redis-5.0.7.tar.gz -C /opt/
    
    cd redis-5.0.7/
    make -j 4 && make PREFIX=/usr/local/redis install
    
    cd /opt/redis-5.0.7/utils/
    ./install_server.sh
    #回车,直到出现以下选项,手动修改为“/usr/local/redis/bin/redis-server”
    Please select the redis executable path [/usr/local/bin/redis-server] /usr/local/redis/bin/redis-server
    
    ln -s /usr/local/redis/bin/* /usr/local/bin/
    
    netstat -natp | grep "redis"
    #当 install_server.sh 脚本运行完毕,Redis 服务就已经启动,默认侦听端口为 6379
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    可以执行安装脚本:

    vim /opt/install_redis.sh
    //以下为脚本内容
    #!/bin/bash
    #stop firewall
    systemctl stop firewalld
    systemctl disable firewalld
    setenforce 0
    
    #install
    
    yum -y install gcc gcc-c++ make expect
    cd /opt
    tar zxvf redis-5.0.7.tar.gz -C /opt/
    cd /opt/redis-5.0.7/
    core=`grep -c "core id" /proc/cpuinfo`
    if [ $core -gt 2 ] ; then
            let core--
    fi
    make -j $core
    make PREFIX=/usr/local/redis install
    cd /opt/redis-5.0.7/utils/
    /usr/bin/expect <<-EOF
    spawn  ./install_server.sh
    expect "Please select the redis port for this instance"
    send "\r"
    expect "Please select the redis config file name"
    send "\r"
    expect "Please select the redis log file name"
    send "\r"
    expect "Please select the data directory for this instance"
    send "\r"
    expect "Please select the redis executable path"
    send "/usr/local/redis/bin/redis-server\r"
    expect "Is this ok? Then press ENTER to go on or Ctrl-C to abort."
    send "\r"
    expect eof
    EOF
    
    #init bash
    ln -s /usr/local/redis/bin/* /usr/local/bin/
    a=`netstat -natp | grep -c  "redis"`
    clear
    if [ $a -ne 0 ] ; then
    echo "redis install ok!"
    else
    echo "redis install fail!!"
    fi
    //执行脚本
    chmod +x /opt/install_redis.sh
    ./opt/install_redis.sh
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    4.2、修改Redis配置文件

    Master:

    vim /etc/redis/6379.conf
    bind 0.0.0.0                        #70行,修改监听地址为 0.0.0.0,默认监听所有网卡
    daemonize yes                       #137行,开启守护进程
    logfile /var/1og/redis_ 6379.1og    #172行,指定日志文件目录
    dir /var/lib/redis/6379             #264行,指定工作目录
    appendonly yes                      #700行,开启 AOF 持久化功能
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    slave:

    vim /etc/redis/6379. conf
    bind 0.0.0.0                        #70行,修改监听地址为 0.0.0.0
    daemonize yes                       #137行,开启守护进程
    logfile /var/log/redis_ 6379. log   #172行,指定日志文件目录
    dir /var/lib/redis/6379             #264行,指定工作目录
    replicaof 192.168.10.11 6379       #288行,指定要同步的 Master 节点 IP 和端口
    appendonly yes                      #700行,开启 AOF 持久化功能
    
    
    /etc/init.d/redis_6379 restart
    #重启服务使配置生效
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    4.3、验证主从效果

    在Master上看日志:

    tail -f /var/log/redis_6379.log
    
    • 1

    image-20220822185323913

    在master上验证从节点:

    redis-cli info replication
    
    • 1

    image-20220822185617320

    二、Redis哨兵模式

    1、什么是哨兵?

    哨兵(sentinel)是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master。

    2、哨兵是干什么的?
    • 监控
      • 不断地检查master和slave是否正常运行
      • master存活监测、master与slave运行情况检查
    • 通知(提醒)
      • 当被监控的服务器出现问题时,向其他(哨兵间、客户端)发送通知
    • 自动故障转移
      • 断开与master与slave连接。选举一个slave作为master,将其他slave连接到新的master,并告知客户端新的服务器地址

    注:

    • 每台redis服务器都要部署哨兵
    • 哨兵配置数量要为奇数(2n+1,n代表最大允许出故障的主机数)
    • 哨兵 + redis主从的部署架构,是不会保证数据零丢失的,只能保证redis集群的高可用性。
    3、哨兵工作原理

    监控阶段:

    获取各个sentine的状态(确认是否在线),这期间是利用ping命令进行测试,sentinel中信息的获取都是通过master来获取的,第一个sentinel先向master发送info指令并建立socket连接专门用来发命令,与此同时获取到了其他哨兵的状态以及其他从属服务器的信息,然后根据获取到的slave信息去连接每一个slave,第二个sentinel同样也会发命令连接master同时获取到了其他与master有关哨兵的信息,并与其他哨兵发布订阅,以保证与其他哨兵信息同步。

    通知阶段:

    当多个哨兵经过监控阶段组成了一个小的群体,彼此之间进行信息的互通,哨兵会时时刻刻通过他们之间已经建立的socket连接去获取他们对应的工作状态,不管是哪位哨兵获取到,都会将信息回传,在哨兵内部的网络中进行信息的互换。

    故障转移:

    sentinel1向master发送确认指令,master无回应,并且持续一定时间以后,sentinel1就会确认master已宕机,并将master标记为SRI_S_DOWN,之后将master指令传递到哨兵群体的内网中,传播master已宕机的消息,其他sentinel得到指令后,就会不断的向master发出确认,确定他是真的宕机了,确认完毕也分别将信息传播进内网里。

    4、sdown和odown转换机制

    sdown和odown两种失败状态

    • sdown是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机。

    • odown是客观宕机,如果quorum数量的哨兵都觉得一个master宕机了,那么就是客观宕机。

    • sdown达成的条件很简单,如果一个哨兵ping一个master,超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机。

    • sdown到odown转换的条件很简单,如果一个哨兵在指定时间内,收到了quorum指定数量的其他哨兵也认为那个master是sdown了,那么就认为是odown了,客观认为master宕机。

    5、搭建Redis哨兵模式
    5.1 修改Redis哨兵模式的配置文件
    vim /opt/redis-5.0.7/sentinel.conf
    
    protected- mode no                              #17行,关闭保护模式
    port 26379                                      #21行,Redis哨兵默认的监听端口
    daemonize yes                                   #26行,指定sentinel为后台启动
    logfile "/var/log/sentinel.log"                 #36行,指定日志存放路径
    dir "/var/lib/redis/6379"                       #65行,指定数据库存放路径
    
    sentinel monitor mymaster 192.168.10.11 6379 2
    #84行,修改,指定该哨兵节点监控 192.168.10.11:6379 这个主节点,该主节点的名称是 mymaster
    #最后的 2 的含义与主节点的故障判定有关:至少需要 2 个哨兵节点同意,才能判定主节点故障并进行故障转移
    
    sentinel down-after -milliseconds mymaster 30000#113行,判定服务器 down 掉的时间周期,默认 30000毫秒 (30)
    sentinel failover-timeout mymaster 180000       #146行,故障节点的最大超时时间为 180000 (180)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    4.2 启动哨兵模式

    先启动Master,再启动slave

    cd /opt/redis-5.0.7/
    redis-sentinel sentinel.conf &
    
    • 1
    • 2

    image-20220822225701850

    image-20220822230321878

    image-20220822230331690

    4.3 查看哨兵信息
    redis-cli -p 26379 info sentinel
    
    • 1

    image-20220822230413207

    image-20220822230422385

    image-20220822230432612

    4.4 模拟故障
    ps -elf | grep "redis" | grep -v "grep"
    #查看 redis-server 的进程号
    
    kill -9 [进程号]
    #杀死 Master 节点上的 redis-server 的进程号
    
    • 1
    • 2
    • 3
    • 4
    • 5

    image-20220822230843613

    4.6 验证结果
    tail /var/log/sentinel.log
    redis-cli -p 26379 info Sentinel
    
    • 1
    • 2

    三、Redis集群模式

    1、redis集群的概念
    • Redis集群是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。
    • Redis集群不需要sentinel哨兵也能完成节点移除和故障转移的功能。
    • 需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000个节点)。
    • redis集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单。
    • redis集群的运用主要是针对海量数据+高并发+高可用的场景。
    2、作用
    2.1 数据分片
    • 数据分片是集群的核心功能之一

    • 集群讲数据分散到多个节点,一方面突破了Redis单机内存大小的限制,存储容量大大增加,另外一方面每个主节点都可以对外提供读服务,大大提供了集群的响应能力。

    • 哈希槽

      • Redis 集群引入了哈希槽的概念,有 16384 个哈希槽(编号 0~16383)
      • 集群的每个节点负责一部分哈希槽,每个 Key 通过 CRC16 校验后对 16384 取余来决定放置哪个哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作
      • 以 3 个节点组成的集群为例:
        • 节点 A 包含 0~5469 号的哈希槽
        • 节点 B 包含 5461~10922 号的哈希槽
        • 节点 C 包含 10923~16383 号的哈希槽
    2.2 高可用
    • 集群支持主从复制和主节点的自动故障转移(与哨兵类似),当任意节点发送故障时,集群仍然可以对外提供服务
    2.3 Redis 集群的主从复制模型
    • 集群中具有 A、B、C 三个节点,如果节点 B 失败了,整个集群就会因为缺少 5461~10922 这个范围的槽而不可用
    • 为每个节点添加一个从节点(a、b、c),即整个集群便有了三个 Master 节点和三个 slave 节点,在节点 B 失败后,集群选举 b 为主节点继续服务,当 B 和 b 都失败后,整个集群将不可用
    3、搭建cluster集群模式
    1、准备

    四、总结

    1、常见三个模式对比
    模式版本优点缺点
    主从模式redis2.8之前1、解决数据备份问题2、做到读写分离,提高服务器性能1、master故障,无法自动故障转移,需人工介入2、master无法实现动态扩容
    哨兵模式redis2.8级之后的模式1、Master 状态监测2、master节点故障,自动切换主从,故障自愈3、所有slave从节点,随之更改新的master节点1、slave节点下线,sentinel不会对一进行故障转移,连接从节点的客户端因为无法获取到新的可用从节点
    2、master无法实行动态扩容
    redis cluster模式redis3.0版本之后1、有效的解决了redis在分布式方面的需求
    2、遇到单机内存,并发和流量瓶颈等问题时,可采用Cluster方案达到负载均衡的目的
    3、可实现动态扩容
    4、P2P模式,无中心化
    5、通过Gossip协议同步节点信息
    6、自动故障转移、Slot迁移中数据可用
    7、自动分割数据到不同的节点上
    8、整个集群的部分节点失败或者不可达的情况下能够继续处理命令
    1、架构比较新,最佳实践较少
    2、为了性能提升,客户端需要缓存路由表信息
    3、节点发现、reshard操作不够自动化
    4、不支持处理多个keys的命令,因为这需要在不同的节点间移动数据
    5、Redis 集群不像单机 Redis 那样支持多数据库功能, 集群只使用默认的 0 号数据库, 并且不能使用 SELECT index 命令

    机内存,并发和流量瓶颈等问题时,可采用Cluster方案达到负载均衡的目的
    3、可实现动态扩容
    4、P2P模式,无中心化
    5、通过Gossip协议同步节点信息
    6、自动故障转移、Slot迁移中数据可用
    7、自动分割数据到不同的节点上
    8、整个集群的部分节点失败或者不可达的情况下能够继续处理命令 | 1、架构比较新,最佳实践较少
    2、为了性能提升,客户端需要缓存路由表信息
    3、节点发现、reshard操作不够自动化
    4、不支持处理多个keys的命令,因为这需要在不同的节点间移动数据
    5、Redis 集群不像单机 Redis 那样支持多数据库功能, 集群只使用默认的 0 号数据库, 并且不能使用 SELECT index 命令 |

  • 相关阅读:
    Java开发工具之使用cmd安装MySQL数据库
    Collection集合 迭代器 增强for List集合 LinkedList集合详解
    struct结构体【C#】
    详细介绍@GetMapping和@PostMapping的区别
    Spring Boot 注解详解:一步一步了解Spring Boot的核心注解
    【Java 进阶篇】Java XML组成部分:理解XML的结构
    linux并发服务器 —— 项目实战(九)
    Flask 框架:运用Echarts绘制图形
    Cuda cmake支持C++17
    kubernetes数据持久化PV-PVC详解(一)
  • 原文地址:https://blog.csdn.net/weixin_46514551/article/details/126616454