一、概述

     Redis的强大性能很大程度上都是因为数据时存在内存中的,然而当Redis重启时,所有存储在内存中的数据将会丢失,所以我们要将内存中的数据持久化。

Redis支持两种数据持久化的方式: RDB方式和AOF方式。

(1)RDB方式会根据配置的规则定时的将内存中的数据持久化到硬盘上。

(2)AOF则是将redis执行过的所有写指令记录下来,在下次redis重新启动时,只要把这些写指令从前到后再重复执行一遍,就可以实现数据恢复了。

     其实RDB和AOF两种方式也可以同时使用,在这种情况下,如果redis重启的话,则会优先采用AOF方式来进行数据恢复,这是因为AOF方式的数据恢复完整度更高。

     如果你没有数据持久化的需求,也完全可以关闭RDB和AOF方式,这样的话,redis将变成一个纯内存数据库,就像memcache一样。

 

1.RDB方式

     RDB方式的持久化是通过快照的方式完成的。当符合某种规则时,会将内存中的数据全部生成一个副本存储在硬盘上,Redis会在以下几种情况下对数据进行快照:

a: 根据配置的规则自动快照。

b: 用户执行save、bgsave命令。

c: 执行flushall命令。

d: 执行复制(replication)。

(1)根据配置自动快照

     Redis允许用户自定义快照条件,当满足条件时自动执行快照,快照规则的配置方式如下:

 

(2)执行save、bgsave命令

     我们可以手动执行save、bgsave命令主动进行快照操作。

save: 当执行save命令时,Redis同步进行快照操作,期间会阻塞所有来自客户端的请求,所以放数据库数据较多时,应该避免使用该命令;

bgsave: 从命令名字就能看出来,这个命令与save命令的区别就在于该命令的快照操作是在后台异步进行的,进行快照操作的同时还能处理来自客户端的请求。执行bgsave命令后Redis会马上返回OK表示开始进行快照操作,如果想知道快照操作是否已经完成,可以使用lasesave命令返回最近一次成功执行快照的时间,返回结果是一个Unix时间戳。

 

(3)执行flushall命令

     执行FLUSHALL命令时,Redis会清除数据库中的所有数据。

 

(4)执行复制

     当设置了主从模式时,Redis会在复制初始化的时候进行自动快照。

 

2.快照原理

     Redis默认会将快照文件存储在Redis当前进程的工作目录的dump.rdb文件中,可以通过配置文件中的dir和dbfilename两个参数分别指定快照文件的存储路径和文件名。

    

快照执行的过程如下:

(1)Redis使用fork()函数复制一份当前进程(父进程)的副本(子进程)。

(2)父进程继续处理来自客户端的请求,子进程开始将内存中的数据写入硬盘的临时文件。

(3)当子进程写完所有的数据后,用该临时文件替换旧的RDB文件。

     Redis启动时会自动读取RDB快照文件,将数据从硬盘载入到内存,根据数量的不同,这个过程持续的时间也不尽相同,通常来讲,一个记录1000万个字符串类型键,大小为1GB的快照文件载入到内存需要20-30秒的时间。

     对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了redis极高的性能。

     如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

     虽然RDB有不少优点,但它的缺点也是不容忽视的。如果你对数据的完整性非常敏感,那么RDB方式就不太适合你,因为即使你每5分钟都持久化一次,当redis故障时,仍然会有近5分钟的数据丢失。所以,redis还提供了另一种持久化方式,那就是AOF。

 

3.AOF方式

默认情况下,Redis没有开启AOF(append only file)持久化功能,可以通过在配置文件中作如下配置启用:

    

     开启之后,Redis每执行一条写命令就会将该命令写入硬盘中的AOF文件。AOF文件保存路径和RDB文件路径是一致的,都是通过dir参数配置,默认文件名是:appendonly.aof,可以通过配置appendonlyfilename参数修改。

AOF英文是Append Only File,即只允许追加不允许改写的文件。

     如前面介绍的,AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍,就这么简单。

     我们通过配置redis.conf中的appendonly yes就可以打开AOF功能。如果有写操作(如SET等),redis就会被追加到AOF文件的末尾。

     默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。

     如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志修复。

     因为采用了追加方式,如果不做任何处理的话,AOF文件会变得越来越大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。举个例子或许更形象,假如我们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,完全可以把这100条指令合并成一条SET指令,这就是重写机制的原理。

     在进行AOF重写时,仍然是采用先写临时文件,全部完成后再替换的流程,所以断电、磁盘满等问题都不会影响AOF文件的可用性,这点大家可以放心。

     AOF方式的另一个好处,我们通过一个“场景再现”来说明。某同学在操作redis时,不小心执行了FLUSHALL,导致redis内存中的数据全部被清空了,这是很悲剧的事情。不过这也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件还没有被重写(rewrite),我们就可以用最快的速度暂停redis并编辑AOF文件,将最后一行的FLUSHALL命令删除,然后重启redis,就可以恢复redis的所有数据到FLUSHALL之前的状态了。是不是很神奇,这就是AOF持久化方式的好处之一。但是如果AOF文件已经被重写了,那就无法通过这种方法来恢复数据了。

     虽然优点多多,但AOF方式也同样存在缺陷,比如在同样数据规模的情况下,AOF文件要比RDB文件的体积大。而且,AOF方式的恢复速度也要慢于RDB方式。

     如果你直接执行BGREWRITEAOF命令,那么redis会生成一个全新的AOF文件,其中便包括了可以恢复现有数据的最少的命令集。

     如果运气比较差,AOF文件出现了被写坏的情况,也不必过分担忧,redis并不会贸然加载这个有问题的AOF文件,而是报错退出。这时可以通过以下步骤来修复出错的文件:

1.备份被写坏的AOF文件。
2.运行redis-check-aof –fix进行修复。
3.用diff -u来看下两个文件的差异,确认问题点。
4.重启redis,加载修复后的AOF文件。

Redis基础学习(四)—Redis的持久化的更多相关文章

  1. Redis基础学习(一)—Redis的安装

    一.Redis的安装 1.在Linux环境下安装gcc环境 yum install gcc-c++   2.解压缩Redis源码包 tar -zxf redis-3.0.0.tar.gz   3.编译 ...

  2. Redis基础学习(五)—Redis的主从复制

    一.概述     Redis的主从复制策略是通过其持久化的rdb文件来实现的,其过程是先dump出rdb文件,将rdb文件全量传输给slave,然后再将dump后的操作实时同步到slave中.让从服务 ...

  3. Python基础学习四

    Python基础学习四 1.内置函数 help()函数:用于查看内置函数的用途. help(abs) isinstance()函数:用于判断变量类型. isinstance(x,(int,float) ...

  4. redis 基础学习总结

    背景:因为项目用到了redis,加上之前一直听说了redis,但一直没有用过,正好项目现在要用到了,抽时间简单学习了下,做个记录总结下. 一 .Redis简介 介绍Redis之前,先了解下NoSQL ...

  5. redis深入学习(二)-----redis配置文件、持久化

    redis配置文件 地址 units单位 a  配置大小单位,开头定义了一些基本的度量单位,只支持bytes,不支持bitb  对大小写不敏感 GENERAL通用 1.daemonize 2.pidf ...

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

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

  7. redis基础学习(不定期更新)

    redis简介 redis是Remote Dictionary Server(远程数据服务)的缩写 数据模型是key-value,是用C编写的 数据类型有string list hash set so ...

  8. 15,redis基础学习

    redis Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件 yum安装redis 1.yum安装 #前提得配置好阿里云yum源,epel源 #查看 ...

  9. redis基础学习---1

    5.1.xshell传输文件命令快捷键:alt+p 2.当运行一个程序时,想退出按ctrl+c退出 3.给用户权限:chmod 777 redis.conf 另一种方式:chmod –x 4. 5.查 ...

随机推荐

  1. Unity3d中如何混用三种脚本语言?

    首先要明白,这三种说的混用是指文件级别的混用,就是说一个文件是由一种语言写的.而不是说你这一个文件可以混用这三种语言,注意这是不允许的. 第二要明白,在unity3d中为什么可以使用三种语言混合开发? ...

  2. Ansible详解(一)

    简介 Ansible是一个简单的自动化运维管理工具,基于Python语言实现,由Paramiko和PyYAML两个关键模块构建,可用于自动化部署应用.配置.编排task(持续交付.无宕机更新等).主版 ...

  3. 动态添加删除网卡 - 每天5分钟玩转 OpenStack(156)

    这是 OpenStack 实施经验分享系列的第 6 篇. 在项目实施过程中,经常会有添加删除网卡的需求.比如一个运行数据库的 instance,初始只有一个网卡,数据库服务和备份共用这块网卡,后来为提 ...

  4. Oracle主键异常处理

    Hibernate: insert into test1.WarnWeather (WAREA, wdate, WDAYS, WINFO, WTYPE, WNO) values (?, ?, ?, ? ...

  5. HTML5之多媒体

    概览 html5新增了两个关于多媒体的元素:video和audio,前者是用于视频,后者用于音频.而他们使用非常简单 <audio src="xhn.mp3" control ...

  6. 关于Edittext默认弹出软键盘为数字键

    如果说我们只是输入数字的话,我们可以直接在xml文件中: android:inputType="number" 如果是身份证类型的话,我们可以这样: android:inputTy ...

  7. 2751: [HAOI2012]容易题(easy)

    2751: [HAOI2012]容易题(easy) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1087  Solved: 477[Submit][ ...

  8. AndroidTest工程的自定义gradle task

    由于需要将assets目录的资源拷贝到设备sdcard中,然而我的工程是一个android test工程,而android test工程在编译阶段,不会把assets目录的资源打包成对应apk,而为了 ...

  9. zip error: Invalid command arguments

    在编译使用svn管理的android代码时,会出现如下错误: zip error: Invalid command arguments (cannot repeat names in zip file ...

  10. django进阶-3

    先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...