重写AOF

当AOF文件太大时,Redis将在临时文件重新写入新的内容。重写不会读取旧的AOF文件,而是直接访问内存中数据,以便让新产生的AOF文件最小,重写过程不需要读取磁盘。

重写完成后,Redis使用fsync系统调用将临时文件同步到磁盘,并替换原有AOF文件。

你可能想知道在重写过程中,如何处理写入服务器的数据。新的数据将会写入到旧的(当前)AOF文件,同时进入一个内存队列,当新的AOF文件完成后,将这部分遗失的内容写入新的AOF文件,并最终替换旧的AOF文件。

你可以看到,所有写入仍旧是追加形式写入,重写AOF文件时,仍旧将所有内容写入旧的AOF文件。这意味着我们不必考虑AOF文件会重写。真正的问题是,写入的频率和fsync系统调用的频率。

AOF耐用性(durability)

我很高兴已经介绍完前面的内容,也很高兴你能坚持读到这里。

Redis AOF使用执行新命令填充的用户空间buffer。每次事件循环的最后,Redis使用write系统调用将这个buffer写入(flush)到磁盘。实际上,有三个不同的配置值可以修改write尤其是fsync的行为。

这三个值通过appendfsync配置项控制,可以设置为no, everysec, always。这个配置也可以在Redis运行时通过CONFIG SET命令修改,因此可以不必停止Redis运行即可修改。

appendfsync no

appendfsync配置为no时,Redis不会调用fsync。然而,它要保证客户端没有使用pipelining。也就是说,等待收到响应后发送后续命令的客户端将收到命令的响应,表明命令已经在Redis正确执行,相关修改已经通过以调用write系统调用将命令写入AOF文件描述符的方式传递给内核。

由于这个配置不会调用fsync。数据将完全由内核控制写入磁盘。对于Linux系统来说,每30秒写入一次。

appendfsync everysec

Redis使用这个配置调用write将数据写入文件,每秒调用一次fsync将数据从内核同步到磁盘。通常,每次事件循环结束时执行写入,但这个机制并不完全可信(not guaranteed)。

如果磁盘不能提供背景fsync调用的带宽需求,那么随后的fsync调用可能被延迟(以避免阻塞主线程)。如果两秒钟内fysnc仍旧没有完成,Redis最终会调用write将数据同步到磁盘。

appendfsync always

如果客户端没有使用pipelining,而是等待前一个命令的响应,那么Redis不仅将数据写入文件并使用fsync将数据同步到磁盘,完成后将命令执行结果返回给客户端。

这是现在Redis可能取得的最高级别的耐用性,但也是最慢的一个。

Redis默认的配置是appendfsync everysec,是考虑速度和耐用性的折中方案。

pipelining的不同之处

以不同方式处理使用pipelining的客户端的原因是为了提升效率,它执行下一条命令前,牺牲了读取某一命令结果的能力。这对响应不感兴趣只要求速度的客户端来说,返回响应前提交数据毫无意义。但对使用pipelining的客户端,Redis返回事件循环时总会有write和fsync调用。

AOF与Redis事务

AOF可以保证正确执行MULTI/EXEC事务,不会导入在文件末尾包含不完整事务的AOF文件,Redis提供工具删除AOF文件末尾不完整事务。

对比PostrgreSQL

以AOF默认配置作为持久化引擎时,Redis的耐用性如何呢?

最坏场景:保证write和sync在两秒钟内完成

正常场景:响应客户端前执行write, 每秒钟执行一次fsync.

这时Redis仍旧很快,一个原因是fsync在背景线程执行,另外一个原因是Redis只以追加模式写入文件,这是一个大的优势。

如果需要最大的数据安全性且写入量不大时,可以使用fsync always获取所有数据库可能得到的最强数据耐用性。

和PostgreSQL比如何呢?它是一个非常可靠的优秀数据库。

引用一下PostgreSQL文档:

fsync(布尔值)

当这个参数为on时,PostgreSQL将使用fsync或其等效方法尽力保证更新写入到物理磁盘。这保证在操作系统或者硬件崩溃后,数据库集群可以将数据恢复到一致状态。

所以PostgreSQL需要使用fsync保证不损坏数据。幸运的是,Redis不存在这种问题,不可能有数据损坏发生。

对于PostgreSQL来说,如果需要提升速度那么去使能同步提交。同样对redis来说,提升速度就不能配置appendfsync always。

在PostgreSQL中,去使能同步提交类似于Redis中的appendsync everysec. 写入物理磁盘的延迟延迟约为600毫秒,而Redis默认是1秒。

MySQL InnoDB有同样的配置参数 -innodb_flush_log_at_trx_commit。

长话短说,Redis虽然是内存数据库,但它和其他构建在磁盘基础上的数据库一样提供良好的耐用性。

实际上,Redis提供AOF和RDB快照,并可以同时使用(这也是建议配置),提供易用性和数据耐用性。

现在为止所有讨论的关于Redis耐用性的内容不仅可以适用于把Redis作为数据存储的场景,也适用于将Redis作为队列并可将数据持久化到磁盘保证良好耐用性的场景。


