众所周知,redis是内存数据库,它把数据存储在内存中,这样在加快读取速度的同时也对数据安全性产生了新的问题,即当redis所在服务器发生宕机后,redis数据库里的所有数据将会全部丢失。

为了解决这个问题,redis提供了持久化功能——RDB和AOF。通俗的讲就是将内存中的数据写入硬盘中。

一、持久化之全量写入:RDB

[redis@]$ more /usr/local/redis/conf/redis.conf
save
save
save
dbfilename "dump.rdb" #持久化文件名称
dir "/data/dbs/redis/6381" #持久化数据文件存放的路径

上面是redis配置文件里默认的RDB持久化设置,前三行都是对触发RDB的一个条件,例如第一行的意思是每900秒钟里redis数据库有一条数据被修改则触发RDB,依次类推;只要有一条满足就会调用BGSAVE进行RDB持久化。第四行dbfilename指定了把内存里的数据库写入本地文件的名称,该文件是进行压缩后的二进制文件,通过该文件可以把数据库还原到生成该文件时数据库的状态。第五行dir指定了RDB文件存放的目录。

配置文件修改需要重启redis服务,我们还可以在命令行里进行配置,即时生效,服务器重启后需重新配置

[redis@iZ254r8s3m6Z redis]$ bin/redis-cli
127.0.0.1:> CONFIG GET save #查看redis持久化配置
) "save"
) "900 1 300 10 60 10000" 127.0.0.1:> CONFIG SET save "21600 1000" #修改redis持久化配置
OK

而RDB持久化也分两种:SAVE和BGSAVE

SAVE是阻塞式的RDB持久化,当执行这个命令时redis的主进程把内存里的数据库状态写入到RDB文件(即上面的dump.rdb)中,直到该文件创建完毕的这段时间内redis将不能处理任何命令请求。

BGSAVE属于非阻塞式的持久化,它会创建一个子进程专门去把内存中的数据库状态写入RDB文件里,同时主进程还可以处理来自客户端的命令请求。但子进程基本是复制的父进程,这等于两个相同大小的redis进程在系统上运行,会造成内存使用率的大幅增加。

(本人在生产中就碰到过这问题,redis本身内存使用率就60%,总的内存使用率在百分之七八十左右,持久化的时候立马飙到百分之一百三十多,告警邮件是每天几十封/(ㄒoㄒ)/~~ 最后根据需求选择了AOF持久化)

二、持久化之增量写入:AOF

与RDB的保存整个redis数据库状态不同,AOF是通过保存对redis服务端的写命令(如set、sadd、rpush)来记录数据库状态的,即保存你对redis数据库的写操作,以下就是AOF文件的内容

 [redis@iZ]$ more appendonly.aof
*
$
SELECT
$ *
$
SET
$
DEV_USER_LEGAL_F9683BE0E27F1A06C0CB869CEC7E3B22
$
¬
*
$
SET
$

先让我们看看如何配置AOF

 [redis@iZ]$ more ~/redis/conf/redis.conf
dir "/data/dbs/redis/6381" #AOF文件存放目录
appendonly yes #开启AOF持久化,默认关闭
appendfilename "appendonly.aof" #AOF文件名称(默认)
appendfsync no #AOF持久化策略
auto-aof-rewrite-percentage #触发AOF文件重写的条件(默认)
auto-aof-rewrite-min-size 64mb #触发AOF文件重写的条件(默认)

