Redis数据持久化

总的来说有两种持久化方案:RDB和AOF

RDB方式按照一定的时间间隔对数据集创建基于时间点的快照。

AOF方式记录Server收到的写操作到日志文件,在Server重启时通过回放这些写操作来重建数据集。该方式类似于MySQL中基于语句格式的binlog。当日志变大时Redis可在后台重写日志。

若仅期望数据在Server运行期间存在则可禁用两种持久化方案。在同一Redis实例中同时开启AOF和RDB方式的数据持久化方案也是可以的。该情况下Redis重启时AOF文件将用于重建原始数据集,因为叫RDB方式而言,AOF方式能最大限度的保证数据完整性。

两钟方案各自的优缺点

RDB优点

RDB是Redis数据集的基于时间点的紧凑的副本,非常适合于备份场景。比如每个小时对RDB文件做一次小的归档,每天对RDB文件做一次大的归档,每月对RDB文件做一次更大的归档。这样可以在必要的时刻选择不同的备份版本进行数据恢复。

由于是一个紧凑的文件,易于传输到远程数据中心或Amazon S3,因此RDB非常适合于灾难恢复。

RDB方式的开销较低,在该种方式下Redis父进程所要做的仅是开辟一个子进程来做剩下的事情。

与AOF相比RDB在数据集较大时能够以更快的速度恢复。

RDB缺点

若需在Redis停止工作时(例如意外断电)尽可能保证数据不丢失,那么RDB不是最好的方案。例如,通常会每隔5分钟或者更长的时间来创建一次快照,如若Redis没有被正确的关闭就可能丢失最近几分钟的数据。

RDB方式需经常调用fork()函数以开辟子进程来实现持久化。在数据集较大、CPU性能不够强悍时fork()调用可能很耗时从而会导致Redis在几毫秒甚至一秒中的时间内不能服务clients。AOF也需要调用fork()但却可以在不影响数据持久性的条件下调整重写logs的频率。

AOF优点

使用AOF方式时Redis持久化更可靠:有三种不同的fsync策略供选择:no fsync at all、fsync every second、 fsync at every query。默认为fsync every second此时的写性能仍然很好,且最坏的情况下可能丢失一秒钟的写操作。

AOF日志是append only方式产生的日志,因此不存在随机访问问题以及意外断电时造成的损毁问题。即使出于某种原因(如磁盘满)日志以一个写了一半的命令结尾,仍可以使用redis-check-aof工具快速进行修复。

当AOF日志逐渐变大后,Redis可在后台自动的重写AOF日志。当Redis在继续追加旧的AOF日志文件时重写日志是完全安全的。Redis利用可以重建当前数据集的最少的命令产生一个全新的日志文件,一旦新的日志文件创建完成Redis开始向新的日志文件追加日志。

AOF日志的格式易于理解易于解析。这在某些场景非常有用。比如,不下心使用FLUSHALL命令清空了所有的数据,同时AOF日志没有发生重写操作,那么就可以简单的通过停止Redis Server移除日志中的最后一条FLUSHALL命令重启Redis Server来恢复数据。

AOF缺点

同样的数据集AOF文件要比RDB文件大很多。

根据使用的fsync方式不同AOF可能比RDB慢很多。在使用no fsync at all时AOF的性能基本与RDB持平,在使用fsync every second时性能有所下降但仍然较高,在使用 fsync at every query时性能较低。然而RDB方式却能在高负载的情况下保证延迟尽可能小。

一些特定的命令可能存在bug从而导致重载AOF日志时不能重建出完全一样的数据集。这样的bugs非常非常罕见,已经通过测试套件做了充分的测试。这种类型的bugs对于RDB来说几乎是不可能的。说的更清晰一点:Redis AOF增量的更新既存的状态而RDB快照每次都重新创建,从概念上讲RDB方式更加健壮。然而,需要注意两点:每次AOF日志被Redis重写的时候日志由包含数据集的实际数据重新生成,与追加AOF文件的方式相比该方式能有效减少bugs出现的概率;现实的应用场景中还未收到过任何用户关于AOF损毁的报告。

如何选择持久化方式?

