• Redis 持久化——学习笔记


    Redis 持久化

    1. Redis 持久化的取舍和选择

    持久化的作用

    什么是持久化

    • redis所有数据是保存在内存中的,对数据的更新将异步的保存到磁盘上。

    持久化的实现方式

    1. 快照方式
      • MySQL Dump
      • Redis RDB
    2. 写日志方式
      • MySQL Binlog
      • Hbase Hlog
      • Redis AOF

    2. RDB 持久化 方式

    什么是RDB?

    image

    触发机制——主要三种方式

    1. save(同步)生成RDB文件

    image

    image

    2. bgsave(异步)生成RDB文件

    image

    image

    image

    3. 自动生成RDB文件

    通过修改配置文件,控制自动生成RDB文件

    image

    缺点

    • RDB 生成频率太高
    • 不容易控制写入量

    配置

    save 900 1
    save 300 10
    save 60 10000
    dbfilename dump.rdb  # 生成RDB文件名
    dir ./               # 生成RDB文件、日志文件、AOF文件的存储路径
    stop-writes-on-bgsave-err yes  # bgsave 发生错误,将停止写入
    rdbcompression yes             # RDB 文件是否压缩 默认yes
    rdbchecksum yes                # 是否检查 RDB 文件校验和 默认yes
    

    最佳配置

    image

    触发机制——不容忽略的方式

    1. 全量复制(主从复制会触发生成RDB文件)
    2. debug reload (debug 级别重启 会触发生成RDB文件)
    3. shutdown (关闭 会触发生成RDB文件)

    试验

    • 试验 save 是否会阻塞
    • 试验 bgsave fork 过程
    • 自动配置的 save 是否真的有效
    • RDB 文件长什么样子

    配置启动试验redis

    1. cd redis # redis 目录的创建 参照redis 安装部分 https://www.cnblogs.com/guohewei/p/16246771.html#_label0_2
    2. mkdir config # 存放配置文件
    3. mkdir data # 存放RDB 文件
    4. cp redis.conf config/ # 复制默认配置文件
      • cat redis.conf | grep -v "#" | grep -v "^$" > redis-6382.conf # 去掉注释和空格
    5. 修改配置文件
      [root@nezha-api config]# vi redis-6382.conf
      port 6379
      daemonize yes
      pidfile /var/run/redis_6379.pid
      logfile 6379.log
      # save 3600 1
      # save 300 100
      # save 60 10000
      stop-writes-on-bgsave-error yes
      rdbcompression yes
      rdbchecksum yes
      dbfilename dump-6379.rdb
      dir /root/Redis/redis/data
      
    6. redis-server redis-6379.conf # 启动redis

    验证用例

    首先插入大量数据 (use memory 大于 500MB)

    1. 试验 save 是否会阻塞
      • 打开两个 redis-cli, 其中一个执行 save 后,另一个立即执行 'get hello', 查看执行时间,是否阻塞
    2. 试验 bgsave fork 过程
      • 打开两个 redis-cli, 其中一个执行 bgsave 后,另一个立即执行 'get hello', 查看执行时间,是否阻塞
      • 通过命令查看redis 进程 ps aux | grep redis- | grep -v "redis-cli"|grep -v "grep" 查看是否有 fork 进程
      • 查执行 bgsave 后,/root/Redis/redis/data 目录中是否有临时文件生成,等一会临时文件消失,dump-6379.rdb 文件被更新
    3. 自动配置的 save 是否真的有效
      • 修改配置文件
        [root@nezha-api config]# vi redis-6382.conf
        port 6379
        daemonize yes
        pidfile /var/run/redis_6379.pid
        logfile "6379.log"
        # save 3600 1
        # save 300 100
        save 60 5           # 60 秒 5条改变记录,自动执行 bgsave
        stop-writes-on-bgsave-error yes
        rdbcompression yes
        rdbchecksum yes
        dbfilename dump-6379.rdb
        dir /root/Redis/redis/data
        
      • 重启redis redis-cli shutdown && redis-server redis-6379.conf
      • 执行6次修改命令,查看rbd.文件生成、修改时间 ,查看日志文件是否有记录
        14801:M 12 May 2022 16:42:39.099 * 5 changes in 60 seconds. Saving...
        14801:M 12 May 2022 16:42:39.100 * Background saving started by pid 15013
        15013:C 12 May 2022 16:42:39.103 * DB saved on disk
        15013:C 12 May 2022 16:42:39.103 * RDB: 0 MB of memory used by copy-on-write
        14801:M 12 May 2022 16:42:39.201 * Background saving terminated with success
        

    总结

    1. RDB 是 Redis 内存到硬盘的快照,用于持久化
    2. save 通常会阻塞 Redis
    3. bgsave 不会阻塞 Redis, 但会fork 新进程
    4. save 自动配置满足任一就会被执行
    5. 有些触发 save 机制不容忽视

    3. AOF 持久化 方式

    RDB 现存问题

    • 耗时、耗性能

      image

    • 不可控、丢失数据

      image

    什么是AOF

    • AOF原理-创建

      image

    • AOF原理-恢复

      image

    AOF 三种策略

    1. always

    image

    2. everysec

    image

    3. no

    image

    always everysec no 对比

    通常使用 everysec 模式

    image

    AOF 重写

    image

    AOF 重新作用

    • 减少硬盘占用量
    • 加速恢复速度

    AOF 重写实现方式

    1. bgrewriteaof 命令

      image

    2. AOF 重写配置

      • auto-aof-rewrite-min-size: AOF 文件重写需要的尺寸

        就是当 AOF 文件达到多大的时候进行重写

      • auto-aof-rewrite-percentage: AOF 文件增长率

        就是当执行一次重写后,下一次达到多大进行重写(比如第一次达到100M重写,设置为 100%,则第二次达到200M再次重写)

    3. AOF 统计

      • aof_current_size: AOF 当前尺寸(单位:字节)
      • aof_base_size : AOF 上次启动和重写的尺寸(单位:字节)
    4. 重写自动触发时机

      (1) aof_current_size > auto-aof-rewrite-min-size (触发重写)

      (2) (aof_current_size - aof_base_size) / aof_base_size > auto-aof-rewrite-percentage (触发重写)

    5. AOF 重写流程

      image

    AOF 配置

    appendonly yes                          # 打开 AOF 功能
    appendfilename apppendonly-6379.aof     # AOF 文件名
    appendfsync everysec                    # AOF 策略
    dir /bigdiskpath                        # 存储生成RDB文件、日志文件、AOF文件的路径
    no-appendfsync-on-rewrite yes           # AOF 重写的时候,是否做正常的 append 操作
    auto-aof-rewrite-min-size 64mb          # 就是当 AOF 文件达到64mb的时候进行重写
    auto-aof-rewrite-percentage 100         # AOF 增长率大于 100% 重写
    aof-load-truncated yes                  # 重启加载 AOF 时,是否忽略由于AOF不完整,格式等错误 (yes 忽略)
    

    试验

    • AOF 生成
    • AOF 长什么样子
      [root@nezha-api data]# cat appendonly-6379.aof
      REDIS0009�	redis-ver6.2.7�
      �edis-bits�@�ctime���|bused-mem��W
       aof-preamble���counter�worldbigmy_listabcd��
                                                   s�<*2
      $6
      SELECT
      $1
      0
      *3
      $3
      set
      $4
      hehe
      $2
      go
      
    • AOF 配置
      # 基本配置
      port 6379
      daemonize yes
      pidfile /var/run/redis_6379.pid
      logfile "6379.log"
      dir /root/Redis/redis/data
      
      # AOF 配置
      appendonly yes                          # 打开 AOF 功能
      appendfilename apppendonly-6379.aof     # AOF 文件名
      appendfsync everysec                    # AOF 策略
      
      # AOF 重写配置
      no-appendfsync-on-rewrite yes           # AOF 重写的时候,是否做正常的 append 操作
      auto-aof-rewrite-min-size 64mb          # 就是当 AOF 文件达到64mb的时候进行重写
      auto-aof-rewrite-percentage 100         # AOF 增长率大于 100% 重写
      
      # AOF 重载配置
      aof-load-truncated yes                  # 重启加载 AOF 时,是否忽略由于AOF不完整,格式等错误 (yes 忽略)
      

    4. RDB 和 AOF 的抉择

    (1) RDB 和 AOF 的比较

    image

    (2) RDB 最佳策略

    • "关" 实际是关不了的(参见上文:"有些触发 save 机制不容忽视")
    • 集中管理 (定期 按天、按星期 等等)
    • 主从,从节点开 RDB

    (3) AOF 最佳策略

    • "开": 缓存和存储
      • 建议开启
      • 如果将redis单纯当做缓存使用,可以考虑关闭
    • AOF重新集中管理
      • 单机多部署的情况下,如果 AOF 集中发生,可能都在机器内存爆满
    • 使用 everysec 策略

    (4) 最佳策略

    • 小分片 (使用 maxmemory 对redis 进行规划,maxmemory=4GB)
    • 存储和缓存特性决定
    • 监控(硬盘、内存、负载、网络)
    • 保证足够的内存

    开发运维常见问题

    1. fork 操作

    1. fork 操作是同步操作,大多数情况下速度是非常快的 (只是做内存页的拷贝,不是完全内存的拷贝)
    2. 与内存量息息相关:内存越大耗时越长(与机器类型有关系)
    3. info Persistence 查看latest_fork_usec
      127.0.0.1:6379> info Persistence # 查看持久化信息
      # Persistence
      loading:0
      current_cow_size:0
      current_cow_size_age:0
      current_fork_perc:0.00
      current_save_keys_processed:0
      current_save_keys_total:0
      rdb_changes_since_last_save:0
      rdb_bgsave_in_progress:0
      rdb_last_save_time:1652358920
      rdb_last_bgsave_status:ok
      rdb_last_bgsave_time_sec:0
      rdb_current_bgsave_time_sec:-1
      rdb_last_cow_size:286720
      aof_enabled:1
      aof_rewrite_in_progress:0
      aof_rewrite_scheduled:0
      aof_last_rewrite_time_sec:0
      aof_current_rewrite_time_sec:-1
      aof_last_bgrewrite_status:ok
      aof_last_write_status:ok
      aof_last_cow_size:323584
      module_fork_in_progress:0
      module_fork_last_cow_size:0
      aof_current_size:207
      aof_base_size:153
      aof_pending_rewrite:0
      aof_buffer_length:0
      aof_rewrite_buffer_length:0
      aof_pending_bio_fsync:0
      aof_delayed_fsync:0
      
    4. 改善 fork
      • 优先使用物理机或者高效支持fork操作的虚拟化技术
      • 控制 Redis 实例最大可用内存:maxmemory
      • 合理配置Linux内存分配策略:vm.overcommit_memory=1 (默认是0 当发现没有足够内存分配,就不去分配) 这样会阻塞 fork, 所有设置为 1
      • 降低 fork 频率:如放宽 AOF 重写自动触发时机,不必要的全量复制

    2. 子进程开销和优化

    1. CPU

      • 开销: RDB 和 AOF 文件生成,属于CPU密集型
      • 优化: 不做 CPU 绑定,不和 CPU 密集型部署
    2. 内存

      • 开销: fork 内存开销,copy-on-write
      • 优化: echo never > /sys/kernel/mm/transparent_hugepage/enabled (关闭 可以优化内存,redis 用不着)
    3. 硬盘

      • 开销: AOF 和 RDB 文件写入,可以结合 iostat iotop分析
      • 优化:
        • 不要和高硬盘负载部署在一起:存储服务,消息队列
        • 增加配置no-appendfsync-on-rewrite yes: AOF 重写的时候,是否做正常的 append 操作
        • 根据写入量决定磁盘类型:例如ssd
        • 单机多部署持久化文件目录可以考虑分盘

    3. AOF 追加阻塞

    image

    AOF 追加阻塞问题定位

    1. 日志定位

      image

    2. info Persistence 查看latest_fork_usec

      127.0.0.1:6379> info Persistence # 查看持久化信息
      # Persistence
      aof_delayed_fsync:100  # 阻塞会加1,是历史累计值,无法判断那一段事件阻塞
      
    3. 通过硬盘观察

      image

  • 相关阅读:
    Python入门-函数进阶
    Python入门-初始函数
    Leetcode300. Longest Increasing Subsequence最长上升子序列
    Leetcode139. Word Break单词拆分
    Leetcode279. Perfect Squares完全平方数
    Leetcode319. Bulb Switcher灯泡开关
    Leetcode322. Coin Change零钱兑换
    二叉树三种遍历两种方法(递归和迭代)
    Leetcode145. Binary Tree Postorder Traversal二叉树的后序遍历
    Leetcode515. Find Largest Value in Each Tree Row在每个树行中找最大值
  • 原文地址:https://www.cnblogs.com/guohewei/p/16264637.html
Copyright © 2020-2023  润新知