要弄明白上面几个配置就得从AOF的实现去理解,AOF的持久化是通过命令追加、文件写入和文件同步三个步骤实现的。当reids开启AOF后,服务端每执行一次写操作(如set、sadd、rpush)就会把该条命令追加到一个单独的AOF缓冲区的末尾,这就是命令追加;然后把AOF缓冲区的内容写入AOF文件里。看上去第二步就已经完成AOF持久化了那第三步是干什么的呢?这就需要从系统的文件写入机制说起:一般我们现在所使用的操作系统,为了提高文件的写入效率,都会有一个写入策略,即当你往硬盘写入数据时,操作系统不是实时的将数据写入硬盘,而是先把数据暂时的保存在一个内存缓冲区里,等到这个内存缓冲区的空间被填满或者是超过了设定的时限后才会真正的把缓冲区内的数据写入硬盘中。也就是说当redis进行到第二步文件写入的时候,从用户的角度看是已经把AOF缓冲区里的数据写入到AOF文件了,但对系统而言只不过是把AOF缓冲区的内容放到了另一个内存缓冲区里而已,之后redis还需要进行文件同步把该内存缓冲区里的数据真正写入硬盘上才算是完成了一次持久化。而何时进行文件同步则是根据配置的appendfsync来进行:

appendfsync有三个选项:always、everysec和no:

1、选择always的时候服务器会在每执行一个事件就把AOF缓冲区的内容强制性的写入硬盘上的AOF文件里,可以看成你每执行一个redis写入命令就往AOF文件里记录这条命令,这保证了数据持久化的完整性,但效率是最慢的,却也是最安全的;

2、配置成everysec的话服务端每执行一次写操作(如set、sadd、rpush)也会把该条命令追加到一个单独的AOF缓冲区的末尾,并将AOF缓冲区写入AOF文件,然后每隔一秒才会进行一次文件同步把内存缓冲区里的AOF缓存数据真正写入AOF文件里,这个模式兼顾了效率的同时也保证了数据的完整性,即使在服务器宕机也只会丢失一秒内对redis数据库做的修改;

3、将appendfsync配置成no则意味redis数据库里的数据就算丢失你也可以接受,它也会把每条写命令追加到AOF缓冲区的末尾,然后写入文件,但什么时候进行文件同步真正把数据写入AOF文件里则由系统自身决定,即当内存缓冲区的空间被填满或者是超过了设定的时限后系统自动同步。这种模式下效率是最快的,但对数据来说也是最不安全的,如果redis里的数据都是从后台数据库如mysql中取出来的,属于随时可以找回或者不重要的数据,那么可以考虑设置成这种模式。

相比RDB每次持久化都会内存翻倍,AOF持久化除了在第一次启用时会新开一个子进程创建AOF文件会大幅度消耗内存外,之后的每次持久化对内存使用都很小。但AOF也有一个不可忽视的问题:AOF文件过大。你对redis数据库的每一次写操作都会让AOF文件里增加一条数据,久而久之这个文件会形成一个庞然大物。还好的是redis提出了AOF重写的机制,即我们上面配置的auto-aof-rewrite-percentage和auto-aof-rewrite-min-size。AOF重写机制这里暂不细述,之后本人会另开博文对此解释,有兴趣的同学可以看看。我们只要知道AOF重写既是重新创建一个精简化的AOF文件,里面去掉了多余的冗余命令,并对原AOF文件进行覆盖。这保证了AOF文件大小处于让人可以接受的地步。而上面的auto-aof-rewrite-percentage和auto-aof-rewrite-min-size配置触发AOF重写的条件。

Redis 会记录上次重写后AOF文件的文件大小,而当前AOF文件大小跟上次重写后AOF文件大小的百分比超过auto-aof-rewrite-percentage设置的值,同时当前AOF文件大小也超过auto-aof-rewrite-min-size设置的最小值,则会触发AOF文件重写。以上面的配置为例,当现在的AOF文件大于64mb同时也大于上次重写AOF后的文件大小,则该文件就会被AOF重写。

最后需要注意的是,如果redis开启了AOF持久化功能,那么当redis服务重启时会优先使用AOF文件来还原数据库。

