Redis持久化

Redis持久化

一、持久化简介

因为Redis是内存数据库,它将自己的数据库状态储存在内存里面,所以如果不想办法将储存在内存中的数据库状态保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据库状态也会消失不见。

因此Redis 提供了两种持久化方案,RDB (Redis DataBase)和 AOF (Append Only File)。

二、RDB持久化

RDB 是 Redis 默认的持久化方案。RDB持久化可以手动执行也可以根据服务器配置选项定期执行。该功能会将在某个时间点上的数据库状态保存到一个.rdb文件。Redis 重启会通过加载.rdb文件恢复数据。

2.1 RDB手动备份恢复

有两个redis命令可以用于生成rdb文件:

  • save:save命令会阻塞redis服务器进程,直到rdb文件创建完成为止,在服务器进程阻塞期间不能处理任何命令请求;
  • bgsave:bgsave命令会派生出一个子进程,由子进程负责创建rdb文件,父进程继续处理redis命令。

rdb文件的数据恢复工作是在redis启动时自动完成的,没有特殊命令来手动进行恢复工作,值得注意的是由于AOF的更新频率通常会比RDB更新频率高,因此如果服务器开启了AOF持久化那么redis优先使用AOF恢复数据,只有在AOF持久化关闭时才使用RDB恢复数据。

# 阻塞主进程的持久化
127.0.0.1:6379> save
OK
# 使用子进程持久化
127.0.0.1:6379> BGSAVE
Background saving started
# 执行任意一个命令就会生成/var/lib/redis/dump.rdb 文件

# rdb文件恢复
# 查看rdb文件存放位置
127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"
# 将需要恢复的rdb文件放在/var/lib/redis下
# 重启redis(注意:不要使用service redis-server restart/stop/start重启,否则出现莫名其妙的错误,rdb无法恢复)
redis-cli shutdown
sudo redis-server /etc/redis/redis.conf
# 登录redis-cli就会看到恢复的数据

2.2 RDB配置

/etc/redis/redis.conf 文件中

save 900 1  # 时间策略,服务器在900秒之内,对数据库进行了至少1次修改。
save 300 10  # 时间策略,服务器在300秒之内,对数据库进行了至少10次修改。
save 60 10000  # 时间策略,服务器在60秒之内,对数据库进行了至少1000次修改。
dbfilename dump.rdb   #文件名称
dir /var/lib/redis   #文件保存路径 
stop-writes-on-bgsave-error yes   # 如果持久化出错,主进程是否停止写入 
rdbcompression yes    # 是否压缩 
rdbchecksum yes     # 导入时是否检查 

# 通过save 300 10次略,我们可以在5分钟内插入10个数据,到了五分钟发现的确生成了新的dump.rdb文件,说明配置生效

那么为什么需要配置这么多条规则呢?因为Redis每个时段的读写请求肯定不是均衡的,为了平衡性能与数据安全,我们可以自由定制什么情况下触发备份。所以这里就是根据自身Redis写入情况来进行合理配置。

2.3 RDB优缺点

优点

  • 适合大规模的数据恢复。
  • 如果业务对数据完整性和一致性要求不高,RDB是很好的选择。

缺点:

  • 数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
  • 备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时总占用内存是原来的两倍),最后再将临时文件替换之前的备份文件。所以Redis 的持久化和数据的恢复要选择在夜深人静的时候执行是比较合理的。

三、AOF持久化

Redis 默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

3.1 AOF持久化步骤

  1. 命令追加:在AOF模式打开的情况下,服务器每执行一次写命令就会以协议格式将执行的写命令追加到aof_buf缓冲区的末尾;
  2. AOF文件的写入和同步:Redis每执行完一次事件循环,就要考虑要不要将缓冲区的数据写入AOF文件,写入同步策略有配置文件的appendfsync决定:appendfsync的值有三个
    1. always:将缓冲区所有内容写入并同步AOF文件;
    2. everysec(默认):将缓冲区内容写入AOF文件,如果上次同步AOF文件的时间与现在间隔超过1秒钟,那么在此对AOF文件进行同步,并且这个同步操作是由一个线程专门执行的;
    3. no:将缓冲区内容写入文件,不对AOF进行同步,何时同步由操作系统来决定。
tips:
为了提高文件的写入效率,在现代操作系统中,当用户调用write函数,将一些数据写入到文件的时候,操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区的空间被填满、或者超过了指定的时限之后,才真正地将缓冲区中的数据写入到磁盘里面。这种做法虽然提高了效率,但也为写入数据带来了安全问题,因为如果计算机发生停机,那么保存在内存缓冲区里面的写入数据将会丢失。为此,系统提供了fsync和fdatasync两个同步函数,它们可以强制让操作系统立即将缓冲区中的数据写入到硬盘里面,从而确保写入数据的安全性。

