【Redis核心知识 二】Redis持久化策略(一)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,经济版 1GB 1个月
简介: 【Redis核心知识 二】Redis持久化策略

上一篇blog在linux中安装了Redis,并且对Redis进行了启动和操作。本篇blog主要学习下Redis的持久化策略。什么是持久化呢?举个最简单的例子,就是内存中的数据如果突然遭遇断电,将会丢失,那么为了保证数据不丢失,内存中的数据要持久化到硬盘里来利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化。持久化的作用就是防止数据的意外丢失,确保数据安全性!也就是为什么我们每写会儿文档就要保存一次的原因。

因为Redis本质上也是个数据库,所以也面临持久化的问题,Redis提供的持久化策略有两种,一种是RDB,也就是数据快照,一种是AOF,也就是数据日志。

RDB方案

RDB是数据快照的持久化策略,只存储数据结果,存储格式简单,关注点在数据。依据执行持久化时机分为如下三种策略:

save即时执行策略

save即时生成策略持久化的命令为save。我们执行下查看:

127.0.0.1:6379> keys *
1) "love"
127.0.0.1:6379> save
OK
127.0.0.1:6379> set age 26
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379> set sex girl
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379>

我们找到之前设定的log文件地址查看文件,可以看到生成了一个新的文件:

save执行原理

这就是之前大佬们老是讨论的而我一无所知的dump快照文件啊!,那么save执行的原理是什么呢?因为redis是单线程的,所以多客户端操作的时候,会有个指令执行顺序。

save指令比较耗费服务器性能!

RDB最佳配置

其实使用RDB存在一些最佳实践,我们调整下它的配置,还是在redis-6379.conf进行修改,修改后配置为:

port 6379
daemonize yes
logfile "redis-6379.log" 
dir /root/redis-6.0.8/data/
dbfilename dump-6379.rdb
rdbcompression yes
rdbchecksum yes

同时我们可以把6380也同步修改了即可,修改完后杀掉进程,重启服务:

[root@192 ~]# ps -ef |  grep redis-
root      35924      1  0 11:28 ?        00:01:05 redis-server *:6379
root      36048      1  0 11:35 ?        00:01:04 redis-server *:6380
root      39574  39523  5 15:24 pts/0    00:00:00 grep --color=auto redis-
[root@192 ~]# kill -s 9 35924
[root@192 ~]# kill -s 9 36048
[root@192 ~]# ps -ef |  grep redis-
root      39591  39523  0 15:25 pts/0    00:00:00 grep --color=auto redis-
[root@192 redis-6.0.8]# redis-server config/redis-6379.conf
[root@192 redis-6.0.8]# redis-cli -p 6379
127.0.0.1:6379> set name tml love guochengyu
(error) ERR syntax error
127.0.0.1:6379> set name tmlloveguochengyu
OK
127.0.0.1:6379> get name
"tmlloveguochengyu"
127.0.0.1:6379> save
OK
127.0.0.1:6379>

我们可以看到已经写了新的dump文件进入data了,我们把之前的删掉即可。

查看即可隐约看到文件内容:

[root@192 redis-6.0.8]# cd data/
[root@192 data]# ll
总用量 12
-rw-r--r-- 1 root root  121 10月 24 15:30 dump-6379.rdb
-rw-r--r-- 1 root root 3102 10月 24 15:30 redis-6379.log
-rw-r--r-- 1 root root 1447 10月 24 11:35 redis-6380.log
[root@192 data]# cat dump-6379.rdb 
REDIS0009dis-ver6.0.8edis-bitsctime_ed-mem

bgsave后台执行策略

使用指令bgsave会使用延迟执行save策略。

[root@192 redis-6.0.8]# redis-cli 
127.0.0.1:6379> set age 35
OK
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379>

bgsave执行的这个子进程不参与redis的数据读写,可以通过查看日志文件看到这个信息:

39800:M 24 Oct 2020 15:44:54.394 * Background saving started by pid 39915
39915:C 24 Oct 2020 15:44:54.397 * DB saved on disk
39915:C 24 Oct 2020 15:44:54.397 * RDB: 0 MB of memory used by copy-on-write
39800:M 24 Oct 2020 15:44:54.408 * Background saving terminated with success

条件save后台执行策略

限定时间限定条件的save持久化:满足限定时间内key的变化数量达到指定数量则进行持久化。命令为:

save second changes

second代表指定时间,changes代表key的变化数量,如果设置为:

save 100  10

100秒内有10个key变化则进行持久化,那么如果我在100秒到期的时候只有9个key变化,则重置时间,重新从上一次持久化后的key的变化数全量统计变化值【实际上也就是9个】,也就是剩余100秒只需再等待一个key变化就能进行持久化了。

配置添加

需要在配置文件进行配置:

port 6379
daemonize yes
logfile "redis-6379.log" 
dir /root/redis-6.0.8/data/
dbfilename dump-6379.rdb
rdbcompression yes
rdbchecksum yes
save 10 2

配置完成后进行下实验,首先重启后台进程:

[root@192 redis-6.0.8]# ps -ef |  grep redis-              
root      39800      1  1 15:37 ?        00:00:22 redis-server *:6379
root      40243  39523  0 16:05 pts/0    00:00:00 grep --color=auto redis-
[root@192 redis-6.0.8]# kill -s 9 39800
[root@192 redis-6.0.8]# ps -ef |  grep redis-
root      40246  39523  0 16:05 pts/0    00:00:00 grep --color=auto redis-
[root@192 redis-6.0.8]# redis-server config/redis-6379.conf

同时干掉快照文件:

然后进行实验,要记住两点,1,只有对key产生变化的才算【get不算,del和set都算】,2,同一个key的两次变化都算,因为不进行数据比对,redis不会记忆上一个变化的是什么。我们先操作一次:

127.0.0.1:6379> set name tmlhhhh
OK
127.0.0.1:6379> get name
"tmlhhhh"
127.0.0.1:6379> 
[root@192 redis-6.0.8]#

这里可以看到虽然是两条指令,但一条是get不算。我们可以看到还是没有dump文件产生:

接下来我们再操作一次:

[root@192 redis-6.0.8]# redis-cli  
127.0.0.1:6379> set age 25
OK
127.0.0.1:6379>

dump文件产生了,我们可以看到:

条件save执行原理

带有条件的save的工作原理如下:

需要注意的是:

  • save配置后台执行的是bgsave的操作,只是有一定的触发时间
  • second和change要设置成互补的,如果是相同的则没什么意义。例如如果我业务量特别大,每10秒更新1000条数据,我设置的key太小了没什么意义,一会儿一次dump写入,要爆炸,所以设置成save 1 100000,也就是1秒内变化的key数量不超过100000,就不需要写入dump了,反之,如果我业务量很小,每10秒更新1条数据,但是这条数据又很重要,那么我需要尽快持久化,所以设置成save 100 1,也就是100秒内,只要有一条变化就写入dump,实际情况往往是依据业务场景来的

以上就是RDB的优化方式。

RDB三种执行策略对比

以下是三种执行RDB方式的对比:

方式 save bgsave 条件save
读写 同步 异步 满足条件异步
阻塞客户端指令
额外内存
启动新进程
推荐使用度

其实说白了,又是一个空间换时间的例子。另外说几个特殊的RDB启动时机:

  • 进行全量复制时,首先需要有快照
  • 重启服务Redis时,可以执行RDB:debug reload
  • 关闭服务Redis的时候可以执行RDB:shutdown save

以上就是一些特殊的启动形式

RDB恢复文件

我们存储了快照,那么该如何验证快照能恢复回数据呢?我们先把进程杀掉,也就是把内存里的干掉,看能不能恢复回来。

[root@192 redis-6.0.8]# redis-cli -p 6379
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
"tmlloveguochengyu"
[root@192 redis-6.0.8]# ps -ef |  grep redis-              
root      39624      1  1 15:27 ?        00:00:09 redis-server *:6379
root      39782  39523  0 15:36 pts/0    00:00:00 grep --color=auto redis-
[root@192 redis-6.0.8]# kill -s 9 39624
[root@192 redis-6.0.8]# ps -ef |  grep redis-
root      39794  39523  0 15:37 pts/0    00:00:00 grep --color=auto redis-
[root@192 redis-6.0.8]# redis-server config/redis-6379.conf
[root@192 redis-6.0.8]# ps -ef |  grep redis-              
root      39800      1  0 15:37 ?        00:00:00 redis-server *:6379
root      39806  39523  0 15:37 pts/0    00:00:00 grep --color=auto redis-
[root@192 redis-6.0.8]# redis-cli
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> get name
"tmlloveguochengyu"

我们杀掉进程后重启服务端,发现数据还留存着,其实就是当我们重启服务端的时候Redis读取dump文件将数据恢复了。

RDB优缺点

优点

  • RDB存储效率高【能存更多】,RDB文件是紧凑的二进制文件,存储效率高,比较适合做冷备,灾备,全量复制的场景。RDB做会生成多个文件,每个文件都代表了某一个时刻的Redis完整的数据快照,RDB这种多个数据文件的方式,非常适合做冷备,因为大量的一个个的文件,可以每隔一定的时间,复制出来;可以将这种完整的数据文件发送到一些远程的云服务、分布式存储上进行安全的存储,以预定好的备份策略来定期备份Redis中的数据;
  • RDB恢复数据更快【能恢复更快】,直接基于RDB数据文件来重启和恢复Redis进程,更加快速:RDB就是一份数据文件,恢复的时候,直接加载到内存中即可;
  • **RDB对Redis的读写无影响,RDB对Redis【不影响Redis】对外提供的读写服务,影响非常小,可以让Redis保持高性能,因为Redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可;RDB每次写,都是直接写Redis内存,只是在一定的时候,才会将数据写入磁盘中

