首页 > 数据库 >Redis 高可用之持久化

Redis 高可用之持久化

时间:2024-04-30 23:22:19浏览次数:21  
标签:AOF 异步 持久 可用 Redis 写入 RDB 快照 日志

Redis服务实例宕机后,其中的数据还能恢复吗?

是的,与其他内存数据库不同(如memcache没有持久化),redis还提供了数据持久化功能,并提供两种持久化方式:

  • AOF(append only file):逻辑文件,记录的是一条一条的更改命令。在进行数据恢复时,需要一条一条的重放日志,恢复速度较慢
  • RDB(read database):物理文件,把某一时刻内存中的数据写入到磁盘,类似于一个快照。在进行数据恢复时,直接将快照文件加载到内存中,恢复速度快

redis默认使用RDB的方式,异步的将数据写入到磁盘中。

AOF

AOF默认为关闭状态(appendonly no),需要手动开启(appendonly yes)。

# 开启aof
appendonly yes
# aof文件名
appendfilename "appendonly.aof"
# 持久化文件目录,aof+rdb
dir ./
# 进行数据恢复时,在 AOF 文件的开头追加 RDB 文件内容,加快数据恢复速度,减少AOF重放
aof-use-rdb-preamble yes

写入方式

在MySQL中,写日志的方式往往是写前日志(Write Ahead Log, WAL),即先写日志,再更新内存中的数据。Redis中不同的是,采用的写入方式为写后日志,即先更新内存中的数据,再写日志。

这是为什么呢?首先,在速度上,写后日志的速度快于写前日志,但写前日志可支持事务回滚、恢复等事务特性。而redis作为NoSQL更关注于速度,不支持事务回滚、恢复等,所以采用写后日志提供处理速度。

写入策略

我们知道AOF是在命令执行完后再写入日志,那么写入日志是同步写入还是异步写入呢?同步写入可以保证数据一致性,但是影响处理性能,有阻塞主线程的风险;异步写入速度最快,但是有数据不一致的风险(宕机,日志没写入磁盘)。其中的优劣需要根据实际应用去把握,为此,redis提供了三种写入策略:

  • always:立即同步写回,每个写命令执行完后,同步地将日志写回磁盘,速度慢、但能保证一致性
  • everysec:每秒同步写回,每个写命令执行完后,先把日志写到 AOF 文件的内存缓冲区,主线程每隔一秒把缓冲区中的内容写入磁盘,速度中等、宕机损失一秒内数据更改信息
  • no:异步写回,由操作系统控制,每个写命令执行完后,先把日志写到 AOF 文件的内存缓冲区,由操作系统决定何时将缓冲区内容写回磁盘,速度最快、宕机损失的数据也最多

Redis的默认策略是everysec

# appendfsync always
appendfsync everysec
# appendfsync no

AOF日志重写

随着执行的命令数量增加、写入的日志大小也同步增加。为了减小日志的大小,使用一个异步线程对AOF日志进行重写。重写原理是,合并多条更新命令为一条。例如对一个key进行了六次更新,保存了六条日志,重写后只保存最新的一条即可。相关配置如下

# 设置 AOF 重写的触发条件,指定 AOF 文件大小增长的百分比,例如从32mb增加到64mb
auto-aof-rewrite-percentage 100
# 设置 AOF 重写的触发条件,指定最小 AOF 文件大小
auto-aof-rewrite-min-size 64mb

RDB

RDB是将数据库某一时刻的数据当作一个快照文件写入到磁盘中,这就引出了一个问题,什么时候执行RDB?

执行策略

redis中相关的配置格式为save ,其中seconds表示时间范围,changes表示key的更改数量。save 300 100的意思是如果300s内,有至少100个key的更改,就执行一次RDB操作。

可以配置多个save,符合任一条配置都可以立即执行RDB,例如,默认的save配置有三个:

  • save 3600 1
  • save 300 100
  • save 60 10000
# 执行策略
save 300 100

# 快照文件名
dbfilename dump.rdb

# 持久化文件目录,aof+rdb
dir ./

# 校验rdb文件,默认yes
rdbchecksum yes

# 压缩rdb文件,默认yes
rdbcompression yes

# 子线程执行RDB失败后,则拒绝接受写请求,用以提醒用户RDB无法正常工作
# 默认为yes,在有监控运维时可设置为no
stop-writes-on-bgsave-error no

写入策略

假设当前redis中有2GB的数据,以什么方式将2GB的数据保存到磁盘上呢?

为了不阻塞主线程,自然只能使用子线程进行异步保存了。具体操作是主线程fork一个子线程,这个子线程共享主线程的内存,可以访问其中的数据。

异步保存?那岂不是可以加快RDB的执行频率了。

这也是不可取的,

  • 一是:磁盘的写入速率较慢,会增加磁盘压力
  • 二是:虽然保存快照是异步的,但是主线程fork子线程这个操作是同步的,并且内存数据越大,fork时间越长

异步保存快照文件时,内存中的数据还能进行更改吗?变了还能叫做快照吗?

