前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >后台开发必备:每个程序员都应掌握的缓存技术

后台开发必备:每个程序员都应掌握的缓存技术

作者头像
腾讯云开发者
发布2024-07-02 11:30:27
3630
发布2024-07-02 11:30:27
举报
本文介绍了后台开发中使用的缓存技术,如缓存策略、缓存类型,包括本地缓存和分布式缓存,还有缓存淘汰策略,以及缓存使用中的常见问题,如一致性问题、缓存雪崩、缓存穿透、缓存击穿。

缓存(Cache)是一种存储技术,可以存储数据,以便快速获取数据。缓存最重要的是两个特性:存储、快速获取。缓存的本质:「用空间换时间」,用快速存储的介质保存数据,以提升数据访问的速度。

在计算机的世界里,缓存被广泛应用于硬件(如 CPU 高速缓存、寄存器)和软件中(如浏览器缓存、CDN、应用程序中的缓存等)。

后台中的缓存

后台开发中,缓存的使用场景一般有:

  • 提升接口响应速度:缓存相比 IO 请求、数据库查询速度要快得多,适当使用缓存提升响应速度
  • 降低数据源服务的负载压力:将需要高并发读取的数据缓存起来,当相同请求进来时返回缓存数据,减轻数据源服务(如数据库、上游系统)的负载压力
  • 减少计算资源的浪费:将需要复杂且耗时计算的结果缓存起来,减少相同请求导致的重复计算资源浪费

01、缓存策略

缓存策略通常分为两种,通读缓存和旁路缓存。

1.1 通读(read-through)缓存

在使用通读缓存时,应用程序会尝试从缓存中获取数据。如果该数据已存在于缓存中,那么缓存会直接返回该数据。若缓存中并未包含所需数据,那么缓存会自行访问数据源来获取数据,并将获取的数据返回给应用程序,同时将这份数据保存在缓存中。如此一来,当应用程序下次需要同样的数据时,就能够直接从 read-through 缓存中获取,无需再次访问数据源。

通读缓存的应用有很多,比如 CDN:

CDN(Content Delivery Network)即内容分发网络,是一种分布式的网络架构。依赖于服务商提供的广泛分布于各地的 CDN 服务器,通过把数据分发并缓存到各地的 CDN 服务器上,当用户请求数据时,CDN 会匹配离用户距离最近的节点并返回缓存数据,以此来提高用户访问资源的速度。CDN 一般用来加速静态资源的传输,比如图片、CSS、HTML 等内容。而动态的内容,如搜索结果、单据信息等则不合适,这类数据需要应用服务器实时计算后才能返回。

腾讯云 CDN 具有海量资源储备、全球智能调度、一键接入、丰富功能等产品优势,欢迎企业及用户了解试用:https://cloud.tencent.com/product/cdn

配图来源:seobility

1.2 旁路(cache-aside)缓存

与通读缓存不同,旁路缓存不直接与数据源打交道。应用程序尝试从旁路缓存获取数据,如果数据不存在,则返回空。应用程序自行请求数据源获取数据,并写入旁路缓存。这样下次相同的请求到达时,应用程序从旁路缓存中则会获取到数据。

通读缓存和旁路缓存这两种策略,一般来说都会灵活应用、互相包含。比如通读缓存中,对数据的查询和写缓存,使用的就是旁路缓存策略。而该实现被整体封装起来,对外表现的则是通读缓存策略。

02、缓存类型

在后台服务中,缓存的类型可以分为本地缓存和分布式缓存。

2.1 本地缓存(local cache)

本地缓存,与应用程序的进程有相同的生命周期,存放于应用程序的堆空间(heap)中。

  • 优势: 使用简单;无外部依赖;读取速度快(无网络 IO 请求);
  • 缺点: 空间小:应用程序的服务器资源有限,所以本地缓存的空间小;分布式一致性问题:如果后台服务是分布式架构的,那么不同的服务实例之间的本地缓存可能会有差异;无法持久化:本地缓存会随着进程结束而被销毁,无法持久化。

2.2 分布式缓存(remote cache)

分布式缓存,也可理解为远端缓存。使用外部的缓存服务,独立部署,与应用程序解藕。

  • 优势: 空间充足:外部存储一般空间都很充足;无分布式一致性问题:不同的服务实例连接同一个缓存服务,不存在一致性问题;主流的分布式缓存,如 redis,支持数据持久化和恢复,当缓存服务挂了可以恢复数据。
  • 缺点: 引入外部依赖、需要部署和运维单独的缓存服务。

2.2.1 常见的缓存服务

Redis

  • 支持多种数据结构,如:list,set,zset,hash 等数据结构。
  • 支持数据的持久化和恢复。
  • 支持多种集群模式:主从复制、哨兵模式和 Cluster 模式,保证高可用、容灾恢复、易于扩展。
  • 能提供毫秒级别的响应速度。
  • Redis 6.0 引入了多线程 IO,之前是单线程模型。

Memcache

  • 主要支持简单的键值对存储。
  • 不支持持久化和恢复。
  • 集群:可以通过客户端分片实现分布式存储。
  • 多线程,非阻塞 IO 模式。
  • 能提供毫秒级别的响应速度。

选择 Redis 还是 Memcached 取决于具体的应用需求。如果需要一个轻量级、专注于缓存的解决方案,且不需要复杂的数据类型和持久化,Memcached 可能是更合适的选择。而如果应用需要利用丰富的数据类型、持久化以及构建高可用的分布式系统,Redis 将是更强大、更灵活的选择。

