redis入门第五课:持久化

redis实际上也是一种数据库,就需要考虑到数据的持久化。redis提供了两种持久化方式:AOF,RDB

1. RDB

1.1 定义

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。RDB持久化形成的文件dump.rdb文件是一个经过压缩的二进制数据,通过该文件可以在redis服务器启动时自动恢复数据库中的数据状态。

1.2 RDB文件保存过程

RDB保存命令有两个:SAVE,BGSAVE
SAVE的实现方式
redis的SAVE命令会阻塞线程,一直等到RDB文件保存完为止。
BGSAVE的实现方式

  • redis单独fork出一个子线程,现在有了子进程和父进程。
  • 父进程继续处理业务,而子进程进行持久化,将数据持久化到一个临时文件中。
  • 等到持久化完毕,用临时文件替代上次持久化的文件。方便redis重启的时候还原数据。
    每次快照持久化都是将内存数据完整写入到磁盘一次,并不 是增量的同步数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,会严重影响性能。

1.3 数据恢复过程

redis的RDB持久化方式,并没有直接的命令进行数据的恢复。就是说从rdb文件到数据库的过程,只有在redis配置了开启了持久化方式是RDB的时候,redis服务器在重启的时候会加载rdb文件恢复数据。Redis 服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。恢复数据过程如下所示:

图片.png

1.4 什么情况下对数据进行快照

  • 根据配置规则进行快照
    redis.windows.conf默认配置:
save 900 1
save 300 10
save 60 10000

他们之间的关系是或。就是说每隔900s,如果数据库有至少一个键值对变化,则进行rdb持久化。或者每隔300s,如果数据库有至少10个键值对变化,则进行rdb持久化。或者每隔60s,如果有至少10000个键值对变化,则进行rdb持久化。

  • 用户执行SAVE或者GBSAVE命令
    除了让redis自动快照之外,有时候我们在数据库迁移或者服务器重启的时候需要手动执行rdb持久化。
    redis提供了两条命令来完成这个任务。
    同步数据到磁盘上:save
    SAVE 命令执行一个同步操作,以RDB文件的方式保存所有数据的快照,很少在生产环境直接使用SAVE 命令,因为它会阻塞所有的客户端的请求。
    异步数据到磁盘上:bgsave
    后台保存DB。会立即返回 OK 状态码。 Redis forks, 父进程继续提供服务以供客户端调用,子进程将DB数据保存到磁盘然后退出。如果操作成功,可以通过客户端命令LASTSAVE来检查操作结果。默认快照方式为异步。
  • 执行FLUSHALL命令
    该命令在前面讲过,会清除redis在内存中的所有数据。执行该命令后,只要redis中配置的快照规则不为空,也就是save 的规则存在。
    redis就会执行一次快照操作。不管规则是什么样的都会执行。如果没有定义快照规则,就不会执行快照操作
  • 执行复制(replication)时
    该操作主要是在主从模式下,redis会在复制初始化时进行自动快照。当执行复制操作时,即使没有定义自动快照规则,并且没有手动执行过快照操作,它仍然会生成RDB快照文件。

1.5 RDB的持久化配置

redis.windows.conf配置如下:

# 时间策略
save 900 1
save 300 10
save 60 10000

# 文件名称
dbfilename dump.rdb

# 文件保存路径
dir /home/work/app/redis/data/

# 如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-error yes

# 是否压缩
rdbcompression yes

# 导入时是否检查
rdbchecksum yes

1.6 停止 RDB 持久化

有些时候,我们并不想redis服务器进行RDB持久化,比如redis服务器只用作缓存的时候,怎么停止RDB持久化呢?

  • 通过上面讲的在配置文件 redis.conf 中,可以注释掉所有的 save 行来停用保存功能
  • 执行save命令
save " "

1.7 RDB持久化原理

  • redis.windows.conf配置:
save 900 1
save 300 10
save 60 10000
  • 设置保存条件
struct redisService{
     //1、记录保存save条件的数组
     struct saveparam *saveparams;
     //2、修改计数器
     long long dirty;
     //3、上一次执行保存的时间
     time_t lastsave;
}

主要看看saveparam :

struct saveparam{
     //秒数
     time_t seconds;
     //修改数
     int changes;
};

每一个saveparam都记录了间隔秒数,以及修改次数。比如:save 900 10 ,这里的saveparam就是{seconds:900,changes:10}

  • 检查条件是否满足
    redis的周期性函数serverCron默认每隔100ms执行一次,去检查设置条件是否满足,如果满足,则执行BGSAVE命令,其伪代码如下:
def  serverCron():
//遍历所有设置的条件
...
//如果满足条件开始执行
BGSAVE;

1.8 RDB的特点

  • rdb文件是经过压缩的二进制数据,适合备份和迁移。
  • RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
  • RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
  • RDB 文件需要保存整个数据集的状态,如果快照规则设置的不合适,主线程过多的fork子线程,可能会消耗相对较长的时间,影响Redis对外提供服务的能力。
  • 快照是定期生成的,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失)。

