一文读懂 Redis 缓存系统
本文介绍了redis缓存原理、详细解析了缓存模型、缓存一致性和缓存异常场景 。
尽管(关系型)数据库系统 (SQL) 带来了许多出色的属性,例如 ACID,但为了保持这些属性 , 数据库的性能在“ 3 高” 条件环境下下往往显得捉襟见肘、苍白无力。
为了解决这个问题,我们往往需要在应用层(即处理业务逻辑的后端代码)和存储层(即 SQL 数据库)之间增加一个缓存层 。该缓存层通常使用内存缓存来实现 , 毕竟 , 传统 SQL 数据库的性能瓶颈通常发生在二级存储(即硬盘)的 I/O 层面 。随着主内存 (RAM) 的价格在过去十年中下降,故将(至少部分)数据存储在主内存中以提高性能便是一种性价比较高的解决方案 。基于当前的技术发展现状,Redis 便成为当下一种较为流行的选择 。

文章插图
当然,大多数系统只将所谓的“热数据”存储在缓存层(即主内存)中 。基于帕累托原理(也称为 80/20 法则),对于大多数事件,大约 80% 的影响来自 20% 的原因 。为了节省成本,我们只需要将这 20% 存储在缓存层中 。为了识别“热数据”,我们可以指定驱逐策略(例如 LFU 或 LRU )来确定哪些数据将过期 。

文章插图
缓存概述缓存是一种“预热”技术 , 用于将经常访问的数据存储在临时存储器(称为缓存)中 , 以减少硬盘驱动器的读/写 。缓存无处不在 , 基于此技术可以大大地提高 Web 应用程序的性能 。
通常,在最初的单体架构模型,当用户向我们的服务发送一个消息请求时,Web 服务器首先会读取或写入数据库再返回响应 。在缓存的情况下,服务器首先检查缓存副本是否存在,如果存在则从缓存返回数据而不是询问数据库 。它节省了时间和数据库的计算工作量 。
下面简要介绍一下应用程序如何请求 Redis ,此处主要基于 Master-Slave-Sentinel 模式的集群,App 通过调用 Redis Client ,例如,Jedis、Lettuce 及 Redisson 等来与 Redis Sentinel 通信,当 Redis Master 切换至 Slave 时,Application 依旧能够正常工作,如下为详细的时序图:

文章插图
缓存模型在分布式系统中,基于 CAP 定理指导,根据业务需求和上下文选择这些策略,通常可将其划分为常规模式和 Cache-Aside 模式 。在开始之前,让我们通过刷新缓存的方式来了解常用的缓存模式,具体如下所 示:

文章插图
写模型【一文读懂 Redis 缓存系统】1、Write Through:即“直写” 。此模型为同步写入数据库后再缓存 。这是安全的,因为它首先写入数据库,但比后写慢 。与写无效相比,它为先写后读场景提供了更好的性能 。在这种写入策略中,数据首先写入缓存,然后写入数据库 。缓存与数据库串联,写入总是通过缓存到主数据库 。

文章插图
直写模式的算法是:
1)对于不可变操作(读?。??
此策略不处理不可变操作 。它应该与通读模式相结合 。
2)对于可变操作(创建、更新、删除):
客户端只需要在 Redis 中创建、更新或删除条目 。缓存层必须以原子方式将此更改同步到 MySQL 。
直写模式的缺点也很明显 。首先,许多缓存层本身并不支持这一点 。其次,Redis 是缓存而不是 RDBMS 。它的设计并非具有弹性 。因此 , 更改在复制到 MySQL 之前可能会丢失 。即使 Redis 现在已经支持 RDB 和 AOF 等持久化技术 , 但仍然不推荐这种方式 。
就其本身而言 , 直写缓存似乎没有太大作用 , 实际上,它们会引入额外的写入延迟,因为数据先写入缓存,然后再写入主数据库 。但是当与通读缓存配对时,我们可以获得通读的所有好处 , 并且我们还可以获得数据一致性保证 , 使我们免于使用缓存失效技术 。
DynamoDB Accelerator (DAX) 是读取/写入缓存的一个很好的例子 。它与 DynamoDB 和应用程序内联 。可以通过 DAX 对 DynamoDB 进行读取和写入 。
2、Write Behind:即“后写或回写” 。基于此策略 , 应用程序将数据写入缓存 , 缓存会立即确认,并在延迟一段时间后将数据写回数据库。这对于写入速度非常快,如果将同一键上的多个写入合并为一次对数据库的写入,则速度会更快 。但是数据库长时间与缓存不一致,如果在数据刷新到数据库之前进程崩溃,可能会丢失数据 。RAID 卡是这种模式的一个很好的例子,为了避免数据丢失 , 通常需要 RAID 卡上的电池备份单元将数据保存在缓存中,但尚未登陆到磁盘 。
推荐阅读
- 一文读懂 Transformer 神经网络模型
- Redis Stream 数据结构实现原理真的很强
- 一文学会Linux内核的编译和调试
- 一文带你了解Docker与Containerd的区别
- 面试为啥都问Redis缓存?赶紧补一下
- 一台服务器上部署 Redis 伪集群
- 为什么创建 Redis 集群时会自动错开主从节点?
- 王者荣耀的段位排行榜是通过Redis实现的?
- Redis断连该如何抢救?
- 一文搞懂Redis架构演化之路