03、缓存淘汰策略

由于缓存的空间是有限的,如果缓慢的空间被使用完了,则需要淘汰旧的数据,腾出空间给新的数据使用。缓存淘汰常用的几种策略有如下几种。

3.1 FIFO(First In First Out)算法

FIFO 算法是最简单最好理解的,其策略是:先进先出,如果一个数据的写入时间越早,说明将来被访问的几率越低。因此 FIFO 算法优先淘汰最早写入的数据。

3.2 LRU(Least Recently Used)算法

LRU 算法,即最近最少使用算法。如果一个数据最近被访问了,那么将来被访问的几率越高。反之,如果一个数据很久都没有访问,那么将来被访问的几率越低。其淘汰策略就是:优先淘汰最久没有被使用到的数据。LRU 通常使用双向链表+哈希表来实现。

3.3 LFU(Least Frequently Used)算法

LFU 算法,即最少使用算法。如果一个数据被访问的次数越多,那么将来被访问的几率越高。反之,如果一个数据被访问的次数越少,那么将来被访问的几率越小。其淘汰策略就是:优先淘汰最少被使用的数据。LFU 算法可以使用小顶堆+哈希表来实现。

大部分本地缓存的三方库或缓存服务,都支持设置淘汰算法,无需自行实现。

04、缓存常见问题

4.1 缓存与数据源的一致性

缓存的数据是来自数据源的,当数据源被更新了,而缓存没有被更新,后台服务则会从缓存中取到脏数据,这就有数据脏读的问题。对于这个问题,主要的策略有两种。

4.1.1 过期失效

每个写入缓存中的数据,都设置一个合适的过期时间,在有效期内都返回缓存的数据。当缓存数据过期失效,则会回源到数据源,重新缓存最新的数据。这种情况会有数据脏读的问题,不过采用过期失效的数据,一般是更新不频繁的数据,比如用户信息、热门信息等,存在一定的数据延迟是可以接受的。

4.1.2 主动更新

当数据源的数据更新了,程序主动去更新缓存数据,保证缓存中的数据始终是最新的。这种策略,适合对数据的时效性要求很高的数据,比如库存、余额等等。主动更新的代价则是代码的复杂度增加,所有涉及数据更新的操作,都需要更新其缓存数据。

无论是过期失效还是主动更新,首先应该分析当前场景对数据的时效性要求是否很高?如不是,过期失效足矣。如果是,需要衡量主动更新的代价能否接受,比如代码复杂度增加。否则是否可以通过缩短失效时间而采取过期失效策略来折中处理。

4.2 缓存雪崩

缓存雪崩是指在同一时间点后台服务中的缓存大量过期失效,当服务的并发量很高时,大量的数据请求同时到达数据源服务(比如数据库或其他服务),引起数据源服务的瞬时负载增大,甚至崩溃。

引起缓存雪崩的原因一般有两种:

  • 一是大量的缓存 key 在同一时间失效
  • 二是缓存服务不可用,请求都被透传到数据库。

解决办法:

  • 设置合理的缓存失效时间:合理设置过期时间,分散缓存的失效时间,避免缓存在同一时间失效。
  • 保证缓存服务的高可用:使用独立的缓存服务,尽量使用缓存集群,保证缓存服务的高可用和容灾恢复。

4.3 缓存穿透

缓存穿透是指同一时间大量的空值请求到达后台服务,空值请求是指查询数据源后无数据的请求,由于数据源返回空数据,所以缓存层没有将空值保存,导致空值请求必然会穿透缓存层,透传到数据源。

引起缓存穿透的原因,一般有:

  • 未对请求参数进行合理的校验和拦截。
  • 被精心构造的恶意请求攻击。

解决办法:

  • 设置合理的参数校验:通过设置合理的校验规则,比如 id 范围、名称正则规则等,对不合理或空值请求的参数的进行过滤和拦截。
  • 缓存空值处理:即使数据源返回空值,也在缓存层将其保存起来。可能对其数值设置一些标记,比如 value=-1 等等,方便服务识别为空值。同时,也可以为空值的缓存设置一个较短的失效时间。

4.4 缓存击穿

缓存击穿是指某个热点数据的缓存失效了,然后同一时间有大量的请求访问该热点数据,由于缓存失效,这些请求同时被透传到数据源服务,导致数据源的负载增加,甚至崩溃。

引起缓存击穿的原因,一般是:热点数据的缓存失效时,高并发请求同时访问该数据。

解决办法:

  • 使用互斥锁或者分布式锁,对数据的回源操作进行上锁,保证同一时刻只有一个请求被透传到数据源服务。
  • 热点数据的缓存永不过期,由数据源主动更新缓存。
  • 热点数据预加载:在缓存数据将要过期时,由后台服务主动更新热点数据缓存,防止缓存失效。

05、总结

本文详细地介绍了后台开发中的缓存技术,希望能对你的日常工作有所帮助和启发。熟练掌握各种缓存策略和机制,解决缓存问题,对于程序员而言至关重要,可以在很大程度上提升后台开发的效率、稳定性和用户体验。

-End-

原创作者 | 唐国富

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云开发者 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01、缓存策略
  • 02、缓存类型
  • 03、缓存淘汰策略
  • 04、缓存常见问题
  • 05、总结
相关产品与服务
内容分发网络 CDN
内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档