Redis 的读写都是在内存中进行的,所以它的性能高。而当我们的服务器断开或者重启的时候,数据就会消失,那么我们该怎么解决这个问题呢?
我们提供的服务有:网站建设、网站设计、微信公众号开发、网站优化、网站认证、德州ssl等。为数千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的德州网站制作公司
其实 Redis 已经为我们提供了一种持久化的机制,分别是 RDB 和 AOF 两种方式,接下来跟着我一起看看这两个锦囊都是怎么保证数据的持久化的。
由于 Redis 是基于内存的数据库,所以当服务器出现故障的时候,我们的数据就得不到安全保障。
这个时候就需要将内存中的数据存储到磁盘中,当我们服务器重启时,便可以通过磁盘来恢复数据,这个过程就叫做 Redis 持久化。
Redis持久化
RDB全称Redis Database Backup file(Redis数据备份文件),也可以称为Redis数据快照。
当 Redis 持久化时,程序会将当前内存中的数据库状态保存到磁盘中。
创建
创建 RDB 文件主要有两个 Redis 命令:SAVE 和 BGSAVE。
同步操作,执行命令时,会阻塞 Redis 服务器进程,拒绝客户端发送的命令请求。
代码示例:
- def SAVE():
- # 创建 RDB 文件
- rdbSave()
图示:
Save命令
异步操作,执行命令时,子进程执行保存工作,服务器还可以继续让主线程处理客户端发送的命令请求。
代码示例:
- def BGSAVE():
- # 创建子进程
- pid = fork()
- if pid == 0:
- # 子进程负责创建 RDB 文件
- rdbSave()
- # 完成之后向父进程发送信号
- signal_parent()
- elif pid > 0:
- # 父进程继续处理命令请求,并通过轮训等待子进程的信号
- handle_request_and_wait_signal()
- else:
- handle_fork_error()
图示:
bgSave命令
载入工作在服务器启动时自动执行。
载入
服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。
Redis 允许用户通过设置服务器配置的 save 选项,让服务器每隔一段时间自动执行一次 BGSAVE 命令。
提供配置如下:
- save 900 1
- save 300 10
在这种情况下,只要满足以下条件中的一个,BGSAVE 命令就会被执行:
服务器程序会根据 save 选项所设置的保存条件,设置服务器状态 redisServer 结构的 saveparams 属性。
- struct saveparam {
- // 秒数
- time_t seconds;
- // 修改数
- int changes;
- }
dirty 计数器记录距离上一次成功执行 SAVE 命令或 BGSAVE 命令之后,服务器对数据库状态进行了多少次修改(包括写入、删除、更新等操作)。
是一个 UNINX 时间戳,记录了服务器上一次成功执行 SAVE 命令或者 BGSAVE 命令的时间。
服务器周期性操作函数 serverCron (该函数对正在运行的服务器进行维护)默认每隔 100 毫秒就会执行一次,其中一项工作就是检查 save 选项所设置的保存条件是否已经满足,满足的话就执行 BGSAVE 命令。
代码示例:
- def serverCron():
- # ....
- # 遍历所有保存条件
- for saveparam in server.saveparams:
- # 计算距离上次执行保存操作有多少秒
- save_interval = unixtime_now() - server.lastsave
- # 如果数据库状态的修改次数超过条件所设置的次数
- # 如果距离上次保存的时间超过条件所设置的时间
- if server.dirty >= saveparam.changes and save_interval > saveparam.seconds:
- BGSAVE()
RDB 文件默认的配置如下:
- ################################ SNAPSHOTTING ################################
- #
- # Save the DB on disk:
- #在给定的秒数和给定的对数据库的写操作数下,自动持久化操作。
- # save
- #
- save 900 1
- save 300 10
- save 60 10000
- #bgsave发生错误时是否停止写入,一般为yes
- stop-writes-on-bgsave-error yes
- #持久化时是否使用LZF压缩字符串对象?
- rdbcompression yes
- #是否对rdb文件进行校验和检验,通常为yes
- rdbchecksum yes
- # RDB持久化文件名
- dbfilename dump.rdb
- #持久化文件存储目录
- dir ./
AOF全称为 Append Only File(追加日志文件)。日志是写后日志,Redis 是先执行命令,把数据写入内存,然后才记录日志。
写后日志
AOF 持久化流程实现主要是通过以下流程来实现的:
AOF流程
若 AOF 持久化功能处于打开状态,服务器在执行完一个命令后,会以协议格式将被执行的写命令追加到服务器状态的 aof_buf 缓冲区的末尾。
服务器每次结束一个事件循环之前,都会调用 flushAppendOnlyFile 函数,这个函数会考虑是否需要将 aof_buf 缓冲区中的内容写入和保存到 AOF 文件里。
flushAppendOnlyFile 函数执行以下流程:
这个函数是由服务器配置的 appendfsync 的三个值:always、everysec、no来影响的,也被称为三种策略。
每条命令都会 fsync 到硬盘中,这样 redis 的写入数据就不会丢失。
Always
每秒都会刷新缓冲区到硬盘中(默认值)。
everysec
根据当前操作系统的规则决定什么时候刷新到硬盘中,不需要我们来考虑。
no
为何需要文件重写:
文件重写的实现原理:
为不阻塞父进程,Redis 将 AOF 重写程序放到子进程里执行。
在子进程执行 AOF 重写期间,服务器进程需要执行三个流程:
服务器流程
AOF 文件默认的配置如下:
- ############################## APPEND ONLY MODE ###############################
- #开启AOF持久化方式
- appendonly no
- #AOF持久化文件名
- appendfilename "appendonly.aof"
- #每秒把缓冲区的数据fsync到磁盘
- appendfsync everysec
- # appendfsync no
- #是否在执行重写时不同步数据到AOF文件
- no-appendfsync-on-rewrite no
- # 触发AOF文件执行重写的增长率
- auto-aof-rewrite-percentage 100
- #触发AOF文件执行重写的最小size
- auto-aof-rewrite-min-size 64mb
- #redis在恢复时,会忽略最后一条可能存在问题的指令
- aof-load-truncated yes
- #是否打开混合开关
- aof-use-rdb-preamble yes
通过以上的简介,想必大家都对 Redis 持久化有了大致的了解,那么这两种方式,我们该如何选择呢?
也可以参照下图进行选择:
主要对比
本文转载自微信公众号「浅羽的IT小屋」,可以通过以下二维码关注。转载本文请联系浅羽的IT小屋公众号。
网站栏目:Redis持久化锦囊在手,再也不会担心数据丢失了
路径分享:http://www.csdahua.cn/qtweb/news15/306365.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网