2. AOF

2.1 定义

redis会将每一个写请求都通过write函数追加到文件中(默认是 appendonly.aof)。当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。AOF默认是关闭的,如要开启,进行如下配置:

appendonly yes
H71AGTJ8K$C8FH[H3$E0W4A.png

2.2 AOF文件保存过程

H71AGTJ8K$C8FH[H3$E0W4A.png
  • 第一步是命令的实时写入(如果是 appendfsync everysec 配置,会有1s损耗
    实时写入时与RDB不一样的是,增量的追加写入到文档中:命令写入=》追加到aof_buf =》同步到aof磁盘
    写入buf在同步到磁盘呢?如果实时写入磁盘会带来非常高的磁盘IO,影响整体性能。
  • 第二步是对aof文件的重写
    为什么要对aof文件重写呢?
    aof重写是为了减少aof文件的大小,可以手动或者自动触发。我们知道,有些数据可能会存在大量的写操作,这样有可能出现冗余,随着时间和业务的推进,aof文件会越来越大,会对服务器造成性能损耗,而且在数据恢复时也增大了难度。就需要将aof文件进行整理,重写,使aof文件保存最新的写命令。
    重写的流程如下所示:
    图片.png

2.3 数据恢复过程

图片.png

2.4 AOF的持久化配置

redis.windows.conf文件中配置:

appendonly yes

# 文件名称
appendfilename "appendonly.aof"

# 同步方式
appendfsync everysec

# aof重写期间是否同步
no-appendfsync-on-rewrite no

# 重写触发配置
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 加载aof时如果有错如何处理
aof-load-truncated yes

# 文件重写策略
aof-rewrite-incremental-fsync yes

如果redis目录中没有生成appendonly.aof,则请参考http://www.pianshen.com/article/8293214148/

127.0.0.1:6379> FLUSHALL
OK
127.0.0.1:6379> set msg hello
OK
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> rpush numbers 1 2 3 4 5
(integer) 5
127.0.0.1:6379> get msg
(nil)
127.0.0.1:6379>

aof文件如下所示:

*2
$6
SELECT
$1
0
*1
$8
FLUSHALL
*3
$3
set
$3
msg
$5
hello
*1
$8
flushall
*7
$5
rpush
$7
numbers
$1
1
$1
2
$1
3
$1
4
$1
5

可以看到值记录了我们写命令相关信息。

2.5 AOF的重写

Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令
集合。
重写的流程是这样,主进程会fork一个子进程出来进行AOF重写,这个重写过程并不是基于原有的aof文件来做的,而是有点类似于快照的方式,全量遍历内存中的数据,然后逐个序列到aof文件中。在fork子进程这个过程中,服务端仍然可以对外提供服务,那这个时候重写的aof文件的数据和redis内存数据不一致了怎么办?不用担心,这个过程中,主进程的数据更新操作,会缓存到aof_rewrite_buf中,也就是单独开辟一块缓存来存储重写期间收到的命令,当子进程重写完以后再把缓存中的数据追加到新的aof文件。当所有的数据全部追加到新的aof文件中后,把新的aof文件重命名为,此后所有的操作都会被写入新的aof文件。
如果在rewrite过程中出现故障,不会影响原来aof文件的正常工作,只有当rewrite完成后才会切换文件。因此这个rewrite过程是比较可靠
的。

2.6 AOF的特点

  • 最安全,在启用appendfsync always时,任何已写入的数据都不会丢失,使用在启用appendfsync everysec也至多只会丢失1秒的数据。
  • AOF文件在发生断电等问题时也不会损坏,即使出现了某条日志只写入了一半的情况,也可以使用redis-check-aof工具轻松修复。
  • AOF文件易读,可修改,在进行了某些错误的数据清除操作后,只要AOF文件没有rewrite,就可以把AOF文件备份出来,把错误的命令删除,然后恢复数据。
  • AOF文件通常比RDB文件更大
  • 性能消耗比RDB高
  • 数据恢复速度比RDB慢
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容

  • 一、Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义。 我们知道,在w...
    空语阅读 1,597评论 0 2
  • 企业级redis集群架构的特点 海量数据 高并发 高可用 要达到高可用,持久化是不可减少的,持久化主要是做灾难恢复...
    lucode阅读 2,205评论 0 7
  • 本文档翻译自http://redis.io/topics/persistence。 这篇文章提供了 Redis 持...
    daos阅读 693评论 0 10
  • 黑夜有无数只眼睛闪亮, 而白昼只有一只眼睛发光; 只待夕阳西下, 明亮的世界便 悄然变成黑夜的模样。 身上有无数只...
    爱已无声阅读 158评论 0 13
  • 今天和同事讨论了个深奥的问题“气血”。去查阅资料,深感中医文化博大精深。 什么是气血? 中医认为,气血乃人之根本...
    美小雨阅读 341评论 0 1