前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >系统设计:缓存

系统设计:缓存

原创
作者头像
小诚信驿站
修改2021-09-03 15:00:46
2.7K0
修改2021-09-03 15:00:46
举报
文章被收录于专栏:技术一号位指南(小诚信驿站)

上文提到的负载平衡有助于在数量不断增加的服务器上横向扩展,但缓存将使您能够更好地利用现有资源,并使其他无法实现的产品需求变得可行。缓存利用了引用的局部性原则:最近请求的数据可能会再次被请求。它们几乎应用于计算的每一层:硬件、操作系统、web浏览器、web应用程序等等。缓存就像短期内存:它的空间有限,但通常比原始数据源快,并且包含最近访问的项。

缓存可以存在于体系结构中的所有级别,但通常位于最靠近前端的级别,在那里实现缓存可以快速返回数据,而不会对下游级别造成负担。

应用服务器缓存

将缓存直接放置在请求层节点上可以实现响应数据的本地存储。每次向服务发出请求时,节点都会快速返回本地缓存数据(如果存在)。如果不在缓存中,请求节点将从磁盘查询数据。一个请求层节点上的缓存也可以位于内存(非常快)和节点的本地磁盘上(比进入网络存储更快)。

如果将其扩展到多个节点,会发生什么情况?如果请求层扩展到多个节点,那么每个节点仍然有可能拥有自己的缓存。但是,如果负载平衡器在节点间随机分配请求,则相同的请求将转到不同的节点,从而增加缓存未命中。克服这一障碍的两个选择是全局缓存和分布式缓存。

内容分发网络( Content Distribution Network ->CDN)

CDN是一种缓存,用于为大量静态媒体提供服务的站点。在典型的CDN设置中,请求将首先向CDN请求一块静态介质;CDN将提供该内容,如果它在本地可用的话。如果不可用,CDN将在后端服务器上查询该文件,在本地缓存该文件,并将其提供给请求用户。

如果我们正在构建的系统还不足以拥有自己的CDN,那么我们可以通过在单独的服务器上为静态媒体提供服务来简化将来的转换

子域(例如static.yourservice.com)使用轻量级HTTP服务器,比如Nginx,然后将DNS从服务器切换到CDN。

缓存失效

虽然缓存非常棒,但它确实需要一些维护,以保持缓存与真实来源(例如数据库)保持一致。如果数据库中修改了数据,则在缓存中应失效;如果没有,这可能导致应用程序行为不一致。

解决这个问题称为缓存失效;主要采用三种方案:

Write-through cache (直写缓存/透写)

在这种方案下,数据同时写入缓存和相应的数据库。缓存的数据允许快速检索,而且,由于相同的数据被写入永久存储器,我们将在缓存和存储器之间拥有完全的数据一致性。此外,此方案还确保在发生崩溃、电源故障或其他系统中断时不会丢失任何东西。

尽管直写可以最大限度地降低数据丢失的风险,但是由于每次写操作都必须执行两次才能将成功返回给客户端,因此这种方案的缺点是写操作的延迟更高。

Write-around cache (绕写缓存)

这种技术类似于直写缓存(Write-through cache ),但数据直接写入永久存储器,绕过缓存。这可以减少缓存被随后不会被重新读取的写入操作淹没,但其缺点是,对最近写入的数据的读取请求将创建“缓存未命中”,并且必须从较慢的后端存储中读取,并经历更高的延迟。

Write-back cache (回写缓存)

在这种方案下,数据单独写入缓存,完成后立即向客户端确认。写信给永久储存是在规定的时间间隔或特定条件下进行的。对于写密集型应用程序,这会导致低延迟和高吞吐量,但是,在发生崩溃或其他不利事件时,这种速度会带来数据丢失的风险,因为写数据的唯一副本在缓存中。

cache-aside(旁路缓存)

发生在应用层,应用层保证缓存结果同DB的数据一致性,应用层来负责写入到数据库和整理缓存,缓存层则不必插手此事。

read-through

读取数据时,先尝试从缓存中取得,如果缓存中没有,那么再从数据库中读取,而后也将数据放入缓存中,以便下次读取。这个也是普遍使用的方案。因此也会带来缓存穿透、缓存雪崩、缓存击穿、缓存数据不一致等问题

refresh-ahead

简单的说就是在缓存数据过期前,能自动的刷新缓存数据。举个例子来说,某条数据在缓存中,过期时间是60秒。我们给他设置一个参数,比如是0.8,60x0.8=48秒,那么在前48秒访问该数据,就照正常的取法,直接返回缓存中的数据。当在48-60秒这个区间取数据时,缓存先将之前缓存的结果返回给外部应用程序,然后异步的再从数据库去更新缓存中的值,以尽可能的保证缓存的值是最新的。如果取数据的的时候超过了60秒,就安照read-through的方式。 Refresh-ahead是对未来数据的访问情形的估算,这一个在分布式锁,锁续期中有预估延长缓存时间的实践。

缓存淘汰策略

以下是一些最常见的缓存逐出策略:

1.先进先出(FIFO):缓存逐出首先访问的第一个块不考虑以前访问它的频率或次数。

2.后进先出(LIFO):缓存逐出最近首先访问的块,而不考虑以前访问的频率或次数。

3.最近最少使用(LRU):首先丢弃最近最少使用的项目。

4.最近使用(MRU):与LRU不同的是,首先丢弃最近使用的物品。

5.最少使用频率(LFU):统计需要某个项目的频率。最不常用的会先被丢弃。

6.随机替换(RR):随机选择一个候选项,并在必要时丢弃它以腾出空间。

参考资料

https://lethain.com/introduction-to-architecting-systems-for-scale/

https://en.wikipedia.org/wiki/Cache_(computing)

https://www.cnblogs.com/asis/p/cache-pattern.html

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 应用服务器缓存
  • 内容分发网络( Content Distribution Network ->CDN)
  • 缓存失效
    • Write-through cache (直写缓存/透写)
      • Write-around cache (绕写缓存)
        • Write-back cache (回写缓存)
          • cache-aside(旁路缓存)
            • read-through
              • refresh-ahead
              • 缓存淘汰策略
              • 参考资料
              相关产品与服务
              云数据库 Redis
              腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档