3.2 AOF重写机制

因为AOF备份的策略是保存所有的写命令,当写命令不断增加时,AOF文件会越来越大,可能会影响系统性能和恢复数据的性能。为了解决这个问题,Redis提供了AOF文件重写(rewrite)功能。通过该功能,Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个AOF文件所保存的数据库状态相同,但新AOF文件不会包含任何浪费空间的冗余命令,所以新AOF文件的体积通常会比旧AOF文件的体积要小得多。

那么它是如何实现的呢?虽然名字叫做AOF重写,但是新文件并不会读取并分析旧的AOF文件,而是通过读取当前数据库的状态来实现的。过程就是首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令,这就是AOF重写功能的实现原理。

数据不一致的处理

Redis使用一个子进程来处理AOF的重写,这样会导致数据不一致的问题,比如当开始重写的时候数据库只有key1,在重写过程中有增加了key2,那么重写完后AOF中只有key1,就导致了数据的不一致。为了解决这种数据不一致问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程之后开始使用,当Redis服务器执行完一个写命令之后,它会同时将这个写命令发送给AOF缓冲区和AOF重写缓冲区。

当子进程完成AOF重写工作之后,它会向父进程发送一个信号,父进程在接到该信号之后,会调用一个信号处理函数,并执行以下工作:

  • 将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新AOF文件所保存的数据库状态将和服务器当前的数据库状态一致。

  • 对新的AOF文件进行改名,原子地(atomic)覆盖现有的AOF文件,完成新旧两个AOF文件的替换。这个信号处理函数执行完毕之后,父进程就可以继续像往常一样接受命令请求了。

在整个AOF后台重写过程中,只有信号处理函数执行时会对服务器进程(父进程)造成阻塞,在其他时候,AOF后台重写都不会阻塞父进程,这将AOF重写对服务器性能造成的影响降到了最低。

3.3 AOF配置和恢复

/etc/redis/redis.conf 文件中

appendonly yes  # yes表示开启AOF持久化
appendfilename "appendonly.aof" 
appendfsync everysec # 数据写入同步的策略(everysec、always、no)
#设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no
no-appendfsync-on-rewrite no 
#当前AOF文件大小是上次日志重写得到AOF文件大小的二倍时,自动启动新的日志重写过程。
auto-aof-rewrite-percentage 100
#当前AOF文件启动新的日志重写过程的最小值,避免刚刚启动Reids时由于文件尺寸较小导致频繁的重写。
auto-aof-rewrite-min-size 64mb

恢复数据:

# 配置完后重启redis,写入几条数据,发现生成了aof文件
# 先将aof文件移动到其他目录,然后清空所有数据,再移动回来,重启redis后发现数据恢复了。

appendonly.aof其实就是文本文件,所以完全可以手动修改aof文件来恢复成指定的数据:

# file appendonly.aof 
appendonly.aof: ASCII text, with CRLF line terminators
# cat appendonly.aof 
*2
$6
SELECT
$1
0
*3
$3
......此处省略N行
set
$5
name4
$1
4

3.4 AOF优缺点

优点:

数据的完整性和一致性更高

缺点:

因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。

四、总结

  1. Redis 默认开启RDB持久化方式,在指定的时间间隔内,执行指定次数的写操作,则将内存中的数据写入到磁盘中。
  2. RDB 持久化适合大规模的数据恢复但它的数据一致性和完整性较差。
  3. Redis 需要手动开启AOF持久化方式,默认是每秒将写操作日志追加到AOF文件中。
  4. AOF 的数据完整性比RDB高,但记录内容多了,会影响数据恢复的效率。
  5. Redis 针对 AOF文件大的问题,提供重写的瘦身机制。
  6. 若只打算用Redis 做缓存,可以关闭持久化。
  7. 若打算使用Redis 的持久化。建议RDB和AOF都开启。其实RDB更适合做数据的备份,留一后手。AOF出问题了,还有RDB。

问题

  1. RDB和AOF持久化后的文件存储在哪?

RDB文件存储在/var/lib/redis/dump.rdb,实际位置取决于配置文件/etc/redis/redis.conf中的dir /var/lib/redis,也可以在redis-cli中使用命令config get dir获取。

  1. AOF持久化开启后,是否只是记录开启时间点之后的写操作,那之前的数据如何保证备份呢?

AOF重写时会以当前数据库为依据生成所有写入语句。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349