redis的两种持久化机制及底层原理实现

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
日志服务 SLS,月写入数据量 50GB 1个月
简介: redis的两种持久化机制及底层原理实现

redis的两种持久化机制目录

一、为什么redis要持久化

二、redis 两种持久化机制

三、redis持久化机制之快照持久化(snapshot)

1、特点

2、快照生成方式

(1)系统默认开启

(2)客户端快照方式之bgsave

(3)客户端快照方式之save

(4)shutdown指令,关闭redis服务

(5)修改快照文件的名字和生成位置

(6)快照持久化方式存在的问题:

四、redis持久化机制_AOF 只追加日志文件

1、aof持久化默认不开启

2、日志追加频率

(1)always 【谨慎使用】

(2)everysec 【推荐】

(3) no 【不推荐】

(4)开启日志之后效果图

五、AOF重写机制

1、redis数据持久化方式

2、使用AOF出现的问题

3、触发AOF重写机制

(1)手工Client触发

(2)配置Server自动触发

六、AOF重写原理

一、为什么redis要持久化

redis:开源的 内存型 键值型 nosql型数据库


数据库存储在内存中 Client操作的数据也是内存中 效率高 不安全【突发情况 数据丢失】


提供了一种机制:将存中的数据存储到磁盘中 持久化机制


image.png


二、redis 两种持久化机制

Redis官方提供了两种不同的持久化方法来将数据存储到硬盘里面分别是:


快照(Snapshot: [ˈsnæpʃɒt])持久化


AOF持久化 (Append Only File) 只追加日志文件


三、redis持久化机制之快照持久化(snapshot)

1、特点

这种方式可以将某一时刻的所有数据都写入硬盘中,当然这也是redis的默认开启持久化方式 ,保存的文件是以**.rdb** 形式结尾的文件因此这种方式也称之为RDB方式 。


image.png


其实就是类似于linux中的快照,保存当前redis的数据


image.png

2、快照生成方式

系统默认开启


客户端方式:bsave,save指令


shutdown指令


(1)系统默认开启

在redis-conf 中 save设置触发快照持久化的时机

#插入一个linux小知识点,给linxu下的vi显示序号
[root@localhost redis]#  vi  ~/.vimrc 
set hlsearch            "高亮度反白
set backspace=2         "可随时用退格键删除
set autoindent          "自劢缩排
set ruler               "可显示最后一行癿状态
set showmode            "左下角那一行癿状态
set nu                  "可以在每一行癿最前面显示行号啦!
set bg=dark             "显示丌同癿底色色调
syntax on               "迚行语法检验,颜色显示。

vi redis.conf

image.png


save 900 1 (15分钟内一次写操作) 默认使用bgsave命令

save 300 10 (5分钟10次写操作) 默认使用bgsave命令

save 60 10000 (1分钟内有10000次写操作) 默认使用bgsave命令


image.png


(2)客户端快照方式之bgsave

客户端方式: bgsave(bg相当于前端的bgcolor:背景颜色)

客户端可以使用BGSAVE命令来创建一个快照,当接收到客户端的BGSAVE命令时,redis会调用fork¹来创建一个子进程,然后子进程负责将快照写入磁盘中,而父进程则继续处理命令请求。


   名词解释: fork当一个进程创建子进程的时候,底层的操作系统会创建该进程的一个副本,在类unix系统中创建子进程的操作会进行优化:在刚开始的时候,父子进程共享相同内存,直到父进程或子进程对内存进行了写之后,对被写入的内存的共享才会结束服务


image.png


bgsave指令特点:创建子进程完成快照,初始和主进程使用相同的内存,client发出写操作后会再次分配内存


bgsave好处 :1、保证redis服务一直可用 2、完成快照效率高


image.png


(3)客户端快照方式之save

客户端还可以使用SAVE命令来创建一个快照,接收到SAVE命令的redis服务器在快照创建完毕之前将不再响应任何其他的命令



image.png

特点:不会创建子进程 由主进程完成快照


好处:创建快照效率高


缺陷:redis无法对外提供服务


image.png


