一、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创建快照一样,都是巧妙的利用了写时复制机制:

  1. redis调用fork ,现在有父子两个进程
  2.  子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令
  3. 父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
  4. 当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
  5. 现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。

  4、写数据流程

  1. 客户端向服务端发送写请求(数据在客户端的内存中)
  2. 数据库服务端接收到写请求的数据(数据在服务端的内存中)
  3. 服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)
  4. 操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓冲区中)
  5. 磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)

四、备份Redis数据库

  我们可以在服务器运行的时候对rdb文件进行复制:rdb文件一旦被创建,就不会进行任何修改,当服务器要创建一个新的rdb文件时,它会先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使临时文件替换原来的rdb文件。

  • 创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
  • 确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
  • 至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。

五、参考资料

  1、http://www.redis.cn/topics/persistence.html

Redis系列三之持久化的更多相关文章

  1. Redis系列(三):Redis的持久化机制(RDB、AOF)

    本篇博客是Redis系列的第3篇,主要讲解下Redis的2种持久化机制:RDB和AOF. 本系列的前2篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装. Redis系列(二): ...

  2. Redis系列(4)_持久化方式-RDB

    一.概念 在指定的时间间隔内将内存中的数据集快照写入磁盘(满足指定时间间隔和操作次数两个条件),也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里 二.配置文件(redis.con ...

  3. redis系列:RDB持久化与AOF持久化

    前言 什么是持久化? 持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘).持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中.XML数 ...

  4. Redis系列三(redis配置文件分析)

    在第一篇文章中有提到过redis.conf这个文件,这个文件就是redis-server的具体配置了.要使用好redis,一定要搞清楚redis的配置文件,这样才能最大的发挥redis的性能. # B ...

  5. Redis系列(三)--消息队列、排行榜等

    Redis命令执行生命周期: 发送命令--->排队(单线程)--->执行命令--->返回结果 慢查询: 只是针对命令执行阶段 慢查询日志通过一个固定长度的FIFO queue,这个q ...

  6. Redis系列三 - 缓存雪崩、击穿、穿透

    前言 从学校出来,做开发工作也有一定时间了,最近有想系统地进一步深入学习,但发现基础知识不够扎实,故此来回顾基础知识,进一步巩固.加深印象. 最初开始接触编程时,总是自己跌跌撞撞.不断摸索地去学习,再 ...

  7. Redis系列(三)-Redis发布订阅及客户端编程

    阅读目录 发布订阅模型 Redis中的发布订阅 客户端编程示例 0.3版本Hredis 发布订阅模型 在应用级其作用是为了减少依赖关系,通常也叫观察者模式.主要是把耦合点单独抽离出来作为第三方,隔离易 ...

  8. Redis系列三:reids常用命令

    全局命令 keys *  查看所有键 dbsize 查看的是当前所在redis数据库的键总数 如果存在大量键,线上禁止使用此指令 exists key 检查键是否存在,存在返回1,不存在返回0 del ...

  9. Redis系列三 Redis数据类型

    一 .Redis的五大数据类型 1.String(字符串) string是redis最基本的数据类型,可以理解成与 Memached一模一样的数据类型,一个key对应一个value. string 类 ...

随机推荐

  1. No resource found that matches the given name 'android:Widget.Material.A解决方案

    1:首先新建空白工作区 2:先import appcompat_v7 appcompat_v7在一个类似这样的地方, C:\mywork\android\android-sdk-windows\ext ...

  2. Java的默认编码

    摘要: 1.Java的默认编码内容: 1.Java的默认编码 java的src.zip包中的java.nio.charset.Charset类中defaultCharset()方法说明java的编码类 ...

  3. python多线程网络编程

    背景 使用过flask框架后,我对request这个全局实例非常感兴趣.它在客户端发起请求后会保存着所有的客户端数据,例如用户上传的表单或者文件等.那么在很多客户端发起请求时,服务器是怎么去区分不同的 ...

  4. js const

    js const const 声明创建一个只读的常量.这不意味着常量指向的值不可变,而是变量标识符的值只能赋值一次. const state = { notes: [], activeNote: {} ...

  5. jquerymobile仿微信 - 01

    jquerymobile仿微信 - 01 jquerymobile的组件感觉不咋地哇 本地调试最好是开一个web server,不然数据访问会有问题 <div data-role="p ...

  6. 技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)

    1.前言 作为应用层开发人员,接触最多的网络协议通常都是传输层的TCP(与之同处一层的另一个重要协议是UDP协议),但对于IP协议,对于应用程序员来说更多的印象还是IP地址这个东西,再往深一点也就很难 ...

  7. Android后台保活实践总结:即时通讯应用无法根治的“顽疾”

    前言 Android进程和Service的保活,是困扰Android开发人员的一大顽疾.因涉及到省电和内存管理策略,各厂商基于自家的理解,在自已ROOM发布于都对标准Android发行版作为或多或少的 ...

  8. KnockoutJS 3.X API 第四章 数据绑定(3) 控制流if绑定和ifnot绑定

    if绑定目的 if绑定一般是格式是data-bind=if:attribute,if后所跟属性或表达式的值应为bool值(也可以是非bool值,当非空字符串时则为真),if绑定的作用与visible绑 ...

  9. Spring(一)第一个示例

    原文链接:http://www.orlion.ga/185/ 一.下载与安装Spring 1.访问https://repo.spring.io/webapp/#/artifacts/browse/tr ...

  10. Web 前端开发精华文章集锦(jQuery、HTML5、CSS3)【系列十八】

    <Web 前端开发精华文章推荐>2013年第六期(总第十八期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HTML5 和 C ...