redis的持久化和缓存机制解读

 更新时间:2023年06月26日 10:09:38   作者:王啸tr1912  
这篇文章主要介绍了redis的持久化和缓存机制,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

redis的持久化和缓存机制

说道redis,我们可能都会知道了他是一个类似缓存的一个内存数据库,我们从未感知到它的存在是因为他很快,为什么非常快,是因为他的发展到应用很快,还有他的反应速度也是非常快的。

以前文章我们讲到了缓存以及非关系型数据库的由来,这篇我们来讲讲redis这种非关系型数据库用在什么地方,以及他的特色——持久化是怎么实现的。

一、redis的适用环境

首先作为一个nosql的key—value组成的数据库,它们能存储的数据结构必须是简单的,因为有关系的数据即使存储进去之后查询也是很困难的,并且对于海量的数据存储还是关系型数据库比较合适。

举一个把一般数据库数据存储到key-value中的例子:

student

学号

姓名

年龄

班级

001

小明

18

2

key

value

student:001:姓名

小明

student:001:年龄

18

student:001:班级

2

遵从规则为 

key  表名:主键值:列名value  列值

如果加上表关系的话还要复杂好几倍的。

那么什么样的数据适合存储在非关系型数据库中的呢?

1、关系不是很密切的的数据,比如用户信息,班级信息,评论数量等等。

2、量比较大的数据,如访问记录等

3、访问比较频繁的数据,如用户信息,访问数量,最新微博等

二、持久化

那么这么多,这么重要的数据都存储在内存中,如果突然断电,岂不是很糟糕,于是就有了数据的持久化机制,这个其实就是把内存中的数据存储到硬盘中,方便数据的持续存在,也可以减少断电造成的损失。

那么我们怎么持久化数据呢?多长时间进行一次持久化呢?

redis 支持两种持久化方式,一种是 Snapshotting(快照)也是默认方式,另一种是 Append-only file(缩写 aof)的方式。下面分别介绍:

Snapshotting

快照是默认的持久化方式。这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。

可以通过配置设置自动做快照持久化的方式。

我们可以配置 redis在 n 秒内如果超过 m 个 key 被修改就自动做快照,下面是默认的快照保存配置:

  • save 900 1 #900 秒内如果超过 1 个 key 被修改,则发起快照保存
  • save 300 10 #300 秒内容如超过 10 个 key 被修改,则发起快照保存
  • save 60 10000

下面介绍详细的快照保存过程:

1.redis 调用 fork,现在有了子进程和父进程。

