前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis持久化、事物、读写模式、多级缓存

Redis持久化、事物、读写模式、多级缓存

作者头像
长乐坡头
修改2024-02-01 11:19:46
1350
修改2024-02-01 11:19:46
举报
文章被收录于专栏:时间&空间时间&空间

1、redis持久化

持久化就是把内存中的数据持久化到本地磁盘,防止服务器宕机了内存数据丢失。

Redis 提供两种持久化机制 RDB(默认) 和 AOF 机制,Redis4.0以后采用混合持久化,用 AOF 来保证数据不丢失,作为数据恢复的第一选择; 用 RDB 来做不同程度的冷备。

RDB:是Redis DataBase缩写快照

RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。

优点:

1)只有一个文件 dump.rdb,方便持久化;

2)容灾性好,一个文件可以保存到安全的磁盘。

3)性能最大化,fork 子进程来进行持久化写操作,让主进程继续处理命令,只存在毫秒级不响应请求。

4)相对于数据集大时,比 AOF 的启动效率更高。

缺点:

数据安全性低,RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。

AOF:持久化

AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。

优点:

1)数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录到 aof 文件中一次。

2)通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。

缺点:

1)AOF 文件比 RDB 文件大,且恢复速度慢。

2)数据集大的时候,比 rdb 启动效率低。

2、redis事务

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

Redis事务的概念

Redis 事务的本质是通过MULTI、EXEC、WATCH等一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。总结说:redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。

Redis的事务总是具有ACID中的一致性和隔离性,其他特性是不支持的。当服务器运行在AOF持久化模式下,并且appendfsync选项的值为always时,事务也具有耐久性。

Redis事务功能是通过MULTI、EXEC、DISCARD和WATCH 四个原语实现的。

事务命令:

MULTI:用于开启一个事务,它总是返回OK。MULTI执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中,当EXEC命令被调用时,所有队列中的命令才会被执行。

EXEC:执行所有事务块内的命令。返回事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值 nil 。

WATCH :是一个乐观锁,可以为 Redis 事务提供 check-and-set (CAS)行为。可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到EXEC命令。(秒杀场景)

DISCARD:调用该命令,客户端可以清空事务队列,并放弃执行事务,且客户端会从事务状态中退出。

UNWATCH:命令可以取消watch对所有key的监控。

3、redis失效策略

内存淘汰策略

1)全局的键空间选择性移除

noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。(字典库常用)

allkeys-lru:在键空间中,移除最近最少使用的key。(缓存常用)

allkeys-random:在键空间中,随机移除某个key。

2)设置过期时间的键空间选择性移除

volatile-lru:在设置了过期时间的键空间中,移除最近最少使用的key。

volatile-random:在设置了过期时间的键空间中,随机移除某个key。

volatile-ttl:在设置了过期时间的键空间中,有更早过期时间的key优先移除。

缓存失效策略

定时清除:针对每个设置过期时间的key都创建指定定时器

惰性清除:访问时判断,对内存不友好

定时扫描清除:定时100ms随机20个检查过期的字典,若存在25%以上则继续循环删除。

4、redis读写模式

CacheAside旁路缓存

写请求更新数据库后删除缓存数据。读请求不命中查询数据库,查询完成写入缓存

图片
图片

业务端处理所有数据访问细节,同时利用 Lazy 计算的思想,更新 DB 后,直接删除 cache 并通过 DB 更新,确保数据以 DB 结果为准,则可以大幅降低 cache 和 DB 中数据不一致的概率

如果没有专门的存储服务,同时是对数据一致性要求比较高的业务或者是缓存数据更新比较复杂的业务,适合使用 Cache Aside 模式。如微博发展初期,不少业务采用这种模式

代码语言:javascript
复制
// 延迟双删,用以保证最终一致性,防止小概率旧数据读请求在第一次删除后更新数据库public void write(String key,Object data){    redis.delKey(key);    db.updateData(data);    Thread.sleep(1000);    redis.delKey(key);}

高并发下保证绝对的一致,先删缓存再更新数据,需要用到内存队列做异步串行化。非高并发场景,先更新数据再删除缓存,延迟双删策略基本满足了

  • 先更新db后删除redis:删除redis失败则出现问题
  • 先删redis后更新db:删除redis瞬间,旧数据被回填redis
  • 先删redis后更新db休眠后删redis:同第二点,休眠后删除redis 可能宕机
  • java内部jvm队列:不适用分布式场景且降低并发

Read/Write Though(读写穿透)

先查询缓存中数据是否存在,如果存在则直接返回,如果不存在,则由缓存组件负责从数据库中同步加载数据。

图片
图片

先查询要写入的数据在缓存中是否已经存在,如果已经存在,则更新缓存中的数据,并且由缓存组件同步更新到数据库中。

图片
图片

用户读操作较多.相较于Cache aside而言更适合缓存一致的场景。使用简单屏蔽了底层数据库的操作,只是操作缓存。

场景:

微博 Feed 的 Outbox Vector(即用户最新微博列表)就采用这种模式。一些粉丝较少且不活跃的用户发表微博后,Vector 服务会首先查询 Vector Cache,如果 cache 中没有该用户的 Outbox 记录,则不写该用户的 cache 数据,直接更新 DB 后就返回,只有 cache 中存在才会通过 CAS 指令进行更新。

Write Behind Caching(异步缓存写入)

图片
图片

比如对一些计数业务,一条 Feed 被点赞 1万 次,如果更新 1万 次 DB 代价很大,而合并成一次请求直接加 1万,则是一个非常轻量的操作。但这种模型有个显著的缺点,即数据的一致性变差,甚至在一些极端场景下可能会丢失数据。

5、多级缓存

浏览器本地内存缓存:专题活动,一旦上线,在活动期间是不会随意变更的。

浏览器本地磁盘缓存:Logo缓存,大图片懒加载

服务端本地内存缓存:由于没有持久化,重启时必定会被穿透

服务端网络内存缓存:Redis等,针对穿透的情况下可以继续分层,必须保证数据库不被压垮

为什么不是使用服务器本地磁盘做缓存?

当系统处理大量磁盘 IO 操作的时候,由于 CPU 和内存的速度远高于磁盘,可能导致 CPU 耗费太多时间等待磁盘返回处理的结果。对于这部分 CPU 在 IO 上的开销,我们称为 iowait。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、redis持久化
  • 2、redis事务
  • 3、redis失效策略
  • 4、redis读写模式
  • 5、多级缓存
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档