redis 高级特性

数据编码

在这里插入图片描述

持久化

  • RDB 是一次全量备份,AOF 日志是连续的增量备份,
  • RDB 是内存数据的二进制序列化形式,而 AOF 日志记录的是内存数据修改的指令记录文本

RDB

  • RDB持久化是将某个时间点上Redis中的数据保存到一个RDB文件
    • 因此RDB持久化也叫做快照持久化
  • 根据以下规则把内存中的数据复制到硬盘上,这称为快照
    • 用户执行SAVE, BGSAVE或者FLUSHALL命令
      • SAVE会同步复制,执行时会阻塞所有请求,避免在生产中使用
      • BGSAVE会异步复制,通过LASTSAVE获取最近一次成功执行快照的Unix时间
      • FLUSHALL会清空数据库中的所有数据,并在配置了自动快照时进行快照
    • 通过参数配置自动快照,超过一定时间或被更改的键大于一定数量后进行异步快照
      • 通过save选项设置多个保存条件,只要其中任意一个条件被满足,服务器就会执行BGSAVE命令
    • 设置了主从模式时,会在初始化从库时进行自动异步快照,并发送给从库
  • RDB文件存储上非常紧凑,是经过压缩的二进制格式
    • 占用空间会小于内存中的数据大小
    • 便于网络传输
  • 通过RDB方式来持久化时,redis异常退出会丢失最后一次快照后更改的数据
    • 如果不允许数据丢失,应该使用AOF方式进行持久化
  • 通过载入RDB文件文件可以还原生成RDB文件时Redis中的数据
    • Redis载入RDB文件并没有专门的命令,而是在Redis服务器启动时自动执行的
  • Redis服务器启动时是否会载入RDB文件取决于服务器是否启用了AOF持久化功能
    • 默认情况下Redis服务器的AOF持久化功能是关闭的,所以Redis服务器在启动时会载入RDB文件

在这里插入图片描述

  • Redis 使用操作系统的多进程COW(Copy On Write) 机制来实现 RDB 持久化
    在这里插入图片描述

AOF

  • AOF 的主要作用是解决了数据持久化的实时性,目前已经是 Redis 持久化的主流方式
  • 每次在执行写命令前储存命令本身到AOF文件中
    • 会一定程度上降低性能
    • 先存到磁盘,然后再执行指令
  • AOF文件以文本格式储客户端原始通信协议的内容
  • Redis通过逐一执行(重放)AOF文件中的命令来恢复数据到内存
    • 恢复速度较RDB会慢一些

在这里插入图片描述

  • Redis支持自动重写AOF文件
    • 作用: 减少冗余命令
      • 否则随着Redis服务器运行时间的增加,AOF文件中的内容会越来越多,文件的体积会越来越大
      • 不仅过多的占用服务器磁盘空间,使用AOF文件来进行数据库还原所需的时间也越多
    • 原理:
      • 不需要对现有的AOF文件进行任何读取、分析或者写入操作,而是通过读取服务器当前的数据库数据来实现的
      • 首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令
      • 记录完毕后再将操作期间发生的增量 AOF 日志追加到这个新的 AOF 日志文件中,追加完毕后就立即替代旧的 AOF 日志文件了
    • AOF重写功能被放到后台子进程里执行
      • 子进程进行AOF文件重写期间,服务器进程(父进程)可以继续处理命令请求
      • 子进程带有服务器进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性
        在这里插入图片描述
  • 默认不开启AOF持久化
    • 可以通过appendonly yes配置来启用
    • 此时重新启动Redis时会通过AOF而不是RDB来恢复数据
      • 因为可能丢失的数据更少
      • 会读入并重新执行一遍AOF文件里面保存的写命令,就可以还原Redis服务器关闭之前的数据
  • 由于操作系统会缓存写入硬盘的数据,所以AOF也会存在数据丢失的风险
    • 可以配置主动刷新缓存到硬盘的规则和时间
      • always每次执行都会同步
      • everysec每秒同步一次
      • no让操作系统决定何时刷入硬盘

在这里插入图片描述

混合持久化

在这里插入图片描述

高可用

主从同步

  • 主从结构实现了读写分离,提高了redis服务器的负载
  • 为了避免单点故障,应该把数据复制多个副本到不同服务器上
    • 虽然持久化可以避免服务器重启造成了数据丢失,但是如果硬盘坏了仍会丢失数据
    • 而且恢复数据需要较久时间,会影响线上服务的持续运行
  • redis提供了replication功能,可以在一台服务器数据更新后,自动同步到其他数据库上
    • 只需要在从库配置文件中加上salveof 主库地址 端口
    • 主库无需任何配置