取决于具体的应用场景,通常,两种方式可同时使用。若比较关心数据但仍能忍受几分钟的数据丢失,那么可以简单的使用RDB方式。有许多用户只使用AOF方式,不建议这种做法,一方面以一定时间间隔创建RDB快照是创建数据备份并快速恢复数据的极好的办法,一方面可以避免AOF方式可能存在的bugs。出于上述原因,将来可能将AOF和RDB方式合二为一。

RDB持久化设置

默认情况下Redis在磁盘上创建二进制格式的命名为dump.rdb的数据快照。可以通过配置文件配置每隔N秒且数据集上至少有M个变化时创建快照、是否对数据进行压缩、快照名称、存放快照的工作目录。redis 2.4.10的默认配置如下:

#900秒后且至少1个key发生变化时创建快照
save 900 1
#300秒后且至少10个key发生变化时创建快照
save 300 10
#60秒后且至少10000个key发生变化时创建快照
save 60 10000
#可通过注释所有save开头的行来禁用RDB持久化
#创建快照时对数据进行压缩
rdbcompression yes
#快照名称
dbfilename dump.rdb
#存放快照的目录(AOF文件也会被存放在此目录)
dir /var/lib/redis/

关于配置参数的详细信息可参阅redis.conf中的说明。

除了通过配置文件进行设置外也可以通过手工执行命令来创建快照

SAVE命令执行一个同步操作,以RDB文件的方式保存实例中所有数据的快照。一般不在生产环境直接使用SAVE 命令,因为会阻塞所有的客户端的请求,可以使用BGSAVE命令代替。BGSAVE后台创建数据快照。命名执行结果的状态码会立即返回。Redis开辟一个子进程,父进程继续相应客户端请求,子进程保存DB到磁盘后退出。客户端可通过执行LASTSAVE命令检查操作是否成功。

创建RDB快照的工作流程

Redis需dump数据集到磁盘时会执行下列过程:

Redis forks一个子进程;

子进程写数据集到临时的RDB文件;

子进程写完新的RDB文件后替换旧的RDB文件。

该方式使Redis可以利用copy-on-write机制的好处。

AOF持久化设置

利用快照的持久化方式不是非常可靠,当运行Redis的计算机停止工作、意外掉电、意外杀掉了Redis进程那么最近写入Redis的数据将会丢。对于某些应用这或许不成问题,但对于持久化要求非常高的应用场景快照方式不是理想的选择。AOF文件是一个替代方案,用以最大限度的持久化数据。同样,可以通过配置文件来开闭AOF:

#关闭AOF
appendonly no
#打开AOF
appendonly yes

当设置appendonly为yes后,每次Redis接收到的改变数据集的命令都会被追加到AOF文件。重启Redis后会重放AOF文件来重建数据。

还可以通过配置文件配置AOF文件名、调用fsync的频率、调用fsync的行为、重写AOF的条件。redis 2.4.10的默认配置如下:

#默认AOF文件名
appendfilename appendonly.aof
#每秒调用一次fsync刷新数据到磁盘
appendfsync everysec
#当进程中BGSAVE或BGREWRITEAOF命令正在执行时不阻止主进程中的fsync()调用(默认为no,当存在延迟问题时需调整为yes)
no-appendfsync-on-rewrite no
#当AOF增长率为100%且达到了64mb时开始自动重写AOF
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

各参数含义可参阅redis.conf中详细说明。

几点说明

日志重写

随着Redis接收到的命令的增加AOF文件会变得越来越大。Redis支持日志重写特性,可以在不影响响应客户端的前提下在后台重构AOF文件。当在Redis中执行BGREWRITEAOF后Redis将使用构建数据集所需的最少的命令来重构日志文件。Redis2.2中需要经常手动运行BGREWRITEAOF,Redis2.2开始支持自动触发日志重写。

日志重写同样使用copy-on-write机制,流程大致如下:

Redis开辟一个子进程;

子进程在临时文件中写新的AOF文件;

父进程将所有新的更改缓存在memory中(同时新更改被写入旧的AOF,这样即使重写操作失败了也是安全的);

在子进程重写好临时AOF后父进程收到一个信号并追加memory中缓冲的更改到子进程产生的临时文件的末尾;

Redis进行文件重命名用新的文件替换旧的文件并开始追加新的数据到新文件。

fsync调用模式

该模式决定了Redis刷新数据到磁盘的频率,有三个可选项:

no fsync at all 全由操作系统决定刷数据的时机。最快但最不安全。

fsync every second 每秒一次刷新。足够快,最多可丢失一秒的数据。

fsync at every query 每次记录一条新的命令到AOF便刷一次数据到磁盘。最慢但最安全。

默认策略(也是默认策略)为fsync every second

AOF损坏时的对策

若在写AOF文件时Server崩溃则可能导致AOF文件损坏而不能被Redis载入。可通过如下步骤修复:

创建一个AOF文件的备份;

使用redis-check-aof工具修复原始的AOF文件;

$ redis-check-aof --fix

使用diff -u 检查备份文件和修复后文件的异同(可选步骤);

使用修复后的AOF文件重启Redis。

如何由RDB持久化转换到AOF持久化?

Redis >=2.2时

创建最近的RDB文件的备份;

将备份保存在安全的位置;

发起如下命令;

$redis-cli config set appendonly yes

$redis-cli config set save ""(可选,若不执行RDB和AOF方式将并存)

确认数据库包含相同的keys;

确认write操作被正确追加到了AOF文件。

注意事项:记得修改redis.conf中对应的配置以免Redis Server重启后通过命令进行的配置更新丢失而重新使用旧的配置文件中配置。

Redis2.0时

创建最近的RDB文件的备份;

将备份存放在安全的位置;

停止数据库上的所有写操作;

发起 redis-cli bgrewriteaof命令创建AOF文件;

当AOF文件生成后停止Redis Server;

编辑redis.conf开启AOF持久化;

重启Redis Server;

确认数据库包含相同的keys;

确认write操作被正确追加到了AOF文件。

AOF与RDB之间的相互影响

Redis2.4以上的版本会确保在RDB快照创建时不触发AOF重写或者在AOF重写时不允许BGSAVE操作,以避免Redis后台进程同时做繁重的磁盘I/O操作。

当创建RDB快照时对于用户使用BGREWRITEAOF明确发起的日志重写操作server会立刻回应一个ok状态码告知用户操作将回被执行,当且仅当快照创建完成后重写操作开始被执行。

在同时使用了AOF和RDB方式的情况下,Redis重启后会优先使用AOF文件来重构原始数据集。

备份Redis 数据

务必做好数据备份以防意外丢失。Redis是备份友好的,可在数据库运行时拷贝RDB文件。建议的备份方案:

创建一个cron作业在一个目录中每小时创建一次RDB快照在另一目录中每天创建一次RDB快照;

cron作业每次运行的时候使用find命令确保过时的RDB快照文件被清理掉(可以通过在快照命中包含数据和时间信息来进行标记);

确保将RDB快照转移到外部的数据中心或者至少是运行Redis实例的物理机之外的机器(至少每天一次)。

灾难恢复

在Redis中灾难恢复和数据备份基本上是同样的过程。可考虑将备份分布到不同的远程数据中心以最大限度的避免数据丢失。几种低成本的灾难恢复计划:

Amazon S3或其它类似服务是很好的选择。可将每天会每小时的RDB快照以加密的方式(可使用gpg -c加密)传输到S3。确保将密码存储在不同的安全的地方。建议使用不同的存储服务以提高数据安全性。

使用SCP命令将快照传输到远程服务器。最简单和安全的方式:获取一个小的远程VPS,在其上安装ssh,生成无密码的ssh client key添加到VPS的authorized_keys文件,此后便可使用SCP传输备份到VPS了。建议搞两个不同的VPS以提高安全性。

需要注意的是,文件传输完成后一定要校验文件的完整性正确性。可通过MD5或SHA1进行验证。另外需要搭建一套告警系统,当备份传输发生问题时能及时的告知。

时间: 2024-11-02 13:37:57

Redis数据持久化的相关文章

redis 数据持久化

转:redis 数据持久化 1.快照(snapshots) 缺省情况情况下,Redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb.你可以配置Redis的持久化策略,例如数据集中每N秒钟有超过M次更新,就将数据写入磁盘:或者你可以手工调用命令SAVE或BGSAVE. 数据保存的目录: 工作原理 Redis forks. 子进程开始将数据写到临时RDB文件中. 当子进程完成写RDB文件,用新文件替换老文件. 这种方式可以使Redis使用copy-on-write技术. 2.APP

Redis数据持久化机制AOF原理分析二

