执行一次怎么会写入两次数据_浅谈 Redis 数据持久化之 AOF 模式

我们知道 Redis 之所以读写快、性能高,得益于它是一种基于内存的数据库,毫无疑问它的操作都几乎都是基于内存。但是内存型数据库也有一个很大的弊端:如果进程崩溃或者服务重启的时候内存数据得不到保存,就会造成数据丢失。为了解决这个问题 Redis 提供了两种持久化方式 RDB 和 AOF 。今天笔者主要和大家一起探讨 Redis 的 AOF 模式是如何运行的。

AOF 详解

AOF 是 Append Only File 的缩写,默认是关闭的。当 Redis 启动时只要开启 AOF 模式就会通过 AOF 文件恢复数据,否则将从 RDB 快照文件中恢复数据。开启 AOF 模式需要将 redis.conf 中默认的 appendonly no 改为 appendonly yes 。AOF 开启后 Redis 内部会维护一份 AOF 文件,AOF 文件可以看做是 Redis 的日志文件。Redis 服务使用其通信协议的格式将更新命令保存到 AOF 文件中,所以文件内容容易被人读懂,我们在维护时能够轻松的对文件进行分析。

403ce17946b89628705edccd3f685327.png

工作原理

Redis 内部维护了一个缓冲区 aof_buf ,Redis 服务如果发现有更新命令,这些更新命令不是被直接写入到 AOF 文件中的,而是会被先以 Redis 通信协议的格式追加到 aof_buf 中(命令追加),维护 aof_buf 缓冲区的同时会执行 appendfsync 策略(写入和同步策略)。

ec238422bf779bf906e49858da7e617e.png

持久化的过程

了解 appendfsync 策略之前我们先要搞清楚 AOF 持久化的过程,它一共有三步:

1)命令追加:更新命令追加写入到 aof_buf 中。

2)文件写入:执行 write 操作,写入到系统缓冲区。

3)文件同步:从系统缓冲区同步到磁盘中。

同步策略(appendfsync)

1)always:Redis 每次执行更新命令将 aof_buf 中内容写入并同步到 AOF 文件中。 该策略每次执行更新命令触发,每次发生数据变更就会立刻同步到到磁盘。

c065fcb08cdca515242b06b64a3cdf2d.png

always 策略

2)everysec: 将 aof_buf 缓冲区所有内容写入到 AOF 文件,如果上次同步时间距离现在超过1秒钟,那么再次对 AOF 文件进行同步,这个操作是由一个线程专门负责执行的。everysec 策略持久化性能较好,但是宕机时会造成数据丢失。

e58363b131f2760246587b5dd7104bcb.png

everysec 策略

3)no:将 aof_buf 中的内容写入到 AOF 文件中,但并不对 AOF 同步,何时同步由操作系统来决定。

84fe67747f87aea5a4651d713eb96fb6.png

no 策略

我们可以看到三种策略都是将 aof_buf 缓冲区的所有内容写入到 aof 文件,只是同步时操作不一样。在操作系统中,除非设置了自动同步,否则为了减少磁盘的写入量,延长磁盘寿命、提高文件写入效率。写入文件时并不是同步写入到磁盘中,而是先写入内存,这段内存区域被称为系统缓冲区。在系统缓冲区数据累计到一定数量后(具体数量因系统实际设置而定),会有系统进程一次性写入所有缓冲数据。因此只有等到同步执行完毕这是才是持久化完成。

always 的优点是数据安全,效率太低,因为过于频繁的调用系统;只有在这种策略下,redis的事务是满足持久化的。

no 的优点是效率较高,但是不够安全,因为 aof_buf 中的数据可能因为宕机而丢失。

ererysec 介于两者之间,在效率和安全之间达到一个平衡。这里我们又一次看到折中思想在计算机中的应用。

8b64011552b6e9133ff5906170ee3f18.png

AOF 的重写机制

AOF 文件由于不断写入,会变得越来越大。通过分析 AOF 文件,往往发现里面有太多的重复和冗余数据,重写策略就是成一个新的 AOF 文件来代替旧的 AOF 文件,这个操作在满足一定条件 Redis 会自动触发。

当 AOF 文件大小从 0 增长到指定大小时,会触发 AOF 的第一次 rewrite 操作,Redis 会 fork 出来一个进程(这样主进还可以程继续处理命令,fork出来的子进程带有主进程的数据副本,可以在避免锁的情况下,保证数据的一致性),通过 bgRewriteAOF 命令完成:基于当前数据生成新 AOF 文件。在此期间 Redis 如果收到新的更新命令,Redis 会将命令暂时保存在内存。等待新的 AOF 文件生成后,Redis 会将内存中的命令追加到新 AOF 文件中。新 AOF 完成后,Redis 会删除旧的 AOF 文件。当新的 AOF 文件扩大到2倍的时候会触发第二次 rewrite。

