架构设计系列(六):缓存

news/2025/2/26 6:30:56

一、概述

  在应用对外提供服务的时候其稳定性,性能会受到诸多因素的影响。缓存的作用是将频繁访问的数据缓存起来,避免资源重复消耗,提升系统服务的吞吐量。

二、缓存的应用场景

在这里插入图片描述

2.1 客户端

HTTP响应可以被浏览器缓存。我们第一次通过HTTP请求数据,它在HTTP报头中返回一个过期策略;我们再次请求数据,客户端应用程序首先尝试从浏览器缓存中检索数据。

2.2 CDN

CDN缓存静态web资源。客户端可以从附近的CDN节点检索数据。

2.3 负载均衡器

负载均衡器也可以缓存资源。

2.4 消息中间件

消息中间件用于削峰,在请求量大的场景下,引入消息中间件将请求消息缓存至中间件,待消费者消费处理。

2.5 应用服务本地缓存

这里是服务中的多层缓存。如果数据没有缓存在CPU缓存中,则服务将尝试从内存中检索数据。有时,该服务具有二级缓存,用于在磁盘上存储数据。

2.6 分布式缓存

像Redis这样的分布式缓存在内存中保存了多个服务的键值对。它提供了比数据库更好的读/写性能。

2.7 全文检索

我们有时需要使用全文搜索,如Elastic Search来进行文档搜索或日志搜索。数据的副本也会在搜索引擎中建立索引。

2.8 数据库

即使在数据库中,我们也有不同级别的缓存

  • WAL(Write Ahead Log)预写日志:在构建B树索引之前,先进行WAL。
  • Bufferpool:分配给缓存查询结果的内存区域。
  • 物化视图(Materialized View):预先计算查询结果并将其存储在数据库表中,可以提升查询性能。
  • 事务日志(Transaction Log):记录所有事务和数据库更新
  • Replication Log:用于记录数据库集群的复制状态

三、Redis

redis_30">3.1 redis的工作原理

在这里插入图片描述

  • Redis是一个基于RAM存储的。RAM读写速度比随机磁盘访问至少快1000倍。
  • Redis利用IO多路复用技术和单线程执行循环来提高执行效率。
  • Redis利用了高效的底层数据结构。

redis__35">3.2 redis 的使用场景

在这里插入图片描述
   以下列举的是常见的一些不单单作为缓存的应用场景:

  • Session:我们可以使用Redis在不同的服务之间共享用户会话数据。
  • Cache:我们可以使用Redis来缓存对象或页面,特别是对于热点数据。
  • 分布式锁:我们可以使用Redis字符串来获取分布式服务之间的锁。
  • 计数器:我们可以使用Redis记录文章的点赞数或阅读量。
  • 限流器:我们可以对某些用户ip应用速率限制。
  • 全局ID生成器:我们可以使用Redis 作为全局ID的生成。
  • 购物车:我们可以使用Redis Hash来表示实现购物车的功能。
  • 用户留存率:我们可以使用位图来表示用户每日登录并计算用户留存率。
  • 消息队列:使用Redis的List数据结构来实现简易化的消息队列。
  • 排名:我们可以使用ZSet对条目进行排序。

四、常用的缓存策略

设计大型系统通常需要仔细考虑缓存。下面是常用的五种缓存策略。
在这里插入图片描述

4.1 Cache-Aside 策略

流程

  • 当读取数据的时候,程序将会先去读取缓存,如果命中缓存则直接返回数据
  • 如果没有命中缓存则程序将去数据库查询数据,返回数据的同时也将缓存一份数据

总结

   Cache-Aside 策略的优点是实现简单,只有被请求的数据才会被缓存起来,减少一些不必要数据的缓存。 但程序需要管理其时效性及一致性,增加了系统的复杂度。
   该策略更多的使用在数据读取比较频繁,更新比较少的场景。

4.2 Read-Through 策略

流程

  • 程序只会读取缓存中的数据,如果命中缓存就直接返回数据。
  • 如果没有命中缓存缓存服务将会读取数据库数据加载进缓存并返回数据。

总结

   Read-Through 策略 应用程序将不与数据库进行交互,简化了读取流程,由缓存系统自己管理缓存提高了数据的一致性。但缓存的写入需要单独处理,需要与其他写策略结合使用。
   该策略适用于读写操作频繁的场景。

4.3 Write Through 策略

