专栏首页小诚信驿站系统设计:缓存
原创

系统设计:缓存

上文提到的负载平衡有助于在数量不断增加的服务器上横向扩展,但缓存将使您能够更好地利用现有资源,并使其他无法实现的产品需求变得可行。缓存利用了引用的局部性原则:最近请求的数据可能会再次被请求。它们几乎应用于计算的每一层:硬件、操作系统、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

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

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 大型web系统数据缓存设计

    1. 前言 在高访问量的web系统中,缓存几乎是离不开的;但是一个适当、高效的缓存方案设计却并不容易;所以接下来将讨论一下应用系统缓存的设计方面应该注意哪些...

    腾讯大数据
  • 系统架构设计:进程缓存和缓存服务,如何抉择?

    我们所说的缓存分为进程内部缓存(系统内部缓存)和 缓存服务(如redis/memcache)。计算机服务从原来的单体结构,到多实例,到现在流行的微服务,缓存服务...

    java乐园
  • 分布式系统的缓存设计你真的会了吗?

    缓存系统一般设计简单,功能单一,所以Redis吞吐量能是MySQL几倍~几十倍,对于互联网读多写少的高并发场景已不可或缺。

    JavaEdge
  • 亿级系统的Redis缓存如何设计???

    缓存设计可谓老生常谈了,早些时候都是采用memcache,现在大家更多倾向使用redis,除了知晓常用的数据存储类型,结合业务场景有针对性选择,好像其他也没有什...

    用户7676729
  • 如何设计缓存系统:缓存穿透,缓存击穿,缓存雪崩解决方案分析

    来源:blog.csdn.net/zeb_perfect/article/details/54135506

    后端码匠
  • 设计缓存系统该注意的问题 顶

    分布式缓存对应于CPU的模型有如下的关系,我们知道,CPU跟内存的关系中间还有三级高速缓存L1,L2,L3.L1最靠近CPU内核,CPU在进行数据处理的时候一般...

    算法之名
  • 详谈分布式系统缓存的设计细节

    在分布式Web程序设计中,解决高并发以及内部解耦的关键技术离不开缓存和队列,而缓存角色类似计算机硬件中CPU的各级缓存。如今的业务规模稍大的互联网项目,即使在最...

    IT小白龙
  • 设计一个缓存系统该考虑哪些问题?

    设计一个缓存系统,不得不要考虑的问题就是:缓存穿透、缓存击穿与失效时的雪崩效应。

    Java旅途
  • linux系统中ssd当块设备缓存

    bcache 需要编译最新的内核,要求比较高,配置比较复杂,目前主要用于测试环境;

    力哥聊运维与云计算
  • 性能设计 - 缓存

    基本上来说,在分布式系统中最耗性能的地方就是最后端的数据库了。一般来说,只要小心维护好,数据库四种操作(select、update、insert 和 delet...

    JAVA日知录
  • 同程凤凰缓存系统基于Redis的设计与实践

    2012~2014年,我们的业务开始使用一种新的互联网销售模式——秒杀抢购,一时间,各个产品线开始纷纷加入进来,今天秒杀门票,明天秒杀酒店,等等。各种活动是轮番...

    程序员小王
  • Redis 缓存设计原则

    本文为作者原创,版权归作者雪飞鸿所有。 转载必须保留文章的完整性,且在页面明显位置处标明原文链接。

    雪飞鸿
  • Ehcache缓存设计原理

    纯Java开源缓存框架,配置简单、结构清晰、功能强大,是一个非常轻量级的缓存实现,Hibernate里面就集成了相关缓存功能。

    JavaEdge
  • Redis缓存设计原理

    Redis是一个远程内存数据库(非关系型数据库),性能强劲,具有复制特性以及解决问题而生的独一无二的数据模型

    JavaEdge
  • Ehcache缓存设计原理

    纯Java开源缓存框架,配置简单、结构清晰、功能强大,是一个非常轻量级的缓存实现,Hibernate里面就集成了相关缓存功能。

    JavaEdge
  • ​缓存的设计思想

    缓存在系统设计中不可缺少,实现了以空间换时间,提高了系统的性能和减少了系统的处理时间。

    暮雨
  • SDRAM图像缓存设计

    本文讲述下利用sdram缓存从摄像头处得到的数据,并将图像显示到显示屏上的工程架构。本文不涉及具体的代码讲解,只描述其中的实现思路。

    数字积木
  • kafka 存储系统设计原理

    写入银盘慢? 实际上使用恰当, 写入硬盘也很快,如7200转的机械硬盘, 线性写入的性能大概是600MB/s, 而随机写入的性能大概是 100K/s, 相差60...

    erili
  • 猿设计18——真电商之库存系统设计

    经过上一章的讨论相信你已经了解库存的一些最基本的实体有了一些了解。但是仅仅了解实体还是不够的,就销售层面的库存其实也比较复杂,需要和一些外部系统打交道,有一些典...

    山旮旯的胖子

扫码关注云+社区

领取腾讯云代金券