缺点

  • RDB无法做到实时持久化【可能会丢数据】,一般来说,RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦Redis进程宕机,那么会丢失最近5分钟的数据;这个问题,也是RDB最大的缺点,就是不适合做第一优先的恢复方案,如果你依赖RDB做第一优先恢复方案,会导致数据丢失的比较多;
  • RDB在fork子进程时消耗内存【有一些内存损耗】,RDB每次在fork子进程来执行RDB快照数据文件生成的时候,都会牺牲一些内存。
  • RDB基于快照,每次读写都是全量数据,数据量大时性能较低
  • RDB如果设置的dump读写时间不合适,大数据量下会有IO频繁的风险

以上就是RDB的优缺点,学习完AOF后,我们来一个整体的对比

AOF方案

AOF是独立日志的持久化策略,存储操作过程,存储格式复杂,关注点在数据的操作过程。我们依据RDB的缺点就能理解AOF的存在价值了,因为没有哪种策略是完美的,只有合适的:

  • RDB无法做到实时持久化【可能会丢数据】,一般来说,RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦Redis进程宕机,那么会丢失最近5分钟的数据;这个问题,也是RDB最大的缺点,就是不适合做第一优先的恢复方案,如果你依赖RDB做第一优先恢复方案,会导致数据丢失的比较多;
  • RDB在fork子进程时消耗内存【有一些内存损耗】,RDB每次在fork子进程来执行RDB快照数据文件生成的时候,都会牺牲一些内存。
  • RDB基于快照,每次读写都是全量数据,数据量大时性能较低
  • RDB如果设置的dump读写时间不合适,大数据量下会有IO频繁的风险

基于以上问题,我们看下AOF的实现。

  • 只记录部分数据,不记录全量数据
  • 只记录操作过程,不记录操作数据
  • 对所有操作均记录,降低丢失数据的可能性。

AOF是以独立日志的形式存在的方式记录每次执行的命令,重启时再执行AOF中记录的命令来达到恢复数据的目的,也就是改记录数据为记录日志,主要解决的就是RDB的非实时持久化的问题,现在已经是Redis持久化的主流方式,优先使用这个。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
存储 监控 负载均衡
保证Redis的高可用性是一个涉及多个层面的任务,主要包括数据持久化、复制与故障转移、集群化部署等方面
【5月更文挑战第15天】保证Redis高可用性涉及数据持久化、复制与故障转移、集群化及优化策略。RDB和AOF是数据持久化方法,哨兵模式确保故障自动恢复。Redis Cluster实现分布式部署,提高负载均衡和容错性。其他措施包括身份认证、多线程、数据压缩和监控报警,以增强安全性和稳定性。通过综合配置与监控,可确保Redis服务的高效、可靠运行。
208 2
|
2月前
|
存储 监控 NoSQL
Redis处理大量数据主要依赖于其内存存储结构、高效的数据结构和算法,以及一系列的优化策略
【5月更文挑战第15天】Redis处理大量数据依赖内存存储、高效数据结构和优化策略。选择合适的数据结构、利用批量操作减少网络开销、控制批量大小、使用Redis Cluster进行分布式存储、优化内存使用及监控调优是关键。通过这些方法,Redis能有效处理大量数据并保持高性能。
55 1
|
7天前
|
存储 NoSQL Redis
《面试官之你说我听》:简明的图解Redis RDB持久化、AOF持久化
《面试官之你说我听》:简明的图解Redis RDB持久化、AOF持久化
|
7天前
|
存储 NoSQL 安全
Redis系列学习文章分享---第十五篇(Redis最佳实践--设计优雅的key+合适的数据结构+持久化如何配置+慢查询问题解决)
Redis系列学习文章分享---第十五篇(Redis最佳实践--设计优雅的key+合适的数据结构+持久化如何配置+慢查询问题解决)
15 1
|
17天前
|
存储 缓存 NoSQL
Redis 缓存失效策略及其应用场景
Redis 缓存失效策略及其应用场景
21 1
|
26天前
|
存储 监控 NoSQL
Redis中的LRU淘汰策略深入解析
Redis的内存管理关键在于处理数据增长与有限内存的矛盾,LRU策略被广泛用于此。LRU基于“不常访问的数据未来访问可能性小”的假设,淘汰最近最少使用的数据。Redis通过双向链表实现,但并非严格LRU,而是采样算法以平衡性能和精度。用户可通过调整`maxmemory-samples`等参数优化。尽管LRU简单高效,但无法区分数据重要性和访问频率,可能误淘汰重要数据。合理设置参数、结合其他策略、监控调优是优化LRU使用的关键。
19 1
|
7天前
|
NoSQL API Redis
使用Redis Lua脚本实现高级限流策略
使用Redis Lua脚本实现高级限流策略
24 0
|
9天前
|
存储 缓存 JSON
Redis-持久化-淘汰机制-IO策略
Redis-持久化-淘汰机制-IO策略
|
10天前
|
存储 缓存 NoSQL
redis的过期淘汰策略
只能存储 20w 条数据,那肯定要保证redis存储的都是热点数据,即:被频繁访问到的数据;并且要保证Redis的内存能够存放20w数据,要计算出Redis内存的大小。
8 0
|
2月前
|
存储 缓存 NoSQL
Redis 缓存失效策略及其应用场景
Redis 缓存失效策略及其应用场景
56 1