Redis分布式缓存

Redis分布式缓存

单机Redis存在的四大问题

请添加图片描述

Redis持久化

RDB持久化

  • 简介

    • Redis的一种数据持久化方案,也叫Redis数据快照,简单来说就是将内存数据保存到磁盘中去,当redis实例故障重启后,就可以从磁盘中读取快照文件,恢复数据
  • 执行时机

    • 执行save命令时(主进程执行save时进程会阻塞,无法执行其他命令)
    • 执行bgsave命令时(bgsave命令会开启子进程去保存数据,基本不会阻塞主进程)
    • Redis停机时会自动执行一次
    • 满足RDB条件时,如900秒内至少有一个key被改变时
  • RDB其他配置,可在redis.conf文件中配置

    # 是否压缩 ,建议不开启,压缩也会消耗cpu,磁盘的话不值钱
    rdbcompression yes
    
    # RDB文件名称
    dbfilename dump.rdb  
    
    # 文件保存的路径目录
    dir ./ 
    
  • bgsave命令原理

    • 在linux系统中,所有的进程都无法直接操作物理内存,而是给进程提供一个虚拟内存,进程只能操作虚拟内存,由操作系统维护虚拟内存与物理内存的映射关系表,从而实现进程操作物理内存,当执行bgsave命令时,主进程会folk出一个子线程,子线程复制了一份主进程的映射关系表,由子进程读取内存中的数据并写入到新的RDB文件中去,然后使用新的RDB文件替换旧的RDB文件,这里采用了copy-on-write技术,此时,内存中的数据被设置为了只读状态,在子进程读取的过程中,主进程可能会接到修改内存数据的请求,即主进程需要读取数据时访问的是共享的数据,主进程需要修改数据时会复制一份内存数据再进行修改,修改后再次读取读取的就会是拷贝的数据
  • 原理图

请添加图片描述

  • 缺点

    • 执行间隔时间长,两次RDB之间可能会有数据丢失
    • folk子进程,压缩,写出RDB文件都比较耗时

AOF持久化

  • 简介

    • 将Redis处理的每一个命令都记录到aof文件中去,可看作是命令日志
  • AOF配置

AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:

# 是否开启AOF功能,默认是no
appendonly yes
# AOF文件的名称
appendfilename "appendonly.aof"

AOF的命令记录的频率也可以通过redis.conf文件来配:

# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always 
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec 
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no

三种策略对比:

请添加图片描述

  • AOF文件重写

    • 因为aof文件记录的是所有命令,其中必然有很多命令是不需要记录的,例如对同一个key的多次修改,仅需记录最后一次修改命令即可,通过执行bgrewriteaof命令,即可实现重写aof文件,使其记录的命令更加精简,Redis会在触发阈值时自动去重写aof文件,阈值可以在配置文件中设置

RDB与AOF对比

请添加图片描述

Redis主从架构

搭建意义

  • 单节点的redis并发能力是有上限的,要提高redis的并发能力,就要搭建redis主从集群,实现读写分离

主从数据同步原理

  • 全量同步

    • 第一次建立连接时,会进行一次全量同步,将master节点的所有数据全部拷贝给slave节点
    • 流程图

请添加图片描述

  • master如何判断slave是否是第一次连接?

    • 两个概念:

      • replicatioin id: 简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid

      • offset: 偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

        slave向master请求数据同步时需要声明自己的replication id和offset,因为slave原本也是一个master,有自己的replid和offset,当第一次变成slave,与master建立连接时,发送的replid和offset是自己的replid和offset。

        master判断发现slave发送来的replid与自己的不一致,说明这是一个全新的slave,就知道要做全量同步了。

        master会将自己的replid和offset都发送给这个slave,slave保存这些信息。以后slave的replid就与master一致了。

        因此,master判断一个节点是否是第一次同步的依据,就是看replid是否一致

  • 执行时机

    • slave节点第一次连接master节点时
  • slave节点断开时间太久,repl_baklog中的offset已经被覆盖时

  • 增量同步

    • 除了第一次建立连接时会做全量同步,其他时候都是做增量同步,即同步master与slave不同的地方
    • 流程图