2. 父进程继续处理 client 请求,子进程负责将内存内容写入到临时文件。由于 os 的实时复制机制( copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时 os 会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程地址空间内的数据是 fork时刻整个数据库的一个快照。

3.当子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件,然后子进程退出。client 也可以使用 save 或者 bgsave 命令通知 redis 做一次快照持久化。 save 操作是在主线程中保存快照的,由于 redis 是用一个主线程来处理所有 client 的请求,这种方式会阻塞所有client 请求。所以不推荐使用。另一点需要注意的是,每次快照持久化都是将内存数据完整写入到磁盘一次,并不是增量的只同步变更数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘 io 操作,可能会严重影响性能。

AOF方式

由于快照方式是在一定间隔时间做一次的,所以如果 redis 意外 down 掉的话,就会丢失最后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用 aof 持久化方式。

下面介绍 Append-only file:aof 比快照方式有更好的持久化性,是由于在使用 aof 持久化方式时,redis 会将每一个收到的写命令都通过 write 函数追加到文件中(默认是 appendonly.aof)。

当 redis 重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

当然由于 os 会在内核中缓存 write 做的修改,所以可能不是立即写到磁盘上。这样 aof 方式的持久化也还是有可能会丢失部分修改。不过我们可以通过配置文件告诉 redis 我们想要通过 fsync 函数强制 os 写入到磁盘的时机。

有三种方式如下(默认是:每秒 fsync 一次)

  • appendonly yes //启用 aof 持久化方式
  • # appendfsync always //收到写命令就立即写入磁盘,最慢,但是保证完全的持久化
  • appendfsync everysec //每秒钟写入磁盘一次,在性能和持久化方面做了很好的折中
  • # appendfsync no //完全依赖 os,性能最好,持久化没保证

aof 的方式也同时带来了另一个问题。持久化文件会变的越来越大。

例如我们调用 incr test命令 100 次,文件中必须保存全部的 100 条命令,其实有 99 条都是多余的。

因为要恢复数据库的状态其实文件中保存一条 set test 100 就够了。为了压缩 aof 的持久化文件。

redis 提供了 bgrewriteaof 命令。收到此命令 redis 将使用与快照类似的方式将内存中的数据以命令的方式保存到临时文件中,最后替换原来的文件。

redis缓存和两种持久化机制

redis的优点第一个就是速度快它是由c语言实现的基于内存读写的效率特别高第二个优点就是单线程模型所谓的单线程就是一个每个请求都会有一个新的线程来处理请求第三个优点就是使用的是非阻塞 i/o(i/o流)

不会再网上浪费时间第四个优点就是支持多数据类型存储  

两种持久化机制

rdb (Rrdis DataBase)默认的持久化方案是某个时间内的间隔执行指定次数的写操作则会将内存中的数据存入磁盘中   是以快照方式进行备份缓存    

rdb的优点:

1.适合大规模的数据恢复操作  

2.业务操作对数据的完整行和一致性要求不高  那么Rdb是最好的选择,

rdb的缺点:

1.就是数据的不完整行和一致性不高,可能是在最后一次备份是宕机,

2:备份时会占用内存因为redis在备份的时候会独立创建一个线程(此时的内存中有两份相同的数据);

Aof:默认不开启的持久化它的出现就是为了弥补RdB的不足(数据不一致)所以它采用的是日志的方式储存

优点:数据的完整性和一致性更高

缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring+Redis+RabbitMQ开发限流和秒杀项目功能

    Spring+Redis+RabbitMQ开发限流和秒杀项目功能

    本项目将通过整合Springboot和Redis以及Lua脚本来实现限流和秒杀的效果,将通过RabbitMQ消息队列来实现异步保存秒杀结果的效果,对Spring Redis RabbitMQ限流秒杀功能实现感兴趣的朋友一起看看吧
    2022-02-02
  • 使用注解实现Redis缓存功能

    使用注解实现Redis缓存功能

    这篇文章主要为大家详细介绍了使用注解实现Redis缓存功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • Redis集群增加节点与删除节点的方法详解

    Redis集群增加节点与删除节点的方法详解

    这篇文章主要给大家介绍了关于Redis集群增加节点与删除节点的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • Redis中HyperLogLog的使用详情

    Redis中HyperLogLog的使用详情

    这篇文章主要介绍了Redis中HyperLogLog的使用详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • 使用redis生成唯一编号及原理示例详解

    使用redis生成唯一编号及原理示例详解

    今天介绍下如何使用redis生成唯一的序列号,其实主要思想还是利用redis单线程的特性,可以保证操作的原子性,使读写同一个key时不会出现不同的数据,感兴趣的朋友跟随小编一起看看吧
    2021-09-09
  • 解决redis-cli报错Could not connect to Redis at 127.0.0.1:6379: Connection refused

    解决redis-cli报错Could not connect to Redis&

    这篇文章主要介绍了解决redis-cli报错Could not connect to Redis at 127.0.0.1:6379: Connection refused,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • 利用redis实现排行榜的小秘诀

    利用redis实现排行榜的小秘诀

    这篇文章主要给大家介绍了关于如何利用redis实现排行榜的小秘诀,文中通过示例代码介绍的非常详细,对大家学习或者使用redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • docker安装redis的完整步骤详解

    docker安装redis的完整步骤详解

    这篇文章主要介绍了docker安装redis的完整步骤,包括拉取镜像、设置配置文件、编写docker-compose.yml文件启动Redis以及测试Redis连接,文中通过图文及代码介绍的非常详细,需要的朋友可以参考下
    2025-03-03
  • Redis模拟延时队列实现日程提醒的方法

    Redis模拟延时队列实现日程提醒的方法

    文章介绍了如何使用Redis实现一个简单的延时任务队列,通过Redis的有序集合特性来存储和管理延时任务,通过定期检查集合中小于等于当前时间的任务并执行,可以实现延时任务的管理,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • redis客户端实现高可用读写分离的方式详解

    redis客户端实现高可用读写分离的方式详解

    基于sentienl 获取和动态感知 master、slaves节点信息的变化,我们的读写分离客户端就能具备高可用+动态扩容感知能力了,接下来通过本文给大家分享redis客户端实现高可用读写分离的方式,感兴趣的朋友一起看看吧
    2021-07-07

最新评论