能更改,但是快照还是那个快照,这一切通过写时复制(Copy-On-Write, COW)技术完成。

写时复制

子线程在保存快照文件时,从客户端传来了请求

  • 如果是读取请求,没有影响,主线程从内存中读取后返回
  • 如果是写请求,主线程在进行更改前,需要将值拷贝一个副本出来,供子线程使用

通过写时复制,可以保证在子线程异步保存快照文件时,不影响主线程处理客户端请求。

如何选择持久化方式?

redis中可以单独使用AOF和RDB,也可以一起使用,具体的配置需要根据实际应用进行选择。

在主从架构中,主库不进行持久化,在从库中进行持久化操作。

不需要持久化

可以在redis.conf中配置save "",表明不使用持久化

需要持久化,但可以忍受几分钟的数据丢失

使用默认的RDB配置即可

不能忍受长时间的数据丢失

使用AOF,并配置appendfsync everysec(要求高可配置为always),配合RDB一起使用,可以在确保数据一致性的基础上加快数据恢复速度。

标签:AOF,异步,持久,可用,Redis,写入,RDB,快照,日志
From: https://www.cnblogs.com/cd-along/p/18168873

相关文章

  • 【Redis】Redis的操作命令(五)——Redis 有序集合(sorted set)
    有序集合添加元素ZADDrunoobkey1redis有序集合移除元素ZRANGErunoobkey010WITHSCORES有序集合命令命令说明例子ZADDkeyscore1member1[score2member2]向有序集合添加一个或多个成员,或者更新已存在成员的分数 ZCARDkey获取有序集合的成员数 ......
  • 【Redis】Redis的操作命令(四)——Redis 集合(SET)
    Redis的SET是String类型的无序列表。添加无序列表语句:SADDsetDemoredis获取无序列表语句SMEMBERSsetDemoRedis集合命令如下:命令描述例子SADDkeymember1[member2]向集合添加一个或多个成员 SCARDkey获取集合的成员数 SDIFFkey1[key2]返回......
  • openGauss MOT复制和高可用
    MOT复制和高可用由于MOT集成到openGauss中,并且使用或支持其复制和高可用,因此,MOT原厂功能即支持同步复制和异步复制。openGaussgs_ctl工具用于可用性控制和openGauss实例操作。这包括gs_ctl切换、gs_ctl故障切换、gs_ctl构建等等。有关更多信息,请参见《工具与命令参考》。配......
  • openGauss MOT持久性
    MOT持久性持久性是指长期的数据保护(也称为磁盘持久化)。持久性意味着存储的数据不会遭受任何形式的退化或损坏,因此数据不会丢失或损坏。持久性可确保在有计划停机(例如维护)或计划外崩溃(例如电源故障)后数据和MOT引擎恢复到一致状态。内存存储是易失的,需要电力来维护所存储的信息。......
  • openGauss MOT持久性概念
    MOT持久性概念持久性是指长期的数据保护(也称为磁盘持久性)。持久性意味着存储的数据不会遭受任何形式的退化或破坏,因此数据不会丢失或损坏。持久性可确保在有计划停机(例如维护)或计划外崩溃(例如电源故障)后数据和MOT引擎恢复到一致状态。内存存储是易失的,需要电源来维护所存储的信......
  • Redis删除
    1.登录可以连接Redis的ECS实例,安装Redis客户端,详情请参见redis-cli连接。2.执行以下命令,删除模糊匹配到的Key。redis-cli-h[$Addr]-p[$port]-n[$db]-a[$Password]keys"[$Key]*"|xargs-r-t-n1redis-cli-h[$Addr]-p[$port]-n[$db]-a[$Password]delredis-c......
  • java代码运行出现DENIED Redis is running in protected mode because protected mode
    这个错误是因为开启了保护模式,导致出错。所以需要关闭redis的保护模式。编辑redis的redis.config  注释bind127.0.0.1 、修改protected-mode为no、修改 daemonize为no然后重启redis ......
  • cmd redis 设置密码
     cmdredis设置密码在Redis中设置密码,你需要修改Redis配置文件或者通过命令行设置。以下是通过命令行设置密码的方法:连接到Redis服务器。使用CONFIGSETrequirepassyourpassword命令来设置密码。例如,如果你想通过命令行设置密码为mysecretpassword,你可以这样做:1.re......
  • Redis中对数组的获取类型转换
    1#####Redis中对数组的获取类型转换23```java4//判断redis中键值key是否存在;5BooleancarWeizi_redis_service=redisService.hasKey("carWeizi_redis_service");6if(carWeizi_redis_service){7//获取对应的list数组传入时re......
  • 双token+redis(token无感刷新)
    为什么要使用双token+redis呢?单token+redis+自动续期不行吗?单token+redis的缺点:可能会出现用户正在操作的时候,token过期了,让用户重新登录的情况。单token+redis+自动续期的缺点:单token设置短期的话,虽然一直操作可以通过拦截器重置token过期时间让它续期,但是如果隔一会儿不操作......