小工具      在线工具  汉语词典  css  js  c++  java

Redis持久化机制

redis,redis,数据库,缓存 额外说明

收录于:40天前


前言

Redis是基于内存的非关系型K-V数据库,既然它是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了持久化,即把数据保存到磁盘。
在这里插入图片描述
如上图所示,Redis提供了关系数据库AOF两种持久化机制。RDB快照是一次全量备份,AOF日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而AOF日志记录的是内存数据修改的指令记录文本。AOF日志在长期的运行过程中会变得无比庞大,数据库重启时需要加载AOF日志进行指令重放,这个时间就会无比漫长,所以需要定制进行AOF重写,给AOF日志进行瘦身。


RDB (Redis DataBase)

在默认情况下,Redis 将内存数据库快照保存在名字为 dump.rdb二进制文件中。

开启自动保存

修改配置文件redis.conf文件通过save参数配置自动RDB持久化策略,规则:save N M , 在“ N 秒内数据集至少有 M 个改动”这一条件被满足时,自动保存一次数据集,例如:

save 60 1000 // 60 秒内至少有 1000 个改动
save 300 3000 // 300 秒内至少有 3000 个改动
  • 可以配置多个保存。如果任何一个save满足,就会触发RDB持久化操作。
  • 要关闭RDB,只需注释掉所有保存策略即可。

手动命令保存

还可以手动执行命令生成RDB快照,进入redis客户端执行命令savebgsave可以生成dump.rdb文件,每次命令执行都会将所有redis内存快照到一个新的rdb文件里,并覆盖原有rdb快照文件。

bgsave的写时复制(COW)机制

Redis 借助操作系统提供的写时复制技术(Copy-On-Write, COW),在生成快照的同时,依然可以正常处理写命令。简单来说,bgsave 子进程是由主线程 fork 生成的,可以共享主线程的所有内存数据。bgsave 子进程运行后,开始读取主线程的内存数据,并把它们写入 RDB 文件。此时,如果主线程对这些数据也都是读操作,那么,主线程和 bgsave 子进程相互不影响。但是,如果主线程要修改一块数据,那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave 子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。

save与bgsave对比

节省 背景保存
IO类型 同步 异步
是否阻止其他redis命令 是的 否(子进程执行和调用fork函数时会有短暂的阻塞)
复杂性 在) 在)
优势 不消耗额外的内存 不阻止客户端命令
缺点 阻止客户端命令 需要fork子进程,消耗内存

配置自动生成rdb文件的后台使用的是bgsave方法。

AOF(Append Only File)

快照功能并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化,将修订的每一条指令记录进文件appendonly.aof中(先写入os cache,每隔一段时间fsync到磁盘).

开启AOF

你可以通过修改配置文件redis.conf来打开 AOF 功能:

appendonly yes

AOF格式(resp协议)

例如,执行命令“set tiangang 666”,aof文件中会记录以下数据:

*3
$3
set
$8
tiangang
$3
666

每条命令以*星号开始, 后面的数字代表命令有多少个参数$号后面的数字代表这个参数 有几个字符

注意,如果执行带过期时间的set命令,aof文件里记录的是并不是执行的原始命令,而是记录key过期的时间戳
比如执行命令“set tiangang 888”,aof文件里会记录如下数据:

*3
$3
set
$8
tiangang
$3
888
*3
$9
PEXPIREAT
$8
tiangang
$13
1604249786301

AOF三种刷盘策略:

appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。
appendfsync everysec:每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据。
appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。

推荐(也是默认)的方法是每秒 fsync 一次。这种fsync策略平衡了速度和安全性。

AOF重写

AOF文件里可能有太多没用指令,所以AOF会定期根据内存的最新数据生成aof文件
例如,执行了如下几条命令:

127.0.0.1:6379> incr workerId
(integer) 1
127.0.0.1:6379> incr workerId
(integer) 2
127.0.0.1:6379> incr workerId
(integer) 3
127.0.0.1:6379> incr workerId
(integer) 4
127.0.0.1:6379> incr workerId
(integer) 5

重写后AOF文件里变成

*3
$3
SET
$2
workerId
$1
5

自动重写配置

下面两个配置可以控制AOF自动重写频率。

auto-aof-rewrite-min-size 64mb   //aof文件至少要达到64M才会自动重写,文件太小恢复速度本来就很快,重写的意义不大
auto-aof-rewrite-percentage 100  //aof文件自上一次重写后文件大小增长了100%则再次触发重写

手动命令重写

当然AOF还可以手动重写,进入redis客户端执行命令bgrewriteaof重写AOF

