Redis进阶

RDB(Redis DataBase)

概念

在指定时间间隔内将内存中的数据集快照写入磁盘

流程

Redis 会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件,

待持久化过程结束,再用临时文件替换上次持久化好的文件,默认 dump.rdb

优缺点

优点:

  1. 整个过程中,主进程不进行任何 IO 操作,这就确保了极高的性能

  2. 如果对数据恢复的完整性不敏感,那么比 AOF 更加高效。

  3. 节省磁盘空间,恢复速度快

缺点:

  1. 最后一次持久化后的数据可能丢失
  2. 虽然使用了写时复制技术,但是如果数据庞大还是比较消耗性能
  3. Fork 的时候内存中的数据被克隆一份,大致 2 倍的膨胀性需要考虑

Fork

  1. Fork 的作用是复制一个与当前进程一样的进程,所有的数据均一致,

    但是是一个全新的进程,并作为原进程的子进程

  2. 写时复制技术

  3. 一般情况父进程和子进程共用一段物理内存


AOF(Append Only File)

  1. 概念

    以日志的形式来记录每个写操作(增量保存),

    将 Redis 执行过的所有写指令记录下来(读操作不记录),

    只许追加文件但不可以改写文件,Redis 启动时会读取文件重构数据

  2. 流程

    • 客户端的请求写命令会被 append 追加到 AOF 缓冲区内
    • AOF 缓存区根据 AOF 持久化策略将操作 sync 同步到磁盘 AOF 文件
    • AOF 文件大小超过重写策略或手动重写时,进行 rewrite 重写和压缩
    • Redis 服务启动时,会重新加载 AOF 文件中的写操作恢复数据
  3. 设置

    1. AOF 默认不开启,需要在配置文件中将 appendonly 改为 yes
    2. AOF 和 RDB 同时开启时,系统默认取 AOF 的数据(数据不会存在丢失)
    3. 异常通过 redis-check-aof --fix appendonly,aof 恢复文件,重启即可
    4. 同步频率设置 appendfsync:
      • always:始终同步,每次 Redis 的写入都会立刻记入日志,完整性好但性能差
      • everysec:每秒同步,如果宕机,本秒的数据可能丢失
      • no:不主动进行同步,把同步时机交给操作系统
    5. Rewrite 压缩:避免 AOF 文件过大,采用重写机制,将内容压缩
  4. 优缺点

    优点:

    1. 备份机制更稳健,丢失数据概率更低
    2. 可读的日志文本,可以处理误操作

    缺点:

    1. 占用更多的磁盘空间
    2. 恢复备份速度慢
    3. 每次读写都同步的话,存在一定的性能压力
    4. 存在个别 bug,造成恢复不能

对比

  1. 官方推荐两个都启用
  2. 如果对数据不敏感,可以单独使用 RDB
  3. 不建议单独使用 AOF,可能会出现 bug
  4. 如果只是做纯内存缓存,可以都不用

主从复制

  1. 概念

    主机数据更新后根据配置和策略,自动同步到备机的 master/slaver 机制,

    master 以写为主,slaver 以读为主,但是会存在复制延时的情况,

    当系统繁忙或 slaver 机器数量增加的时候,延迟问题会更加严重

  2. 作用

    • 读写分离,性能拓展
    • 容灾快速恢复
  3. 搭建简单的一主两从

    1. 创建 /myRedis 文件夹,拷贝 redis.Windows.conf 文件至目录下

    2. 配置一主两从,创建三个配置文件

      1
      2
      3
      redis6379.conf
      redis6380.conf
      redis6381.conf
    3. 在每个配置文件中写入以下内容(替换 6379 即可)

      1
      2
      3
      4
      include redis.windows.conf
      pidfile /var/run/redis_6379.pid
      port 6379
      dbfilename dump6379.rdb
    4. 启动三个 Redis 服务

      • 查看当前主机运行状况
      • 在从机上执行 slaveof 主机 ip 端口号
      • SLAVEOF 127.0.0.1 6379 配置主从关系
      • 验证主从的基本性质,master 以写为主,slaver 以读为主
  4. 主从复制特点

    • 一主二仆
    • 薪火相传
    • 反客为主
  5. 哨兵模式

    1. 反客为主的自动版,能够后台监控主机是否故障,根据投票数将从库转为主库

    2. 模拟案例

      1. 建立一个简易的一主二仆模式

      2. /myRedis 目录下建立 sentinel.conf 文件

      3. 写入 sentinel monitor mymaster 127.0.0.1 6379 1

        mymaster 为监控对象起的名称,1 为至少有多少个哨兵同意迁移的数量

      4. 如果你使用 redis-sentinel 可执行文件,你可以使用下面的命令来运行 Sentinel

        1
        redis-sentinel /path/to/sentinel.conf

        另外,你可以直接使用 redis-server 并以 Sentinel 模式来启动:

        1
        redis-server /path/to/sentinel.conf --sentinel
      5. 将主机关闭,查看结果即可

    3. 选择条件依次如下

      • 选择优先级靠前的(redis.conf 中的 slave-priority 值越小优先级越高)
      • 选择偏移量最大的(获得最全原主机数据的从服务)
      • 选择 runid 最小地从服务(每个 Redis 启动后随机生成的 40 位 runid)

集群

  1. 概念

    Redis 集群实现了对 Redis 的水平扩容,即启动 N 个 Redis 节点,

    将整个数据库分布存储在这 N 个节点中,每个节点存储总数据的 1/N,

    集群通过分区来提供一定程度的可用性,即使集群中有一部分节点失效或者无法进行通讯,

    集群也可以继续处理命令请求

  2. 搭建简易集群
    1. 在目录下创建六份实例 redis.conf

    2. 在主从的基础上,添加以下内容(替换 6379 即可)

      1
      2
      3
      cluster-enabled yes
      cluster-config-file nodes-6379.conf
      cluster-node-timeout 15000
    3. 启动六个 Redis 服务,将节点合成一个集群

      启动服务后,确保所有的 nodes-xxxx.conf 文件生成正常

      1
      redis-cli --cluster create --cluster-replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6389 127.0.0.1:6390 127.0.0.1:6391

      通过任意节点进入集群 redis-cli.exe -p 6379

      查看集群节点信息 cluster nodes

  3. 如何分配节点

    --cluster-replicas 1 表示为集群中的每个主节点创建一个从节点

    分配原则尽量保证每个主数据库运行在不同的 IP 地址,每个主库和从库不在一个 IP 地址上

  4. 插槽 Hash Slot

    一个集群包含 16384 个插槽,数据库中的每个键都属于其中一个,

    集群使用公式 CRC16(key) % 16384 来计算 key 属于哪个槽,

    而集群中的每个节点负责处理一部分插槽

  5. 故障恢复

    • 如果主节点宕机,从节点根据超时时间自动升为主节点

    • 主节点恢复后,主节点变成从机

    • 如果所有某段插槽的主从节点都宕机,

      集群根据 cluster-require-full-coverage 是否宕机

  6. 优缺点

    优点:

    1. 实现扩容
    2. 分摊压力
    3. 无中心配置相对简单

缺点:

  1. 多键操作是不支持的
  2. 多键的 Redis 事务是不被支持的,lua 脚本不被支持
  3. 出现较晚,目前整体迁移复杂度较大