(4)shutdown指令,关闭redis服务

shutdown指令,关闭redis服务,同时默认触发快照持久化,默认使用的是save指令


(5)修改快照文件的名字和生成位置

名字:dbfilename dump.rdb (253行)


位置:dir./ 表示启动redis服务命令的当前目录


image.png


(6)快照持久化方式存在的问题:

持久化需要有触发时机,如果在第一次触发后到第二次触发前发生 发生突发情况 期间的所有数据都会丢失


丢失不定量数据


四、redis持久化机制_AOF 只追加日志文件

image.png

快照持久化:将某个时间点的数据状态存储到一个rdb文件中


AOF持久化:将Client的所写命令存储到一个日志文件中


1、aof持久化默认不开启

在redis的默认配置中AOF持久化机制是没有开启的,需要在配置中开启


2、开启aof持久化


在redis的配置文件中进行配置 redis/redis.conf

#先安装vim,方便查找redis.conf中的文件位置

 yum install -y vim

appendonly yes 开启aof持久化


默认日志文件的名字:appendonly.aof


#先安装vim,方便查找redis.conf中的文件位置
  yum install -y vim

image.png


vim redis.conf 进入672行,将appendonly no改为yes,开启追加日志持久化

image.png


2、日志追加频率

always 每写一个命令追加一次日志文件


everysec 美妙追加一次日志文件


no 由操作系统决定


修改同步频率


修改appendfsync everysec|always|no 指定


image.png

(1)always 【谨慎使用】

说明: 每个redis写命令都要同步写入硬盘,严重降低redis速度


解释: 如果用户使用了always选项,那么每个redis写命令都会被写入硬盘,从而将发生系统崩溃时出现的数据丢失减到最少;遗憾的是,因为这种同步策略需要对硬盘进行大量的写入操作,所以redis处理命令的速度会受到硬盘性能的限制;


注意: 转盘式硬盘在这种频率下200左右个命令/s ; 固态硬盘(SSD) 几百万个命令/s; 1k ssd


警告: 使用SSD用户请谨慎使用always选项,这种模式不断写入少量数据的做法有可能会引发严重的写入放大问题,导致将固态硬盘的寿命从原来的几年降低为几个月。


**特点:保证数据的安全 **


决定:效率会降低


(2)everysec 【推荐】

说明:每秒执行一次同步显式的将多个写命令同步到磁盘


解释: 为了兼顾数据安全和写入性能,用户可以考虑使用everysec选项,让redis每秒一次的频率对AOF文件进行同步;redis每秒同步一次AOF文件时性能和不使用任何持久化特性时的性能相差无几,而通过每秒同步一次AOF文件,redis可以保证,即使系统崩溃,用户最多丢失一秒之内产生的数据。


特点:保证突发状况下最多丢失一秒内的数据


(3) no 【不推荐】

说明: 由操作系统决定何时同步


解释:最后使用no选项,将完全有操作系统决定什么时候同步AOF日志文件,这个选项不会对redis性能带来影响但是系统崩溃时,会丢失不定数量的数据,另外如果用户硬盘处理写入操作不够快的话,当缓冲区被等待写入硬盘数据填满时,redis会处于阻塞状态,并导致redis的处理命令请求的速度变慢。


特点:由操作系统决定,不推荐


(4)开启日志之后效果图


image.png

添加数据详情


image.png


五、AOF重写机制

1、redis数据持久化方式

快照 拍摄数据状态


aof 追加写命令


2、使用AOF出现的问题

写命令一直追加到AOF文件中 导致文件越来越大 问题:存储 加载


解决:进行AOF重写


AOF重写:压缩原有的AOF日志文件


3、触发AOF重写机制

(1)手工Client触发

bgrewriteraof指令

image.png



(2)配置Server自动触发


image.png

auto-aof-rewrite-percentage 100 后续AOF重写机触发时机 aof文件到达前一次文件的100%触发AOF重写
auto-aof-rewrite-min-size 64mb  第一次AOF重写机制触发时机,当AOF文件达到64MB时自动触发

image.png


默认的触发机制


image.png

