一、RDB
RDB持久化通过保存数据库中的键值对记录服务器状态。
1、生成RDB文件
两个命令用于生成RDB文件,一个是SAVE,一个是BGSAVE。
两者区别:
1) SAVE命令会阻塞redis服务器进程,直到RDB文件创建完毕为止
调用函数:
def SAVE():
rdbSave()
2) BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求。
调用函数:
def BGSAVE():
pid=fork()
if pid==0:
rdbSave()
signal_parent() //完成后向父进程发送信号
else pid > 0:
handle_request_and_wait_signal() //父进程继续处理命令请求毛病通过轮训等待子进程的信号
else:
handle_fork_error() //处理出错情况
注意:
1、因为AOF文件更新频率通常比RDB文件的更新频率搞,所以
1)如果服务器开启了AOF持久化功能,那么服务器优先使用AOF文件还原数据库状态。
2)只有AOF持久化功能处于关闭时,服务器才会使用RDB文件来还原数据库状态。
2、考虑到性能方面,SAVE、BGSAVE、BGREWRITEAOF三个命令无法同时存在。
2、自动间隔性保存
因为BGSAVE不会阻塞服务器进程,因此允许用户设置服务器配置的save选项(可以设置多个),让服务器在满足选项条件的情况下(只需满足一条即可),每隔一段时间自动执行一次BGSAVE命令。
例如:
save 900 1
save 300 10
服务器在900秒之内,对数据库进行至少1次修改(包括写入、删除、更新等操作),则BGSAVE命令会被执行。
服务器在300秒之内,对数据库进行至少10次修改,则BGSAVE命令会被执行。
dirty计数器和lastsave属性
dirty计数器:距离上次成功执行SAVE或者BGSAVE命令之后,成功的修改次数
lastsave属性:UNIX时间戳,记录上一次服务器成功执行SAVE或者BGSAVE命令的时间
3、RDB文件结构
REDIS | db_version | databases | EOF | check_sum |
REDIS:
RDB文件最开头是REDIS部分,这部分长度为5字节,保存着‘REDIS’五个字符。在程序载入文件时,可以通过该字符检查文件是否为RDB文件。
注意:RDB文件保存的是二进制数据,不是C字符串。
db_version:4字节,字符串表示的整数,记录RDB文件的版本号。
databases:包含零个或任意多个数据库,以及数据库中的键值对数据。
databases结构:
SELECTDB | db_number | key_value_pairs |
key_value_pairs结构(不带过期时间):
TYPE | key | value |
value:保存了一个值对象,每个值对象类型由与之对应的TYPE记录,可以是:字符串对象、列表对象、哈希对象、集合对象、有序集合对象。
EOF:1字节,标志RDB文件正文结束。
check_sum:8字节长无符号整数,保持着一个校验和。
打印RDB文件:
$ od -cx dum.rdb
以ASCII编码和十进制打印RDB文件
二、AOF
AOF持久化通过保存Redis服务器所执行的写命令来记录服务器状态,即将服务器执行的SET、SADD、RPUSH等命令保存到AOF文件中。
被写入AOF文件的所有命令都是以redis的命令请求协议格式保存。
1、AOF持久化实现
命令追加、文件写入、文件同步
1)命令追加
服务器执行完一个写命令后,会以协议格式将被执行的谢明丽追加到服务器状态的aof_buf缓冲区的末尾
2)文件写入和同步
appendfsync选项:
always / eveysqc / no:
1、always:每次都写入
2、eveysqc:每次都将aof缓冲区中的所有内容写入到AOF文件,并且每隔一秒就要在子线程中对AOF文件进行一次同步。
3、交由操作系统处理。
2、AOF文件的载入和数据还原
1)创建一个不带网络连接的伪客户端
2)从AOF文件中分析并读取一条写命令
3)使用伪客户端执行被读出的写命令
4)一直执行步骤2和步骤3,直到文件中的所有写命令被处理完毕。
3、AOF重写(BGREWRITEAOF命令)
1)意义和实现
为了解决AOF文件体积膨胀问题,redis提供了AOF文件重写功能,服务器可以创建一个新的AOF文件来替代现有的AOF文件。
注意:AOF文件重写并不需要对现有的AOF文件进行任何读取、分析或者写入操作,这个功能是通过读取服务器当前的数据库状态来实现。
另外,如果集合带有多个元素的键时,会检查所包含的元素数量,如果超过了规定值,重写程序将使用多条命令来记录键的值,而不只是一条。
2)AOF后台重写
AOF重写程序调用aof_rewrite函数来完成创建一个新AOF文件的任务,因此这个函数会进行大量的写入操作,调用这个函数的线程将被长时间阻塞,所以AOF重写
程序会放到子进程执行。
在子进程执行AOF重写期间,服务器进程执行三个工作
1、执行客户端发来的命令
2、将执行后的写命令追加到AOF缓存区
3、将执行后的写命令追加到AOF重写缓冲区。
4、AOF参数
auto-aof-rewrite-min-size 64mb #AOF文件最小重写大小,只有当AOF文件大小大于该值时候才可能重写,4.0默认配置64mb。 auto-aof-rewrite-percentage 100 #当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比,如100代表当前AOF文件是上次重写的两倍时候才重写。 appendfsync everysec #no:不使用fsync方法同步,而是交给操作系统write函数去执行同步操作,在linux操作系统中大约每30秒刷一次缓冲。这种情况下,缓冲区数据同步不可控,并且在大量的写操作下,aof_buf缓冲区会堆积会越来越严重,一旦redis出现故障,数据 #always:表示每次有写操作都调用fsync方法强制内核将数据写入到aof文件。这种情况下由于每次写命令都写到了文件中, 虽然数据比较安全,但是因为每次写操作都会同步到AOF文件中,所以在性能上会有影响,同时由于频繁的IO操作,硬盘的使用寿命会降低。 #everysec:数据将使用调用操作系统write写入文件,并使用fsync每秒一次从内核刷新到磁盘。 这是折中的方案,兼顾性能和数据安全,所以redis默认推荐使用该配置。 aof-load-truncated yes #当redis突然运行崩溃时,会出现aof文件被截断的情况,Redis可以在发生这种情况时退出并加载错误,以下选项控制此行为。 #如果aof-load-truncated设置为yes,则加载截断的AOF文件,Redis服务器启动发出日志以通知用户该事件。 #如果该选项设置为no,则服务将中止并显示错误并停止启动。当该选项设置为no时,用户需要在重启之前使用“redis-check-aof”实用程序修复AOF文件在进行启动。 appendonly no #yes开启AOF,no关闭AOF appendfilename appendonly.aof #指定AOF文件名,4.0无法通过config set 设置,只能通过修改配置文件设置。 dir /etc/redis #RDB文件和AOF文件存放目录 优势:可以保证数据的一致性。因为它可以实时或者每秒记录客户端对redis的操作 缺点:aof文件比rdb文件大,恢复速度慢
三、对比
rdb持久化:故障数据丢失比aof严重,但是服务重启恢复数据快;
aof持久化:故障数据丢失较rdb少,但是服务启动时恢复数据慢,因为要把aof文件中指令执行一遍。
四、混合模式(RDB+AOF)
AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将
重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一
起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改
名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。
于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的
AOF 全量文件重放,因此重启效率大幅得到提升
本文来自博客园,作者:快牵着我的袜子,转载请注明原文链接:https://www.cnblogs.com/socks/p/16083207.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器