流程

  • 程序在接收到写入数据请求时,直接于缓存系统交互,写入缓存系统,然后缓存系统立即写入数据库。

总结

   Read-Through 策略保证了数据的一致性,读取时总是能够在缓存中获取到最新的数据。但是每次写操作都需要更新两处数据储存,写入性能低。由于经常更新缓存缓存的资源需求较高。
   该策略适用于数据一致性要求比较高或者写操作比较低,读操作比较高的操作。

4.4 Write Back 策略

流程

  • 程序在接收到写入数据请求时,直接于缓存系统交互,写入缓存系统,但不会立即写入数据库,而是等待触发条件(如缓存满了,或者到达一定的时间间隔)之后才会批量一次性写入数据库。

总结

   Write Back 策略 由于只更新缓存,所有对性能的提升显著,同时批量写入减少对数据的操作,减少资源的消耗。但存在数据不一致的风险,同时需要实现缓存的淘汰机制及批量会写数据的策略
   该策略适用于写操作频繁并且对数据一致性要求不高的场景。

4.5 Write Around 策略

流程

  • 程序在接收到写入数据请求时,直接写入数据库
  • 在读取时程序先读取缓存,如缓存不命中,则程序从数据库读取,并更新缓存

总结

   Write Around 策略避免了将不常用的数据写入缓存。但其首次读取数据都需要从数据库中加载,读取性能低,同时缓存命中率也低。
  该策略适用于写操作频繁但读操作不频繁的场景。


http://www.niftyadmin.cn/n/5868210.html

相关文章

终端指令后续和shell脚本编程

终端指令后续 1.磁盘指令 ​常用命令: n 新建分区d 删除分区p 显示分区表w 保存并退出q 不保存退出 ​注意事项: 操作前需卸载设备分区后需格式化才能使用 1.2 mkfs(格式化工具) ​功能:创建文件系统​格式&#…

嵌入式硬件篇---各种插头介绍

文章目录 前言1. XH插头(JST-XH系列)结构优点缺点适用场景 2. T插头(Tamiya Connector,田宫插头)结构优点缺点适用场景 3. DC插头(直流电源插头)结构优点缺点适用场景 4. XT插头(XT6…

34.Java 阻塞队列(阻塞队列架构、阻塞队列分类、阻塞队列核心方法)

一、阻塞队列概述 java.util.concurrent 包下的 BlockingQueue 接口很好的解决了多线程中如何高效安全传输数据的问题,可以使用这些高效并且线程安全的队列类快速搭建高质量的多线程程序 阻塞队列通过一个共享的队列,使得数据由队列的一端输入&#xff…

OpenCvSharp编译

前言 算法部分我们使用opencv4.10作为开发,那么我们在.net winform做UI界面开发时,需要进行相关调用。比较简单的方式是直接从NuGet中直接搜索OpencvSharp进行安装。OpecvSharp对Opencv进行了二次封装,在.net中可以快速操作相关对象和算子&am…

网络安全学习-WEB安全常见漏洞

注入类漏洞 SQL注入漏洞 定义 sql注入漏洞,就是将用户可控的数据拼接到了sql语句当中,一起提交到了数据库执行。 攻*击者通过注入语句,改变sql执行的逻辑,通过控制部分sql语句,攻击者可以查询到数据库钟任何自己需…

【Uniapp-Vue3】导入uni-id用户体系

在uniapp官网的uniCloud中下载uni-id用户体系 或者直接进入加载,下载地址:uni-id-pages - DCloud 插件市场 进入以后下载插件,打开HbuilderX 选中项目,点击确定 点击跳过 点击合并 右键uniCloud文件夹下的database文件夹&#x…

React进阶之React核心源码解析(三)

React核心源码解析 diff多节点比较diff两轮遍历比较第一轮比较第二轮比较Update 状态更新Concurrent Modediff 多节点比较diff isArray方法比较 节点更新// 更新前 <ul><li key="0" className="before">0<li><li key=

【二值图像与手动/自动阈值的详解】

二值图像与手动/自动阈值的详解 目录 二值图像与手动/自动阈值的详解一. 什么是二值图像&#xff1f;二. 二值图像的特点三. 二值图像的生成四.二值图像中的阈值作用及使用方法1. 阈值的概念2. 阈值的作用3. 阈值的类型4. 阈值的选择方法4. 阈值的使用方法5. 阈值的选择对结果的…