在这里插入图片描述
在这里插入图片描述

  • 特性
    • 主库可读可写,从库只读
      • 只有读压力被分摊了,而由于主库对于写请求还要同步给从库,写压力反而增大了
    • 一个主库可以有多个从库,一个从库只能有一个主库
    • 从库可以转化为主库
      • 通过SLAVEOF NO ONE命令来停止接受同步数据
  • 主库异步同步数据给从库
    • 避免主库性能降低
    • 可能造成数据短期不一致
      在这里插入图片描述
  • 由于持久化操作相对耗时,可以在从库中启动持久化,而主库关闭持久化
    • 这样可以提高写性能
    • 从库崩溃后,主库会自动同步数据过来
    • 主库崩溃后,现将从库设计为主库,然后把主库设置为新库的从库
      • 这样就把数据从从库同步回主库了

-

主从复制

  • 从库启动时的复制过程
    在这里插入图片描述

  • 增量复制

    • 实现方式
      • 从库会存储主库的run ID
        • 每个redis实例都有一个唯一的运行ID
        • 重启后会生成一个新ID
      • 同步时主库在传输命令时会同时写入backlog中,并记录当前积压队列命令的偏移量范围
        • backlog中储存的就是命令的文本
      • 从库收到命令后会记录该命令的偏移量
      • 开始增量复制是,从库使用PSYNC替换SYNC命令,并带上主库运行ID和命令偏移量
    • 主库如何判断是否能够增量复制
      • 判断传来的ID是不是和自己的一样
        • 保证之前从库是和自己同步的,避免拿到错误数据
        • 比如主库曾经断线重启过,此时ID会变,也会造成数据不一致
      • 判断传来的命令偏移量是否在backlog队列中,如果在则发送队列中的剩余命令
    • 如果不能增量复制,会执行一次全量同步
    • backlog体积设置的越大,容忍的主从断线时间越长
  • 从数据库也可以作为主库来接入从库,以承受更大的读压力
    在这里插入图片描述

    • 无硬盘复制
      • 基于RDB持久化的复制方式的缺点
        • 当主库就用RDB快照时,如果进行了主从复制,后续主库会从本次快照恢复数据,导致可能大量数据丢失
        • 如果硬盘性能很慢,而RDB复制需要写入硬盘,会导致性能降低
      • 开启无硬盘复制时,会直接通过网络发送数据给从库,而不需要先将快照写入硬盘

哨兵

  • 作用

    • 监控主库和从库是否正常运行
    • 主库故障时,自动选择一个最优的从节点切换为主节点
  • 客户端视角

    • 客户端来连接集群时,会首先连接 sentinel,通过 sentinel 来查询主节点的地址, 然后再去连接主节点进行数据交互
    • 当主节点发生故障时,客户端会重新向 sentinel 要地址,sentinel 会将最新的主节点地址告诉客户端
      在这里插入图片描述
  • 哨兵是一个独立部署的进程,通过配置文件确定要监控的主库

    • 从库会被自动发现并监控,无需配置
    • 可以配置同时监控多个主库,也可多个哨兵监控一个主库
sentinel monitor 主库别名 地址 端口 quorum(执行故障恢复操作最少需要几个哨兵同意)