请添加图片描述

  • repl_backlog原理

    ​ repl_backlog文件是一个环形数组,即当文件写满后,新的数据会从文件开头开始覆盖就的数据,这个文件里面记录了reids处理的命令日志,master和slave的偏移量offset,做增量同步时,会根据master和slave的偏移量大小差异拷贝不一致的数据,若slave断开连接太久,导致它尚未同步的数据已经被master写入的新数据覆盖,则无法基于该文件做增量同步,只能做全量同步

  • 执行时机

    • slave节点断开又恢复,并且在repl_baklog中能找到offset时
  • 全量同步和增量同步区别

    • 全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在repl_baklog,逐个发送给slave。
    • 增量同步:slave提交自己的offset到master,master获取repl_baklog中从offset之后的命令给slave

主从同步优化

  • Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO
  • 适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步
  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力
  • 在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时的磁盘IO。

主从架构图

请添加图片描述

Redis哨兵

Redis哨兵结构图

请添加图片描述

哨兵作用

  • 监控: Sentinel会不断检测master和slave是否按照预期正常工作

    • 集群监控原理:
      Sentinel基于心跳机制检测服务状态,每隔一秒向客户端实例发送ping命令
      主观下线: 如果某个sentinel发现某个服务实例未在指定时间内响应,则认为该实例主观下线
      客观下线: 如果指定数量(quorum)的Sentinel都认为某个服务实例主观下线,则认为该实例客观下线,quorum值最好超过Sentinel数量的一半
  • 故障自动恢复: 如果一个master故障,Sentinel会将一个slave提升为master,故障的实例恢复后也将以新的master为准,成为slave

    • 集群故障恢复原理:
      如果某个master故障,Sentinel需要在slave中选择一个作为新的master,选择依据如下:
      首先判断slave和master断开的时长,若断开时间超过指定值(down-after-milliseconds*10)则会排除该slave
      然后判断slave的slave-priority值,值越小优先级越高,为0则不参与选举
      若slave-priority值一致,则比较offset值的大小,越大表示数据越新,优先级越高
      最后判断slave的运行id大小,越小优先级越高
      选举成功后,切换流程如下:
      Sentinel给被选中的slave节点slave1发送slave of no one命令,使该节点成为master节点
      Sentinel向所有其他slave节点发送slaveof slave1(新master节点的ip地址和端口号),是他们成为新master节点的从节点,开始从新master上同步数据
      Sentinel将故障节点标记为slave,故障节点恢复后也将成为新master节点的slave
  • 通知: Sentinel充当Redis的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis客户端

Redis分片集群

作用

  • 解决海量数据储存和高并发写问题

Redis分片集群结构图

请添加图片描述

分片集群特征

  • 每个集群中由多个master,每个master保存不同的数据
    每个master都可以有多个slave节点
    master之间通过ping互相检测健康状态
    客户端请求可以访问任意节点,最终请求会被转发到正确节点

散列插槽

  • 插槽原理:
    Redis将每一个master映射到0-16383共16384个插槽(hash slot)上,数据的key并不与master绑定,而是与插槽绑定,redis会根据数据key的有效部分计算插槽值,分为两种情况:
  1. 若key中带有’{}‘,且’{}‘中至少有一个字符,则’{}'中的内容为有效部分
  2. 若key中不带’{}',则整个key为有效部分
    插槽值的计算方式为利用CRC16算法计算得到一个hash值,再对16384取余得到插槽值

集群伸缩

  • 集群伸缩是指在一个集群中增加或减少节点的数量,以适应不同的工作负载需求。集群伸缩的目的是为了自动化地分配和处理工作,同时最大化系统的利用率和可用性。当工作负载较轻时,可以减少集群的节点数量,以降低资源消耗和成本;而当工作负载增加时,可以增加集群的节点数量,以扩展系统容量,提高系统响应速度和性能。
    windows集群操作命令可通过redis-cli --cluster help查看

故障转移

  • 自动故障转移:
    若集群中某个master故障下线,则会经历从疑似宕机到确认下线的判断过程,然后自动提升一个slave为master,下线实例恢复后会成为slave节点
  • 手动故障转移:
    使用cluster failover命令可以将集群中指定的master宕机,并将执行该命令的slave提升为master,实现无感知数据迁移
    此命令可指定三种模式:
    缺省:不指定,默认如下图中1-6步
    force: 省略了对offset一致性的校验
    takevoer: 直接执行第五步,省略数据一致性校验,忽略master状态和其他master意见
  • 手动故障转移流程图

请添加图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值