Redis系列三之持久化
一、Redis持久化
Redis是一个支持持久化的内存数据库,redis需要经常将内存中的数据同步到磁盘来保证持久化。
redis提供了不同级别的持久化方法:
- Snapshotting(快照,默认方式):能够在指定的时间间隔对你的操作进程快照存储
- Append-only file(缩写aof):记录每次对服务器写的操作,当服务器重启时会重新执行这些命令来恢复原始的数据
- 如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式
- 你也可以同时开启两种持久化方法,这种情况下,当redis重启的时候会优先载入aof原件来恢复原始数据,因为通常情况下,aof文件保存的数据集要比rdb文件保存的数据集要完整
二、快照方式(snapshotting)
默认情况下,Redis将数据库快照保存在一个dump.rdb的二进制文件中。
1、配置方式
可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果超过m个key被修改就自动做快照,下面是默认的快照保存配置:
save 900 1 //900秒内如果超过1个key被修改,则发起快照保存
save 300 10 //300秒内容如超过10个key被修改,则发起快照保存
save 60 10000
2、工作原理
当Redis需要保存dump.rdb文件时,服务器执行以下操作:
Redis调用forks,同时拥有父进程和子进程
子进程将数据集写入到一个临时rdb文件中
当子进程完成对新rdb文件的写入时,redis用新rdb文件替换原来的rdb文件,并删除旧的rdb文件
client也可以使用save或者bgsave命令通知redis做一次快照持久化。save操作是在主线程中保存快照的,由于redis是一个主线程来处理所有client的请求,这种方式会阻塞所有client请求。
Redis启动后读取RDB快照文件,将数据从硬盘载入到内存。
通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据,这就需要开发者通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。
三、只追加操作的文件(Append-only file AOF)
快照功能并不是非常耐久,如果redis因为某些原因而造成故障停机那么服务器将丢失最近写入、且仍未保存到快照的那些数据。从1.1版本开始,redis增加了一种完全耐久的持久化方式:AOF持久化。
1、配置方式
aof比快照方式有更好的持久化性。在使用aof方式时,redis会将每一个收到的写命令都通过write函数追加到文件(默认是appendonly.aof)中。当redis重启时会通过重新执行文件中的保存的写命令来在内存中重建整个数据库的内容。
由于操作系统会在内核中缓存write做的修改,所以可能不是立即写到磁盘上,这样aof方式的持久化也还是有可能会丢失部分修改。我们可以通过配置文件告诉redis我们想要通过fsync函数强制操作系统写入到磁盘的时机,有三种方式如下(默认:每秒fsync一次):
appendonly yes #启用aof持久化方式
# appendfsync always #每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# appendfsync no #完全依赖os,性能最好,持久化没保证
选项分析:
1、appendfsync no
当设置appendfsync为no时,Redis不会主动调用fsync去将aof日志同步到磁盘,完全依赖于操作系统
2、appendfsync everysec
当设置为appendfsync为everysec的时候,Redis会默认每隔一秒进行一次fsync调用,将缓冲区中的数据写到磁盘。
3、appendfsync always
当设置appendfsync为always时,每一次写操作都会调用一次fsync,这时数据是最安全的,当然,由于每次都会执行fsync,所以其性能也会受到影响。
在配置文件redis.windows.conf中设置appendonly yes 后,打开redis服务器,立即会生成一个append-only.aof空文件。然后在客户端中,输入下面的命令
再查看append-only.aof文件,内容为:
2、日志重写
因为aof的运作方式是不断的将命令追加到文件的结尾,所以随着写入命令的不断增加,aof文件的体积也会变得越来越大。redis支持一种特性:可以在不打断客户端的情况下,对aof文件进行重建(rebuild),执行bgrewriteaof命令,redis将生成一个新的aof文件,这个文件将包含重建当前数据集所需的最少命令。
3、工作原理
AOF重写和rdb创建快照一样,都是巧妙的利用了写时复制机制:
- redis调用fork ,现在有父子两个进程
- 子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
- 父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
- 当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
- 现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。
4、写数据流程
- 客户端向服务端发送写请求(数据在客户端的内存中)
- 数据库服务端接收到写请求的数据(数据在服务端的内存中)
- 服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)
- 操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓冲区中)
- 磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)
四、备份Redis数据库
我们可以在服务器运行的时候对rdb文件进行复制:rdb文件一旦被创建,就不会进行任何修改,当服务器要创建一个新的rdb文件时,它会先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使临时文件替换原来的rdb文件。
- 创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
- 确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
- 至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。
五、参考资料
1、http://www.redis.cn/topics/persistence.html
Redis系列三之持久化的更多相关文章
- Redis系列(三):Redis的持久化机制(RDB、AOF)
本篇博客是Redis系列的第3篇,主要讲解下Redis的2种持久化机制:RDB和AOF. 本系列的前2篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装. Redis系列(二): ...
- Redis系列(4)_持久化方式-RDB
一.概念 在指定的时间间隔内将内存中的数据集快照写入磁盘(满足指定时间间隔和操作次数两个条件),也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里 二.配置文件(redis.con ...
- redis系列:RDB持久化与AOF持久化
前言 什么是持久化? 持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中.XML数 ...
- Redis系列三(redis配置文件分析)
在第一篇文章中有提到过redis.conf这个文件,这个文件就是redis-server的具体配置了.要使用好redis,一定要搞清楚redis的配置文件,这样才能最大的发挥redis的性能. # B ...
- Redis系列(三)--消息队列、排行榜等
Redis命令执行生命周期: 发送命令--->排队(单线程)--->执行命令--->返回结果 慢查询: 只是针对命令执行阶段 慢查询日志通过一个固定长度的FIFO queue,这个q ...
- Redis系列三 - 缓存雪崩、击穿、穿透
前言 从学校出来,做开发工作也有一定时间了,最近有想系统地进一步深入学习,但发现基础知识不够扎实,故此来回顾基础知识,进一步巩固.加深印象. 最初开始接触编程时,总是自己跌跌撞撞.不断摸索地去学习,再 ...
- Redis系列(三)-Redis发布订阅及客户端编程
阅读目录 发布订阅模型 Redis中的发布订阅 客户端编程示例 0.3版本Hredis 发布订阅模型 在应用级其作用是为了减少依赖关系,通常也叫观察者模式.主要是把耦合点单独抽离出来作为第三方,隔离易 ...
- Redis系列三:reids常用命令
全局命令 keys * 查看所有键 dbsize 查看的是当前所在redis数据库的键总数 如果存在大量键,线上禁止使用此指令 exists key 检查键是否存在,存在返回1,不存在返回0 del ...
- Redis系列三 Redis数据类型
一 .Redis的五大数据类型 1.String(字符串) string是redis最基本的数据类型,可以理解成与 Memached一模一样的数据类型,一个key对应一个value. string 类 ...
随机推荐
- 为什么一定要杀掉病毒?---帮一位老师解决MyDocument.exe优盘文件夹图标病毒问题
最近一位大学老师给我抱怨了一个她遇到的烦恼,一直在纠结,生活都被打乱了,事情大概是这样的: 她的优盘里辛辛苦苦弄好备课文件,放在了优盘里,可是每次上课时,就是找不到文件.有时好多文件都被修改了,非常烦 ...
- 简化工作流程,10款必备的HTML5开发工具
利用HTML5工具不仅可以帮助设计师和开发者创建更具吸引力的网站,还能增加网站的可用性和可访问性.本文收集了10款HTML5开发工具让你在网页中搭建特效.动画.视频.音频等诸多功能,为你节省更多开发时 ...
- Java程序员的日常 —— 多进程开发IO阻塞问题
本篇仍旧是源于最近的工作,总结一下纪念那些年埋下的坑... 背景故事 需求:"使用进程方式启动另一个程序!" 开发:"OK! Runtime.getRuntime().e ...
- iOS-SDWebImage
我之前写过一篇博客,介绍缓存处理的三种方式,其中最难,最麻烦,最占内存资源的还是图片缓存,最近做的项目有大量的图片处理,还是采用了SDWebImage来处理,但是发现之前封装好的代码报错了.研究发现, ...
- Tomcat源码解读系列(一)——server.xml文件的配置
Tomcat是J2EE开发人员最常用到的开发工具,在Java Web应用的调试开发和实际部署中,我们都可以看到Tomcat的影子.大多数时候,我们可以将Tomcat当做一个黑盒来看待,只需要将编写的J ...
- vue-cli需要的包
vue-cli需要的包 npm install webpack webpack-dev-server --save-dev npm install vue-loader vue-html-loader ...
- 为什么说基于TCP的移动端IM仍然需要心跳保活?
1.前言 很多人认为,TCP协议自身先天就有KeepAlive机制,为何基于它的通讯链接,仍然需要在应用层实现额外的心跳保活?本文将从移动端IM实践的角度告诉你,即使使用的是TCP协议,应用层的心跳保 ...
- 正则表达式之JSP、Android
对于正则表达式,很多朋友一定不陌生,因为在我们做网站或apk时,当需要用户提交表单时,很多时间需要判断用户的输入是否合法,这个时间正则表达式就可以发挥它的作用了,我们知道正则表达式在这个方面是很强大的 ...
- Dijkstra算法(二)之 C++详解
本章是迪杰斯特拉算法的C++实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnbl ...
- [Qt5] How to connect c++ with QML
Qt5处于过度阶段,架构繁琐,学习成本不低.尤其是UI代码竟然被重写,变了天. Qt中的c++可能是连接OPENCV与QML的一个不错的桥梁,在此学习这部分实用的技术. Reference: http ...