在这里插入图片描述

  • 最佳部署方案
    • 哨兵的视角尽可能和每个redis节点的视角一致
      • 为每个节点部署一个哨兵,无论是主库还是从库
      • 每个哨兵和其对应节点的网络环境一致
    • 设置quorum值为N/2+1,这样大部分哨兵同意后才进行故障恢复
    • 由于每个哨兵会和所有redis节点建立连接,所以上述方案会导致很多连接
      • 如果redis负载较高,会影响对哨兵的回复
  • 实现原理
    • 哨兵启动后会和要监控的主库建立2条连接
      • 该连接和普通的客户端连接无异
      • 一条用于订阅主库的__sentinel__:hello频道
        • 获取其他同样监控该库的哨兵信息
      • 一条定期发送INFO,PING等命令
    • 哨兵会定时执行下面3个操作
      • 每10秒向主库和从库发送INFO命令
        • 获取运行ID等消息,实现从库的自动发现主从切换的信息更新
      • 向主库和从库的__sentinel__:hello频道向其他哨兵分享自己的信息
        • 包括自己的基本信息和监控的主库相关信息
        • 这样可以自动发现其他哨兵
      • 通过定时PING监控redis和其他哨兵是否正常服务
  • 故障恢复
    • 当一个哨兵PING某个节点超过down-after-milliseconds指定的时间未回复,则该哨兵认为其主观下线
    • 如果该节点是主库,则该哨兵发送SENTINEL is-master-by-addr命令询问其他哨兵
    • 如果大于quorum的哨兵认为节点主观下线,则该节点被认为客观下线
    • 随后哨兵选举领头哨兵发起故障恢复流程
      • 保证同一时间只有一个哨兵执行故障恢复
      • 使用Raft算法进行选举
    • 领头哨兵指定一个从库,使用SLAVEOF NO ONE将其选为主库
      • 关于从节点选举,一共有四个因素影响选举的结果:
        • 断开连接时长、优先级排序、复制数量、进程id
      • 如果连接断开的比较久,超过了某个阈值,就直接失去了选举权
      • 如果拥有选举权,那就看谁的优先级高
        • 这个在配置文件里可以设置,数值越小优先级越高
      • 如果优先级相同,就看谁从master中复制的数据最多,选最多的那个
      • 如果复制数量也相同,就选择进程id最小的那个
    • 接着向所有其他从库发送SLAVEOF使其成为新主库的从库
      在这里插入图片描述

集群方案

在这里插入图片描述

Redis Cluster方案(官方)

  • redis3.0版本后支持cluster功能

    • 去中心化方案,没有proxy
    • 客户端分片
      在这里插入图片描述
  • 涉及多键的命令需要保证每个键都位于同一个redis节点中,否则报错

    • 例如mget命令
  • 使用INFO cluster命令判断是否正常启用的集群功能

    • cluster_enabled:1表示开启集群功能
  • 集群准备就绪后会向每个redis节点发送CLUSTER MEET ip port命令

    • 告诉当前节点指定地址和端口的节点也是集群的一部分
    • 加入新节点也只要发送上述命令给新节点A即可,地址和端口可以是集群中任意节点B的
      • A和B握手完成后,B会使用Gossip协议将A的信息通知给集群中的每个节点
  • 插槽的分配

    • 所有的键会被映射到16384个插槽,每个主库负责其中一部分插槽
    • 映射方式:
      • 使用CRC16算法计算哈希值,并对16384取余
      • 如果键名包含{XXX},则只取其中的部分来计算映射,否则使用整个键计算
        • 因此涉及多键操作时,需要每个键含有相同的{xxx}部分
    • 分配方式
      • 新增: 在待分配的节点上执行CLUSTER ADDSLOTS slot_num
      • 移动: 使用CLUSTER SETSLOT 槽号 NODE 新节点的运行ID
        • 前提是插槽中没有任何键,因为该命令不会迁移键,否则会导致客户端在指定节点无法找到未迁移的键
        • 手动获取插槽中存在的键,并手动迁移
          • 获取插槽中的键: CLUSTER GETKEYSINSLOT 槽号 数量
          • 迁移键:MIGRATE 目标地址 目标端口 键名 数据库号码 超时时间 [COPY] [REPLACE]
            • COPY表示不把键从老库删除,REPLACE表示如果目标节点存在同名键,则覆盖
            • 数据库号码在集群模式下只能为0
          • 如果先改插槽,就会造成键的临时丢失;如果先迁移键,那么客户端读写旧节点时也会造成数据临时丢失或修改失败
            • 因此手动迁移必须先下线集群
        • 在线上迁移数据需要增加以下命令告知客户端键被迁移到哪了(重定向)
          • CLUSTER SETSLOT 槽号 MIGRATING 新节点运行IDCLUSTER SETSLOT 槽号 IMPORTING 原节点运行ID
      • 查看: 使用CLUSTER SLOTS命令查看插槽对应的节点
        • 每条返回的记录的前两条是开始和结束槽号,接着是负责该槽段的库
        • 先是主库,然后是所有从库
          在这里插入图片描述
          在这里插入图片描述
          在这里插入图片描述在这里插入图片描述
  • 集群的故障恢复流程和哨兵类似,区别在于节点自己充当了哨兵角色
    在这里插入图片描述

Codis方案

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值