Redis persistence demystified - part 2的更多相关文章

  1. Redis persistence demystified

    https://redis.io/topics/persistence http://oldblog.antirez.com/post/redis-persistence-demystified.ht ...

  2. Redis persistence demystified - part 1

    关于Redis我的一部分工作是阅读博客,论坛以及twitter时间线(time line).对于开发者来说,能够了解用户社区,非用户社区如果理解他正在开发的产品是非常重要的.据我所知,持久化特性是最易 ...

  3. redis 持久化与备份策略 【转载】

    本文转载自 http://blog.csdn.net/is_zhoufeng/article/details/10210353 持久化(persistence) 本文是 Redis 持久化文档 的中文 ...

  4. redis 持久化与备份策略

    持久化(persistence) 本文是 Redis 持久化文档 的中文翻译. 这篇文章提供了 Redis 持久化的技术性描述,推荐所有 Redis 用户阅读. 要更广泛地了解 Redis 持久化,以 ...

  5. Redis 持久化深入--机制、可靠性及比较

    本文是对 antirez 博客中 Redis persistence demystified 的翻译和总结.主要从Redis的持久化机制,提供何种程度的可靠性以及与其他数据库的比较三个方面进行讨论. ...

  6. 详解redis持久化

    我们的Redis必须使用数据持久化吗?如果我们的Redis服务器只作为缓存使用,Redis中存储的所有数据都是从其他地方同步过来的备份,那么就没必要开启数据持久化的选项.Redis提供了将数据定期自动 ...

  7. Redis(7)——持久化【一文了解】

    一.持久化简介 Redis 的数据 全部存储 在 内存 中,如果 突然宕机,数据就会全部丢失,因此必须有一套机制来保证 Redis 的数据不会因为故障而丢失,这种机制就是 Redis 的 持久化机制, ...

  8. 转载:解密Redis持久化

    本文内容来源于Redis作者博文,Redis作者说,他看到的所有针对Redis的讨论中,对Redis持久化的误解是最大的,于是他写了一篇长文来对Redis的持久化进行了系统性的论述.文章非常长,也很值 ...

  9. 【Redis】Redis 持久化之 RDB 与 AOF 详解

    一.Redis 持久化 我们知道Redis的数据是全部存储在内存中的,如果机器突然GG,那么数据就会全部丢失,因此需要有持久化机制来保证数据不会一位宕机而丢失.Redis 为我们提供了两种持久化方案, ...

随机推荐

  1. iOS - OC SQLite 数据库存储

    前言 采用 SQLite 数据库来存储数据.SQLite 作为一中小型数据库,应用 iOS 中,跟前三种保存方式相比,相对比较复杂一些. 注意:写入数据库,字符串可以采用 char 方式,而从数据库中 ...

  2. 从POI到O2O 看百度地图如何走出未来之路

    近期O2O的烧钱融资大战如火如荼,有人已经把O2O大战,用乌合之众的群体心理失控来形容.其实厂商都不傻,O2O烧钱大家都知道,但是大家还知道O2O背后这块大蛋糕价值"万亿级". 有 ...

  3. 批量创建客户主数据函数SD_CUSTOMER_MAINTAIN_ALL

    分享一下批创建客户主数据函数:SD_CUSTOMER_MAINTAIN_ALL TABLES:T077D,ZCITY,T005S,BNKA,ADRC,KNA1.  DATA: TMP_KTOKD(4) ...

  4. [转]ubuntu下安装程序的三种方法

    出处:http://www.cnblogs.com/xwdreamer/p/3623454.html 引言 在ubuntu当中,安装应用程序我所知道的有三种方法,分别是apt-get,dpkg安装de ...

  5. js求和算法研究

    如果遇到一个试题是这样. function sum(arr){ //求和 } 你会怎么做? 反正我第一反应是这样做. function sum(arr){ var result = 0; for(va ...

  6. android电池管理系统从上层的java到底层驱动的调用(转载)

    1.概述 随着移动智能设备的快速发屏,电池的续航能力在很大情况下诱导了大众消费者的购买选择,android系统对电源管理的合理与否直接影响到电池的续航能力,而电池系统作为其中的一部分,主要用于对电池状 ...

  7. GCC编译器和GDB调试器常用选项

    http://blog.csdn.net/u014328976/article/details/46745349 GCC编译器 gcc hello.c -o hello                 ...

  8. js-------》(小效果)实现倒计时及时间对象

    js实现倒计时及时间对象 JS实现倒计时效果代码如下: 1 <!doctype html> 2 <html> 3 <head> 4 <meta charset ...

  9. hibernate的离线关联(多级)查询

    如果实体对象中没有关联对象的情况使用DetachedCriteria进行查询是一件很简单的事情. 假设要通过stuName查询一个学生Student记录,可以如下: Java代码 DetachedCr ...

  10. hdu4418(概率dp + 高斯消元)

    应该是一个入门级别的题目. 但是有几个坑点. 1. 只选择x能到达的点作为guass中的未知数. 2. m可能大于n,所以在构建方程组时未知数的系数不能直接等于,要+= 3.题意貌似说的有问题,D为- ...