Redis数据持久化机制AOF原理分析二 分类: Redis 2014-01-12 15:36  737人阅读  评论(0)  收藏  举报 redis AOF rewrite 目录(?)[+] 本文所引用的源码全部来自Redis2.8.2版本. Redis AOF数据持久化机制的实现相关代码是redis.c, redis.h, aof.c, bio.c, rio.c, config.c 在阅读本文之前请先阅读Redis数据持久化机制AOF原理分析之配置详解文章,了解AOF相关参数的解析,文章链

redis使用基础(五) ——Redis数据持久化

redis使用基础(五) --Redis数据持久化 (转载请附上本文链接--linhxx) 当服务器突然发生问题,或者redis重启,如果希望将数据持久化在硬盘中,下次开启redis还有数据时,redis提供了两种方案,一个叫做RDB(通过内存快照(Snapshotting)实现),另一个叫做AOF(日志追加(Append-only file)).通常结合两种方式来实现redis的持久化. 1.RDB RDB通过内存快照实现,会将redis当前的全部数据以快照的方式写入二进制文件中.实现快照有以

02 : redis 数据持久化

Redis数据持久化 什么是持久化: 通俗点:就是把redis缓存在内存中的数据保存到磁盘文件里面. Redis持久化分2种: RDB 持久化 可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). 优点:速度快,适合于用做备份,主从复制也是基于RDB持久化功能实现的. 缺点:会有数据丢失 AOF 持久化 记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集. AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会

redis数据持久化内存不足

原因:写数据到redis里面写不进去,查看redis日志显示: Can't save in background: fork: Cannot allocate memory 在小内存的进程上做一个fork,不需要太多资源,但当这个进程的内存空间以G为单位时,fork就成为一件很恐怖的操作. 发现问题之后,我先通过sysctl -a查看linux内核参数vm.overcommit_memory(sysctl -a |grep "vm.overcommit_memory"),我们直接修改内

Redis 数据持久化的理解

一.对持久化的理解 Redis 平时的键值对都是在内存中的,但是一旦意外中断或关闭连接,我们将丢失数据. 为了避免这种情况,就有一个持久化的机制,在某种条件下将数据以某种方式转储到文件中,下次启动服务器时可以通过持久化文件恢复数据. 二.持久化的方式 Redis 提供了两种方式,分别是RDB 和 AOF,两者最大的区别是 RDB 存储的是数据库状态(键值对),AOF 则是通过保存 Redis 服务器所执行的命令来记录数据库状态. 三.RDB 3.1 RDB文件的创建与载入 RDB持久化可以手动执

redis 数据持久化 aof方式

打开redis的运行目录,选择数据库2(select 2,是空集)可以看到dump.rdb的上次保存时间是今天中午1:58 添加2条数据: 再查看dump.rdb,保存时间是现在(说明从1:58到现在没有修改过key) 在dump.rdb中可以看到刚才保存进入的数据,但是当添加第三个数据addr3时,dump.rdb的修改时间是不会变的,没有达到快照备份的频率. 现在选择标号为3数据库,添加2条数据,此时还未达到快照持久化的频率,所以默认dump.rdb中还没有这两个数据,dump.rdb的修改

redis学习——数据持久化

一.概述 Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的.所以,我们需要将内存中的数据持久化!典型的需要持久化数据的场景如下: 将Redis作为数据库使用: 将Redis作为缓存服务器使用,但是缓存miss后会对性能造成很大影响,所有缓存同时失效时会造成服务雪崩,无法响应. 本文介绍Redis所支持的两种数据持久化方式. 二.Redis数据持久化 Redis支持两种数据持久化方式:RDB

Redis基本数据类型、数据持久化、过期策略及淘汰机制

一点技术.技术乐享!!! 如果有人问你:Redis这么快,他的“多线程模式”你了解吗? 请回答他:您是想问Redis这么快,为什么还是单线程模式吗? redis是什么 简单来说redis是C语言开发的一个开源的(遵从BSD协议)高性能键值对(key-value)的内存数据库,可以用作数据库.缓存.消息中间件等. 性能优秀,数据在内存中,读写速度非常快,支持并发10W QPS. 单进程单线程,是线程安全的,采用Io多路复用机制. 丰富的数据类型,支持字符串(string).散列(hash).列表(