一、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. http学习笔记(三)

    几乎所有的http通信都是由TCP/IP承载的.http好比一辆汽车,而TCP是一条公路,所有的汽车都要在公路上跑,看看http是如何在tcp这条公路上往返的. 首先简单地看看tcp,TCP连接是通过 ...

  2. Spring-Context之四:Spring容器及bean的定义

    Spring框架的核心功能之一就是控制反转(Inversion of Control, IoC),也叫做依赖注入(dependency injection, DI).关于依赖注入的具体内容可以参见Ma ...

  3. 如何成为一个Xamarin专家

    近期,我们发布了 Xamarin studio 6,这个版本充满了美妙的新特性,能够更有效的帮助我们的开发工作.由于其深层次的 IDE 比较复杂,同时我们也很难去发现并记得那些对我们最有帮助的特性,所 ...

  4. Jsp+ Servlet+Ajax实现点赞功能

    1.jsp页面,使用ajax实现局部刷新 2.servlet接受处理去更新数据库 随后上传

  5. Redis数据库的使用场景介绍(避免误用Redis)

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/122.html?1455854235 Redis 是目前 NoSQL 领域 ...

  6. WebApi系列~实际项目中如何使用HttpClient向web api发异步Get和Post请求并且参数于具体实体类型

    回到目录 本讲比较实际,在WEB端有一个Index和Create方法,用来从web api显示实体列表数据和向api插入实体对象,这就是以往的网站,只不过是把数据持久化过程放到了web pai上面,它 ...

  7. js笔记——理解js中的call及apply

    call及apply在js里经常碰得到,但一直感觉很陌生,不能熟练使用.怎样才能熟练应用呢? 为什么存在call和apply? 在javascript OOP中,我们经常会这样定义: function ...

  8. DOM (Document Object Model)文档对象模型

    [理解下DOM] DOM——Document Object Mode.DOM是网页上XHTML中文档正文标题啊.段落.列表.样式.以及ID/class等所有其他数据的一个内部表示.我自己的理解是将网页 ...

  9. Mysql 事件(定时任务)

    mysql 创建任务(事件) 1.检查数据库事件是否开启,如果 event_scheduler 等于 NO表示开启 SELECT @@event_scheduler; SHOW VARIABLES L ...

  10. JTMz换路径导致MySQL服务不能启动的问题

    问题: JTMz解压到我的机器上,运行一次后,把服务停止了,然后移到了另外一个路径,JTMz中自带的MySQL服务启动不起来了. 解决: 在注册表中修改 HKEY_LOCAL_MACHINE\SYST ...