注意,AOF重写redis会fork一个子进程来做(类似于bgsave命令),这对redis的正常命令处理不会产生太大影响。

RDB 和 AOF 对比

关系数据库 AOF
启动优先级 低的 高的
体积 小的 大的
恢复速度 快的 慢的
数据安全 容易丢失数据 根据策略确定

Redis 4.0 混合持久化

重启 Redis 时,我们很少使用 RDB来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。
通过如下配置可以开启混合持久化(必须先开启aof):

aof-use-rdb-preamble yes   

如果开启了混合持久化,重写时AOF,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写在这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增加的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。
于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重启效率大幅得到提升。

混合持久化AOF文件结构如下
在这里插入图片描述

Redis数据备份策略

  1. 编写一个crontab定时调度脚本,每小时复制一次RDB或AOF的备份到一个目录,只保留最近48小时的备份。
  2. 每天在目录中保留当天的数据备份,也可以保留上个月的备份。
  3. 每次复制备份时,太旧的备份都会被删除。
  4. 每天晚上将当前机器的备份复制到其他机器上,防止机器损坏

. . .

相关推荐

额外说明

JAVA版蓝桥杯往届试卷-2016年蓝桥杯省赛-Java组

第1题——生日蜡烛 (1)题目描述 某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。 现在算起来,他一共吹熄了236根蜡烛。 请问,他从多少岁开始过生日party的? 输出格式:请填写他开始过生日party的年龄数。 (

额外说明

JVM GC日志分析

查看GC日志 第一种 package thread; public class JvmGcTest { public static void main(String[] args) { byte[] data = new b

额外说明

MySql Update修改(替换)字段包含的值,根据条件修改替换字段的部分值

背景: 由于数据迁移和域名变更,Mysql中存储的文件下载地址变更; 要替换某一个字段中的部分内容,可以用update 语句和REPLACE方法,结构如下: UPDATE 表名 SET 字段名= REPLACE( 需要替换值的字段名, '替换前关键字',

额外说明

设计模式——享元模式

设计模式——享元模式 享元模式,运用共享技术有效地支持大量细粒度的对象 //Flyweight类,它是所有具体共享类的超类或者接口,通过这个接口,Flyweight可以接受并作用于外部状态 abstract class Flyweig

额外说明

【腾讯云 Cloud Studio 实战训练营】基于Cloud Studio构建React完成点餐H5页面

前言 【腾讯云 Cloud Studio 实战训练营】基于Cloud Studio 构建React完成点餐H5页面 一、Cloud Studio介绍 1.1 Cloud Studio 是什么 1.2 相关链接 1.3 登录注册 二、实战练习 2.1 初始

额外说明

Spring 计划任务

我们在Java中可以通过Timer类来执行定时任务,在spring中,给我提供了更加便捷的计划任务。我们可以通过@EnableScheduling来开启计划任务,通过@Scheduled来定义一个计划任务。   我们先来看@Scheduled的源码 @T

额外说明

Jquery实现表格动态增加一行,删除一行(最简洁的代码实现)

最近做的项目中有一个需求就是要求在线填写表格内容时,不够的话可以动态添加一行,我这里用的jQuery来实现,下面是我项目截图展现: 当点击“添加输入框”按钮时,就会自动添加一行 下面我们来一下代码实现(把实际项目中的HTML代码简化了,其他功能可自己加)

额外说明

Java学习笔记2.1.1 Java基本语法 - Java代码基本格式

文章目录 零、本讲学习目标 一、Java基本语法格式 (一)简单说明 (二)案例演示 二、Java语句分类 (一)结构定义语句 1、简单说明 2、案例演示 (二)功能执行语句 1、简单说明 2、案例演示 三、Java大小写敏感 (一)简单说明 (二)案例

额外说明

包括edge,Chrome,火狐、百度,360等浏览器怎么全屏_如何在Microsoft Edge中启用和禁用全屏模式以及解决浏览器无法开启或关闭全屏的问题

文章目录 1. 引出问题 2. 解决问题 2.1 使用缩放菜单 2.2 Win + Shift + Enter窍门 2.3 最大化与全屏模式 2.4 以全屏模式观看网络视频 3. 重要总结 4. 解决无法开启或关闭全屏的问题 1. 引出问题 我们经常访问

额外说明

Go基础篇 - 初级(1) - 变量

变量 –1 变量声明方式 1)指定变量类型,声明若不赋值,使用默认值 func main(){ //定义变量 声明变量 var i int //给变量i 复制 i = 10 //使用变量 fmt.Println("i=",i); } 2

ads via 小工具