• Redis的持久化机制


    持久化机制

    RDB:快照模式
    AOF :日志模式

    多数据库
    – 一个redis服务器内部默认有16个数据,编号О0-15
    – 默认操作是编号为0的数据库
    – 可以在命令行用select选择数据库
    127.0.0.1:6379> select 0
    OK
    127.0.0.1:6379> select 1
    OK
    --多个数据库是隔离开的,不影响key
    通过save命令实现持久化
    -客户端发送save命令
    -服务器端收到命ј并执行后,会阻塞客户端的请求
    127.0.0.1:6379[1]> save
    O
    [root@hongquan1 ~]# cd /etc/redis/
    -rw-r--r-- 1 root root 36 Apr 11 06:39 dump.rdb

    通过bgsave命令
    -可以在命令行触发
    --命令行执行bgsave,立即触发执行
    -可以通过服务器端条件触发
    • save seconds ops即͹在seconds秒内发生ops次数数据变化 就会触发RDB持久化操作
    • Save 900 1 代表在900秒内有一次数据变更操作就触发持久化
    • 可以同时配置多条触发条件
    127.0.0.1:6379[1]> bgsave
    Background saving started
    通过过bgsave命令
    – 通过fork一个子进程进行保持操作,所以bgsave不会阻塞客户端请求
    – 父进程负责处理客户端请求,父子程通过fork的copy on write技术进行数据同步
    – 在bgsave执行期间,客户端发送的save和bgsave命令将会被拒绝
    – BGREWITEAOF命令和bgsave命令不能同时执行,如果这时正在执行bgsave命令,则只有执行完成后才会接着执行BGREWITEAOF
    原理
    • Redis有一个周期性函数每隔100ms执行一次,此函数名叫serverCron,此函数的其中一个检测项就是save配置
    • 服务器端维护两个属性:dirty,即上次保存数据库发生多少次操作ͺlastsave,即上次执行操作的时间
    RDB配置项
    – stop-writes-on-bgsave-error true当在bgsave执行出错时,阻止前面的请求,默认是true
    – Rdbcompression yes是否对RDB文件进行压缩,默认是yes
    – rdbchecksum yes是否对rdb文件进行校验,默认是yes
    – dbfilename dump.rdb rdb文件名
    – dir ./ RDB文件存储目录,必须是目录
    # save ""

    save 900 1
    save 300 10
    save 60 10000
    dbfilename dump.rdb
    dir ./
    [root@hongquan1 redis]# find / -name dump.rdb
    /etc/redis/dump.rdb
    /root/dump.rdb
    /dump.rdb
    /home/mysql/backup/binlogbk4/dump.rdb
    /usr/local/redis/src/dump.rdb

    RDB存储结构
    redis5种数据类型,无论是key还是value,存储后的类型都为REDIS_RDB_TYPE_STRING

    AOF持久化
    – AOF即Append Only File,保持redis的执行命令来记录数据
    – 重新加载时,通过重放这些命令来实࣫数据的恢复
    – 文件里面的命令是纯文本格式,可以直接打开观察里面的内容
    – 整个过程中只有一个文件,通过重写技术缩减此文件的大小
    – 命令执行成功后才会写入AOF文件
    AOF写入原理
    – 1.客户端发送请求
    – 2.服务器端处理请求,如果是写请求,则把请求转换为操作命令放入aof缓存队列
    – 3.当redis的主进程主线程重新进入循(时即处理完一次事件请求,重新进入下一次事件)时,进行相关处理(其中一件з情就是检查aof_buf)
    – 4.把aof_buf中的命令写入文件
    – 5.根据同步配置策略把文件内容村入磁盘
    • Alaways:立即进入磁盘
    • Everysec:每秒进入一次 ,默认
    • No,操作系统自己决定什么时候进入

    AOF配置
    – Aof和rdb可以同时配置------/usr/local/redis/src/redis-cli config set appendonly yes
    – appendonly no //是否开启aof,默认是不开启
    – appendfilename "appendonly.aof" //aof文件名
    – appendfsync everysec //aof文件进入磁盘的策略
    – no-appendfsync-on-rewrite no //当正在做rdb的save或者aof的重写时,不要强行做磁盘刷新,会严重影响性能
    – auto-aof-rewrite-percentage 100 //百分比,当前aof文件超过最后一次rewirteեaof文件的多少(百分比)触发aof文件的rewrite操作,比如上一次rewrite后为50m,百分比配置为100,则当前aof文件达到
    100m后会触发aof的rewrite操作
    – auto-aof-rewrite-min-size 64mb //根据percentage触发rewrite的aof最小值,即:即使满足触发的百分比,如果aof文件也达不到64m,也不会触发
    – aof-load-truncated yes //
    • 当aof文件出࣫损坏时是否加载,此种损坏是由于操作系统的文件系统导致,不是redisߎ身导致
    • Yes表示加载,redis会尽量加载最全的时间,并且在日志中提示出࣫问题了
    • No表示不加载,会导致redis启动失败
    Redis启动数据加载
    -服务器判断是否开启了aof配置,如果开启则使用aof恢复数据,如果没有则采用rdb进行恢复
    -服务器内部启动一个伪客户端,通过伪客户端来重放aof文件里面的命令实现恢复
    [root@hongquan1 /]# find / -name appendonly.aof
    /appendonly.aof
    /usr/local/redis/src/appendonly.aof
    [root@hongquan1 redis]# tail -n 100 63079.log

    AOF重写
    背景:大量的写操作会导致aof文件膨胀,主要是某些数据的中间状态状态比较多导致
    并不是对࣫有aof文件进行读再再合并等操作,而是把当前redis的数据库重写做一次aof,比如
    为了避免重写时导致客户端输入缓冲区溢出,当处理列表 哈希表 集合 有序集合时,如果长度超过64个,则分成多条语句来
    执行,64个是通过常量redis.h/REDIS_AOF_REWRITE_PER_CMD配置
    AOF rewrite。其功能就是重新生成一份AOF文件,新的AOF文件中一条记录的操作只会有一次

    AOF重写原理
    在重写过程中如何保证可以继续接收客户端命令,又能保证数据一致性
    – 不阻塞客户端命令请求:通过子进程进行重写操作
    – 保证数据一致性:增加aof重写缓冲区,即启动冲写子进程后,所有变更的数据操作都要写入冲写缓冲区
    – 触发时机
    • 客户端执行:bgrewriteaof
    • 满足auto-aof-rewrite-percentage
    127.0.0.1:6379[1]> bgrewriteaof
    Background append only file rewriting started
    --6379.log
    23387:C 11 Apr 07:36:52.524 * AOF rewrite: 0 MB of memory used by copy-on-write
    22828:M 11 Apr 07:36:52.603 * Background AOF rewrite terminated with success
    22828:M 11 Apr 07:36:52.603 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
    22828:M 11 Apr 07:36:52.603 * Background AOF rewrite finished successfully
    [root@hongquan1 etc]# find / -name appendonly.aof
    /appendonly.aof

    写操作的流程
    首先我们来看一下数据库在进行写操作时到底做了哪些事,主要有下面五个过程。

    1客户端向服务端发送写操作(数据在客户端的内存中)
    2数据库服务端接收到写请求的数据(数据在服务端的内存中)
    3服务端调用write(2) 这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)
    4操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)
    5磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)
    故障分析上面的5个流程看一下各种级别的故障。
    当数据库系统故障时,这时候系统内核还是OK的,那么此时只要我们执行完了第3步,那么数据就是安全的,因为后续操作系统会来完成后面几步,保证数据最终会落到磁盘上。
    当系统断电,这时候上面5项中提到的所有缓存都
    写操作大致有上面5个流程,下面我们结合会失效,并且数据库和操作系统都会停止工作。所以只有当数据在完成第5步后,机器断电才能保证数据不丢失,
    在上述四步中的数据都会丢失。
    通过上面5步的了解,可能我们会希望搞清下面一些问题:

    数据库多长时间调用一次write(2),将数据写到内核缓冲区
    内核多长时间会将系统缓冲区中的数据写到磁盘控制器
    磁盘控制器又在什么时候把缓存中的数据写到物理介质上
    对于第一个问题,通常数据库层面会进行全面控制。而对第二个问题,操作系统有其默认的策略,但是我们也可以通过POSIX API提供的fsync系列
    命令强制操作系统将数据从内核区写到磁盘控制器上。对于第三个问题,好像数据库已经无法触及,但实际上,大多数情况下磁盘缓存是被设置关
    闭的。或者是只开启为读缓存,也就是写操作不会进行缓存,直接写到磁盘。建议的做法是仅仅当你的磁盘设备有备用电池时才开启写缓存。

  • 相关阅读:
    Asp.net core 3.1+EF Core2.2.6+Oracle.EntityFrameworkCore2.1.19连接Oracle数据库
    外业数据采集平台(GPS+Android Studio+Arcgis for android 100.2.1)
    Android Studio 单元测试
    1.泛型(Generic)
    营销推广软件,抢沙发功能,滑动解锁,自动提交文章评论,使用Puppeteer(一)
    C# 使用Tesseract-OCR-v5.0,实现验证码,中文,身份证识别
    Tesseract-OCR-v5.0中文识别,训练自定义字库,提高图片的识别效果
    C# 实现验证码识别,使用AspriseOCR.dll
    C# 自动批量搜索指定关键字,没有注册的域名
    C#图片采集软件 自动翻页 自动分类(收集美图必备工具)(一)
  • 原文地址:https://www.cnblogs.com/yhq1314/p/10001049.html
Copyright © 2020-2023  润新知