在重写期间,主进程继续处理命令,而新的命令有可能还会对现在有数据进行修改,这会导致当前数据库中的数据和生成的 AOF 文件不一致。Redis 维护了一个 AOF 重写缓冲区 rewrite_buf ,主进程接收到更新命令后,把命令写入到 rewrite_buf 中。这样主进程在接收到跟新命令的时候一边将命令写入 aof_buf ,(重写执行是)一边写入到 rewrite_buf 中(重写的时候会保持继续更新旧 AOF 文件)。

fork 出来的子进程完成 bgRewriteAOF 操作后,会向主进程发送信号,会执行一个信号处理函数 1)将 rewrite_buf 中的数据全量写到新的 AOF 文件中。2)重命名新 AOF 文件,覆盖旧文件。信号处理函数完成时主进程会短暂阻塞。

AOF 优势劣势有哪些呢?

a46da3804776585ca920b9b5f72afb06.png

优势

1)AOF 模式带来了更高数据安全性的数据持久化解决方案。

2)AOF 模式对日志文件的写入操作采用的是 append 模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。如果我们数据写入了一半出现了宕机现象 redis-check-aof 工具可以帮我们解决问题,感兴趣同学们可以去研究下。

3)如果日志过大,Redis 有自动启动的 rewrite 机制。即 Redis 以 append 模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行 rewrite 切换时可以更好的保证数据安全性。

4) AOF 包含一个格式清晰、易于理解的日志文件用于记录所有的更新操作。事实上,我们也可以通过该文件完成数据的重建。

劣势

1)由于 AOF 格式是 Redis 通信协议并且文件是命令 append 因此通常要大于 RDB 模式下产生的 .rdb 文件。RDB 模式产生的是数据快照文件小,海量数据集时 RDB 模式恢复速度会比 AOF 快。

2)同步策略与 RDB 模式,AOF 在运行效率上往往会慢于 RDB 。但是,everysec 同步策略的效率也是是比较高的,no 同步策略的效率和RDB一样高效。


总结:

Redis 的两种持久化机制各有优劣,AOF 模式是牺牲性能换取数据数据一致性, RDB 模式则是牺牲一致性换取更高性能。同学们选型时需要根据业务场景合理的使用。

想了解 RDB 持久化模式的同学可以关注下,下回再一起聊一聊~

点击收藏、关注不迷路,欢迎大家评论区留言讨论~

8cfa8a9f2b29230a66e1033e134ce5a1.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/575027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字化转型方法论_双中台:企业数字化转型的核心战略与方法论

当下,绝大部分企业的组织形态、经营模式基本都是垂直闭环型,即围绕一种业务或者管理,其计划、执行、检查、优化的闭环都是独立于企业生态之中。在过去的“局部竞争”、“渠道为王”、“终端为王”的时代,这种组织与经营形式很好地…

java获取cpu使用率_再一次生产 CPU 高负载排查实践

前言前几日早上打开邮箱收到一封监控报警邮件:某某 ip 服务器 CPU 负载较高,请研发尽快排查解决,发送时间正好是凌晨。其实早在去年我也处理过类似的问题,并记录下来:《一次生产 CPU 100% 排查优化实践》不过本次问题产…

《BI那点儿事》三国数据分析系列——蜀汉五虎上将与魏五子良将武力分析,绝对的经典分析...

《BI那点儿事》三国数据分析系列——蜀汉五虎上将与魏五子良将武力分析,绝对的经典分析 原文:《BI那点儿事》三国数据分析系列——蜀汉五虎上将与魏五子良将武力分析,绝对的经典分析献给广大的三国爱好者们,希望喜欢三国的朋友一起讨论&#…

java map取值_Java Set接口 Map 与枚举

Set接口概述一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素特点Set接口是无序的 Set 是继承于Collection的接口。它是一个不允许有重复元素的集合。Set可以存储null值,但是nu…

linux调用ocx插件_Wordpress file manager插件任意文件上传

白斩鸡卫兵实验室近日,Wordpress 插件file manager被爆出严重0day漏洞,本着技术研究角度,和大家分享、探讨其漏洞原因。该修复程序已在同一天发布,并且WP File Manager插件6.9版通过删除允许未经授权的文件上传访问的端点来解决当…

树莓派安装mysql5.6_Linux上安装MySQL5.6

OS & MySQL的版本号和配置:MySQL Version: 5.6.19Linux Version: Linux boston.oracle.com 2.6.18-164.el5 #1 SMP Thu Sep 3 02:16:47 EDT 2009 i686 i686 i386 GNU/Linux一。下载MySQL安装软件。请到www.oracle.com去找DATABASE DOWNLOAD。下载MySQL须要注冊一…

java获取cpu使用率_2019年阿里P8架构师的解析:最新Java性能测试、调优策略