redis——持久化篇的更多相关文章

  1. 浅谈:Redis持久化机制(一)RDB篇

    浅谈:Redis持久化机制(一)RDB篇 ​ 众所周知,redis是一款性能极高,基于内存的键值对NoSql数据库,官方显示,它的读效率可达到11万次每秒,写效率能达到8万次每秒,因为它基于内存以及存 ...

  2. 浅谈:Redis持久化机制(二)AOF篇

    浅谈:Redis持久化机制(二)AOF篇 ​ 上一篇我们提及到了redis的默认持久化方式RDB,是一种通过存储快照数据方式持久化的机制,它在宕机后会丢失掉最后一次更新RDB文件后的数据,这也是由于它 ...

  3. Redis-cluster集群【第二篇】:redis持久化

    Redis持久化原理: Redis支持两种持久化:RDB和AOF模式 一.名词解释: RDB:持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot).AOF ...

  4. 【Redis篇】Redis持久化方式AOF和RDB

    一.前述 持久化概念:将数据从掉电易失的内存存放到能够永久存储的设备上. Redis持久化方式RDB(Redis DB)   hdfs:    fsimageAOF(AppendOnlyFile)   ...

  5. Redis基础篇(三)持久化:AOF日志

    Redis是内存数据库,但是一旦服务器宕机,内存中的数据将会全部丢失. 最简单的恢复方式是从后端数据库恢复,但这种方式有两个问题: 频繁访问数据库,会给数据库带来巨大的压力: 从数据库中读取相比从Re ...

  6. Redis基础篇(四)持久化:内存快照(RDB)

    AOF好处是每次执行只需要记录操作命令,记录量不大.但在故障恢复时,需要逐一执行AOF的操作命令,如果日志很大,恢复就很慢. 今天学习另一种持久化方式:内存快照.内存快照,是Redis某一时刻的状态, ...

  7. 解密Redis持久化

    原文 http://blog.nosqlfan.com/html/3813.html 本文内容来源于Redis作者博文,Redis作者说,他看到的所有针对Redis的讨论中,对Redis持久化的误解是 ...

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

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

  9. 深度剖析Redis持久化

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt118 Redis是一种面向"key-value"类型数据 ...

随机推荐

  1. 关于android 5.0对开发带来的影响

    由于google推出了android5.0的系统,在app的安装方式,权限的管理方面与之前的系统有较大的区别.自己做的app也有体会.现在记录一些要注意的东西,防止忘记: 1.5.0改变了对自定义权限 ...

  2. 浅谈oracle10G spfile与pfile(转)

    转自:http://blog.csdn.net/onebigday/article/details/6108348,http://www.linuxidc.com/Linux/2012-11/7371 ...

  3. JAVA 多线程和并发学习笔记(三)

    Java并发编程中使用Executors类创建和管理线程的用法 1.类 Executors Executors类可以看做一个“工具类”.援引JDK1.6 API中的介绍: 此包中所定义的 Execut ...

  4. HTML 浏览器显示控制

    //强制浏览器以最高版本运行页面 <meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1" ...

  5. android 动态设置控件宽高度

    Android 代码里直接使用 setWidth() 和 setHeight()设置宽高度是没用的. 解决办法是 改用setLayoutParams()方法 如设置宽高内容自适应: setLayout ...

  6. Docker指令集

     FROM            语法:FROM <image>[:<tag>]         解释:设置要制作的镜像基于哪个镜像,FROM指令必须是整个Dockerfile ...

  7. disconf系列【1】——百度disconf在ubuntu14.04环境下的安装

    disconf官网给出的安装文档默认读者已经非常熟练本文1.2章节给出的依赖软件的原理及使用方法,且官网默认安装环境为linux(windows安装方法只字未提).同时,官网对很多重要的细节语焉不详, ...

  8. CheckBox设置Enabled为False后,无法修改ForeColor

    设置CheckBox的AutoCheck为False,Enabled为True,即可解决.

  9. PHP存储blob示例(转)

    原文:http://www.mysqltutorial.org/php-mysql-blob/ <?php /* CREATE TABLE files ( id INT AUTO_INCREME ...

  10. hive中分析函数window子句

    hive中有些分析函数功能确实很强大,在和sum,max等聚合函数结合起来能实现不少功能. 直接上代码演示吧 原始数据 channel1 2016-11-10 1 channel1 2016-11-1 ...