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 类 ...
随机推荐
- [ACM_几何] Wall
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28417#problem/E 题目大意:依次给n个点围成的一个城堡,在周围建围墙,要求围墙 ...
- 【译】用jQuery 处理XML--浏览器中的XML与JavaScript
用jQuery 处理XML--写在前面的话 用jQuery 处理XML-- DOM(文本对象模型)简介 用jQuery 处理XML--浏览器中的XML与JavaScript 用jQuery 处理XML ...
- Andrew Ng机器学习公开课笔记 -- Regularization and Model Selection
网易公开课,第10,11课 notes,http://cs229.stanford.edu/notes/cs229-notes5.pdf Model Selection 首先需要解决的问题是,模型 ...
- JS操作页面
DOM操作 1 windows对象操作 属性(值或者子对象): opener:打开当前窗口的源窗口,如果当前窗口是首次启动浏览器打开的,则opener是null.可以利用这属性来关闭源窗口 方法(函数 ...
- jqGrid实现当前页列合计与总计
当前页列合计 js代码如下: ... footerrow: true, gridComplete: function () { var rowNum = parseInt($(this).g ...
- 为什么很多网站的表单提交按钮都是用<a>标签
之 前看过一些文章,说是用a标签来代替submit按钮更好一些,因为submit按钮在IE6下会有一些兼容的问题,不好统一,而且input的行高在各 浏览器参差不齐,还不能用line-height控制 ...
- 【总结】探索Newlife组件:服务代理利器XAgent的前世今生
本博客所有文章分类的总目录:http://www.cnblogs.com/asxinyu/p/4288836.html Newlife XCode组件相关文章目录:http://www.cn ...
- 基于PHP实现阿里云开放存储服务
开放存储服务(OpenStorageService,简称OSS),是阿里云对外提供的海量,安全,低成本,高可靠的云存储服务.用户可以通过简单的API(REST方式的接口),在任何时间.任何地点.任何互 ...
- Android基于mAppWidget实现手绘地图(四)--如何附加javadoc
如何把javadoc添加到代码库中? How to attach javadoc to the library? 项目属性——>Java Build Path——>Libraries.选择 ...
- [Node.js] DSL in action
原文地址:http://www.moye.me/2015/05/30/dsl-in-action/ 最近看了本有意思的书,受到了一些启发,在此记录一下: DSLs in action DSL是什么 ...