一、性能测试Ⅰ.测试方法微基准性能测试可以精准定位到某个模块或者某个方法的性能问题,例如对比一个方法使用同步实现和非同步实现的性能差异宏基准性能测试宏基准性能测试是一个综合测试,需要考虑到测试环境、测试场景和测试目标测试环境:模…

java在线编辑器_微软开源在线代码编辑器——Monaco Editor

介绍Monaco Editor是为VS Code提供支持的代码编辑器,运行在浏览器环境中。编辑器提供代码提示,智能建议等功能。供开发人员远程更方便的编写代码。移动浏览器或移动Web框架不支持Monaco编辑器。简单的理解就是VSCode中的代码编辑器和Monaco Editor使用的…

java的核心类库_Java核心类库,集合框架

Java集合框架的由来:Java最初版本只为最常用的数据结构提供了很少的一组类:比如Vector、Stack、Hashtable、BitSet、Enumerrationr接品,其中Enumerrationr接口提供了一种用于访问任意容器中各个元素的抽象机制。这是一种很明智的选择&#xf…

js splice方法_我用JS刷LeetCode | Day 8

如有兴趣,微信搜索「九零后重庆崽儿」,我们一起学前端。删除排序数组中的重复项:说明:现阶段的解题暂未考虑复杂度问题首发地址:我用JS刷LeetCode | Day 8​www.brandhuang.comQuestion:Given an array nums and a val…

js 根据掩码位计算可用ip地址_变长子网掩码:轻松分配IP地址(下)

Hello,World.如约而至土土来更文咯[吐舌]图1首先先揭晓一下上一篇文章的答案那就是192.168.1.0/24与192.168.2.0/24不能ping通192.168.1.0/16与192.168.2.0/16能ping通图2还记得土土的提示吗?网络号相同则能够ping通那么根据/24可以看出这两个IP地址有24个网络号,即…

java break递归_【Java】递归总结

摘要:大师 L. Peter Deutsch 说过:To Iterate is Human, to Recurse, Divine.中文译为:人理解迭代,神理解递归。毋庸置疑地,递归确实是一个奇妙的思维方式。对一些简单的递归问题,我们总是惊叹于递归描述问…

[翻译] RDVTabBarController

RDVTabBarController https://github.com/robbdimitrov/RDVTabBarController 效果: Supports iPad and iPhone 支持iPad与iPhoneSupports landscape and portrait orientations 支持横竖屏切换动画Can be used inside UINavigationController 可以用在UINavigationC…

内存位置访问无效 midas.dll_java并发之内存模型

作者:killianxu来源:https://www.cnblogs.com/killianxu/p/11665903.htmljava内存模型知识导图一 并发问题及含义并发编程存在原子性、可见性、有序性问题。原子性即一系列操作要么都执行,要么都不执行。 可见性,一个线程对共享变量的修改&am…

程序一旦发觉写得不理想,那就得重构它

早上有写一篇《设计模式--建造者(Builder)模式》http://www.cnblogs.com/insus/p/4179620.html。是在ASP.NET环境中,应用与演示设计模式(Builder)。现在Insus.NET从博文中最后的下载链接下载取源程序,它是有写得不够理想,现在重构它。问题点&…

template标签_C++核心准则T.65:使用标签分发提供函数的不同实现

T.65: Use tag dispatch to provide alternative implementations of a functionT.65:使用标签分发提供函数的不同实现Reason(原因)A template defines a general interface.模板定义普遍接口。Tag dispatch allows us to select implementations based on specific properties…

Windows服务器学习篇:服务器连接与退出

此文是我早期在公司内部发布的一篇给予新入职程序员基础技术培训的文章,非常基础简单,现拿出来给大家分享。当然,已工作人士可直接忽略... 一、Windows服务器连接 1. 在桌面菜单中的“运行”里,输入mstsc命令,然后回车…

nginx动静分离配置_Nginx动静分离

动静分离动静分离,就是将JSP、Servlet等动态资源交由Tomcat或其他Web服务器处理,将CSS、js、image等静态资源交由Nginx或其他Http服务器处理,充分发挥各自的优势,减轻其他服务器的压力,搭建更为高效的系统架构。Nginx动…

java thread 名称_Thread类常用方法之设置线程名称

package com.itheima.demo02.setName;/*设置线程的名称:(了解)1.使用Thread类中的方法setName(名字)void setName(String name) 改变线程名称,使之与参数 name 相同。2.创建一个带参数的构造方法,参数传递线程的名称;调用父类的带参构造方法,把线程名称传递给父类,让…

成员变量和局部变量的区别_Java 变量类型

点击上方“蓝字”带你去看小星星今天主要学习Java变量类型,主要是局部变量、实例变量和类变量(静态变量)。Java语言中,所有的变量在使用前必须声明。声明变量的基本格式如下:type identifier [ value][, identifier [ value] ...] ;格式说明…