第一次:64M—>44MB


第二次 88MB——》68MB


第三次:136MB——》116MB


后续重写机制触发的百分比不要太小 400


image.png

第一次:64M—>44MB


第二次 176MB——》156MB


第三次:624MB——》600MB


第四次:2400MB——》2000MB


六、AOF重写原理

注意:重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,替换原有的文件这点和快照有点类似。

image.png



# 重写流程
`- 1. redis调用fork ,现在有父子两个进程 子进程根据内存中的数据库状态快照,往临时文件中写入重建数据库状态的命令
- 2. 父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来。这样就能保证如果子进程重写失败的话并不会出问题。
- 3. 当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。然后父进程把缓存的写命令也写入到临时文件。
- 4. 现在父进程可以使用临时文件替换老的aof文件,并重命名,后面收到的写命令也开始往新的aof文件中追加。`

AOF重写机制原理总结

不会读取原有的AOF文件,fork子进程去拍摄快照去转换当前的数据,生成一个临时文件,主进程继续处理请求,追加原有文件,同时也会缓存新执行的命令,最后用临时文件+缓存命令 替换原有AOF文件 实现AOF重写


image.png



相关实践学习
基于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
相关文章
|
NoSQL Redis
Redis学习4:List数据类型、拓展操作、实现日志等
注意点:对存储空间的顺序进行分析!
Redis学习4:List数据类型、拓展操作、实现日志等
|
存储 NoSQL Redis
Redis学习3:hash类型操作、拓展操作、实现购物等
首先可以理解成一个redis里面有一个小的redis。同时要注意引入了一个field的名字。
Redis学习3:hash类型操作、拓展操作、实现购物等
|
缓存 NoSQL 安全
2021年你还不会Shiro?----10.使用redis实现Shiro的缓存
上一篇文章已经总结了使用ehCache来实现Shiro的缓存管理,步骤也很简单,引入依赖后,直接开启Realm的缓存管理器即可。如果使用Redis来实现缓存管理其实也是一样的,我们也是需要引入redis的依赖,然后开启缓存传入自定义的redis的缓存管理器就行。区别是我们需要为自定义的redis缓存管理器提供自定义的缓存管理类。这个缓存管理类中需要使用到redisTemplate模板,这个模板我们也是需要自己定义。
243 0
2021年你还不会Shiro?----10.使用redis实现Shiro的缓存
|
NoSQL Java 关系型数据库
浅谈Redis实现分布式锁
浅谈Redis实现分布式锁
|
缓存 移动开发 NoSQL
php结合redis实现高并发下的抢购、秒杀功能的实例
php结合redis实现高并发下的抢购、秒杀功能的实例
223 0
|
存储 NoSQL 关系型数据库
「Redis」事务实现机制
Redis事务实现机制
380 0
|
消息中间件 设计模式 NoSQL
异步结果通知实现——基于Redis实现,我这操作很可以
前段时间,我在内存中实现了一个简单异步通知框架。但由于没有持久化功能,应用重启就会导致数据丢失,且不支持分布式和集群。今天这篇笔记,引入了 Redis 来解决这些问题,以下是几点理由: 数据结构丰富,支持 List、Sorted Set 等 具有持久化功能,消息的可靠性能得到保证 高可用性,支持单机、主从、集群部署 项目中已使用,接入成本更低 基于 Redis 实现延时队列也有几种方法,展开详细讲讲。
|
NoSQL 前端开发 PHP
thinkphp+redis实现秒杀功能
thinkphp+redis实现秒杀功能
202 0
thinkphp+redis实现秒杀功能
|
存储 NoSQL 安全
分布式锁中-基于 Redis 的实现如何防重入
分布式锁中-基于 Redis 的实现如何防重入
213 0
分布式锁中-基于 Redis 的实现如何防重入
|
存储 消息中间件 缓存
分布式锁中-基于 Redis 的实现需避坑 - Jedis 篇
分布式锁中-基于 Redis 的实现需避坑 - Jedis 篇
295 0
分布式锁中-基于 Redis 的实现需避坑 - Jedis 篇