热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

分布式系统关注点——360°全方位解读「缓存」

如果这是第二次看到我的文章,欢迎文末扫码订阅我个人的公众号(跨界架构师)哟~  本文长度为3578字,建议阅读10分钟。坚持原创,每

如果这是第二次看到我的文章,欢迎文末扫码订阅我个人的公众号(跨界架构师)哟~  

本文长度为3578字,建议阅读10分钟。

坚持原创,每一篇都是用心之作~

 

此前的「伸缩性」章节结束了,此文是「高性能」章节的第一篇。

 

只要是位正儿八经的程序员自然知道「缓存」是什么,甚至我司的很多做运营的×××姐现在和程序员小哥哥的交流中都时不时冒出「缓存」字眼,让人压力山大分布式系统关注点——360°全方位解读「缓存」。(本文讨论的「缓存」皆指的是软件层面运用的缓存

 

大家都知道的一点是,缓存可以让原本打开很慢的页面,变得能“秒开”。你平时访问的APP、网站几乎都有涉及到缓存的运用。

 

那么,缓存除了能加速数据的访问之外,还有什么作用呢?

 

另外,任何事物都有两面性,我们如何才能将缓存的优点发挥得淋淋尽致,同时避免掉到它的弊端中呢?

 

Z哥今天想分享给你的就是我对缓存的理解和运用的思路,希望对你有所启发。

 

 

「缓存」能做什么?

正如前面所说,大家最普遍的理解就是当我们遇到某个页面打开很慢的时候,会想到引入缓存,这样页面打开就快了。

 

其实快和慢都是相对的,从技术角度来说,缓存之所以快是因为缓存是基于内存去建立的,而内存的读写速度比硬盘快X倍,所以用内存来代替硬盘作为读写的介质自然能大大提高访问数据的速度。

 

这个过程大致是这样的,通过在内存中存储访被问过的数据供后续访问时使用,以此来达到提速的效果

 

分布式系统关注点——360°全方位解读「缓存」

 

 

其实除此之外,缓存还有另外2个重要的运用方式,「预读取」和「延迟写」。

 

 

预读取

预读取就是预先读取将要载入的数据,也可以称作「缓存预热」。就是在系统对外提供服务之前,先将硬盘中的一部分数据加载到内存中,然后再对外提供服务

 

分布式系统关注点——360°全方位解读「缓存」

 

为什么要这样做呢?因为有些系统一旦启动就要面临上千上万的请求进来(在一些toC的项目尤其如此),如果直接让这些请求打到数据库上,非常大的可能是数据库压力暴增,直接被干趴,无法正常响应。

 

为了缓解这个问题,需要通过「预读取」来解决。

 

可能你会问,哪怕用了缓存还是扛不住呢?那就是做横向扩展+负载均衡的时候到了。(可以点击文末链接阅读之前的《弹性架构》系列分布式系统关注点——360°全方位解读「缓存」

 

 

如果说「预读取」是在「数据出口」加了一道前置的缓冲区的话,那么顾名思义,下面要说的「延迟写」就是在「数据入口」后面加了一道后置的缓冲区。

 

 

延迟写

你可能知道,数据库的写入速度是慢于读取速度的,因为写入的时候有一系列的保证数据准确性的机制。

 

所以,如果想提升写入速度的话,要么做分库分表,要么就是通过缓存来进行一道缓冲,再一次性批量写到磁盘,以此来提速。

 

题外话:由于分库分表对跨表操作以及多条件组合查询的副作用巨大,所以引入它的复杂度远大于引入缓存,我们应当优先考虑引入缓存的方案。

 

 

那么,通过缓存机制来加速“写”的过程就可以称作「延迟写」。就是预先将需要写入到磁盘或者数据库的数据,先暂时写入到内存,然后就返回成功。再定时将内存中的数据批量写入到磁盘

 

分布式系统关注点——360°全方位解读「缓存」

 

可能你会想,写到内存就认为成功,万一中途出现意外、断电、停机等导致程序异常终止的情况,数据不就丢了吗? 

 

是的。所以,「延迟写」一般仅用于对数据完整性要求不是那么苛刻的场景。比如点赞数啊、参与用户数啊等等,可以大大缓解对数据库频繁修改所带来的压力。

 

其实在我们熟知的分布式缓存Redis中,其默认运用的持久化机制——RDB,也是这样的思路。

 

 

在一个成熟的系统中,能够运用到缓存的地方其实并不是一处。下面Z哥就来帮你梳理一下我们在哪些地方可以“加缓存”。

 

 

哪里可以加「缓存」?

在说哪里可以加缓存之前我们先搞清楚一个事情,我们要缓存什么?也就是符合什么特点的数据才需要加缓存?毕竟加缓存是一个额外的成本投入,得物有所值。

 

一般来说你可以用这两个标准来判断:热点被高频访问,如几十次/秒以上)数据、静态(很少变化,读远大于写,如几天变更一次)数据

 

接下去就可以替它们找到合适的地方加缓存了。

 

 

缓存的本质是一个“防御性”的机制,而系统之间的数据流转是一个有序的过程。所以,选择在哪里加缓存就相当于选择在一条马路的哪个位置设路障。在这个路障之后的道路都能受到保护,不被车流碾压。

 

那么在以终端用户为起点,系统所用的数据库为终点的这条道路上可以作为缓存设立点的位置大致有以下这些。

 

分布式系统关注点——360°全方位解读「缓存」

 

每个设立点可以挡掉一些流量,最终形成一个漏斗状的拦截效果,以此保护最后面的系统以及最终的数据库。

 

分布式系统关注点——360°全方位解读「缓存」

 

下面Z哥来简要描述下每一个的运用场景以及需要注意的点。

 

 

浏览器缓存

这是离用户最近的可以作为缓存的地方,而且借助的是用户的“资源”(缓存的数据在用户的终端设备上),性价比可谓最好,让用户帮你分担压力分布式系统关注点——360°全方位解读「缓存」

 

分布式系统关注点——360°全方位解读「缓存」

 

当你打开浏览器的开发者工具,看到from cache或者from memory cache、from disk cache的时候,就意味着这些数据已经被缓存在了用户的终端设备上了(没网的时候也能访问到一部分内容就是这个原因)。

 

这个过程是浏览器替我们完成的,一般用于缓存图片、js、css这些。我们可以通过Http消息头中的Cache-Control来控制它,具体细节这里就不展开了。

 

js里的全局变量、以及COOKIE等运用也属于该范畴。

 

浏览器缓存是在于用户侧的缓存点,所以我们对其的掌控力就差很多,在没有发起新请求的情况下,你无法主动去更新数据。

 

 

CDN缓存

提供CDN服务的服务商,在全国甚至是全球部署着大量的服务器节点(可以叫做「边缘服务器」)。

 

那么将数据分发到这些遍布各地服务器上作为缓存,让用户访问就近的服务器上的缓存数据,就可以起到压力分摊和加速效果。这在ToC类型的系统上运用,效果格外显著。

 

但是需要注意的是,由于节点众多,更新缓存数据比较缓慢,一般至少是分钟级别。所以一般仅适用于不经常变动的静态数据。

 

题外话:解决方式也是有的,就是在url后面带个自增数或者唯一标示,如?v=1001。因为不同的url会被视作“新”的数据和文件,被重新create出来。



网关(代理)缓存

到这里做缓存就是在你自己的地盘了。很多时候我们会在源站前面架一层网关(或者说反向代理、正向代理),为的是做一些安全机制或者统一分流策略的入口。

 

分布式系统关注点——360°全方位解读「缓存」

 

同时这里也是做缓存的一个好场所。毕竟网关是“业务无关性”的,它能够拦下来的请求,对背后的源站也是很大的受益,减少了大量的CPU运算。

 

常用的网关(代理)缓存有Varnish,Squid,Ngnix。一般情况下,简单的缓存运用场景,用nginx即可,因为大部分时候我们会用它来做负载均衡,能少引入一个技术就少一份复杂度嘛。如果是大量的小文件可以使用Varnish,而Squid则相对大而全,运用成本也更高一些。

 

 

进程内缓存

一个请求能走到这里说明他是“业务相关”的,需要经过业务逻辑的运算。

 

也正因为如此,从这里开始对缓存的引入成本比前面3种大大增加,因为对缓存与数据库之间的「数据一致性」要求更高了。

 

 

可能我们大多数程序员第一次刻意使用缓存的场景就是这个时候分布式系统关注点——360°全方位解读「缓存」。进程内和进程外的缓存运用中有很多的细节需要注意,这些也是我们后续文章的内容,所以我们后续再详聊。

 

 

进程外缓存

这个大家也熟悉,就是redis、memcached之类,甚至也可以自己单独写一个程序来专门存放缓存数据,供其他程序远程调用。

 

同样,这里的细节我们后续再聊,这里先多说几句关于redis和memcached该怎么选择的建议。

 

对资源(cpu、内存等)利用率格外重视的话可以使用Memcached,但程序在使用的时候需要容忍可能发生的数据丢失,因为是纯内存的机制。如果无法容忍这点,并且对资源利用率也比较豪放的话可以使用redis。而且redis的数据库结构更多,Memcached只有key value,更像是一个nosql存储。

 

 

数据库缓存

数据库本身自带缓存模块的,否则也不会叫它内存杀手,基本上你给多少内存就能吃多少。

 

数据库缓存是数据库的内部机制,我们这里就不深入下去了。一般都会给出设置缓存空间大小的配置来让你进行干预。

 

 

最后,其实磁盘本身也有缓存。所以你会发现,为了让数据能够平稳的写到物理磁盘中真的是一波三折,不知道什么时候可以有“快”到不需要程序来考虑缓存的磁盘出现来拯救我们程序员呢分布式系统关注点——360°全方位解读「缓存」

 

 

「缓存」是Silver bullet吗?

可能你会想缓存那么好,那么应该×××,只要慢就上缓存来解决?

 

一个事物看上去再好,也有它负面的一面。缓存也有一系列的副作用需要考虑。除了上面提到的「缓存更新」和「缓存与数据的一致性」问题,还有诸如:

  1. 缓存雪崩

  2. 缓存穿透

  3. 缓存并发

  4. 缓存无底洞

  5. 缓存淘汰

  6. ...

等等问题,这些Z哥会在接下去的文章中和你一起深入剖析。

 

想第一时间了解这些的可以「关注」Z哥一波~

 

 

总结

好了,我们总结一下。

 

这次呢,Z哥先向你介绍了运用缓存的三种思路。

 

然后梳理了在一个完整的系统中可以设立缓存的几个位置,并且分享了关于浏览器缓存、CDN缓存、网关(代理)缓存的一些使用经验。

 

希望对你有所启发。

 

 

后续的文章我将着重深入「进程内缓存」和「进程外缓存」的最佳实践,等我再次出现分布式系统关注点——360°全方位解读「缓存」

 

 

 


 

相关文章:

  • 分布式系统关注点——仅需这一篇,吃透「负载均衡」妥妥的

  • 分布式系统关注点——如何去实施「负载均衡」?

  • 分布式系统关注点——做了「负载均衡」就可以随便加机器了吗?

  • 分布式系统关注点——「无状态」详解

  • 分布式系统关注点——「高内聚低耦合」详解

  • 分布式系统关注点——弹性架构

 


 

作者:Zachary

出处:https://www.cnblogs.com/Zachary-Fan/p/cache.html

 

如果你喜欢这篇文章,可以点一下左下角的「大拇指」。

 

这样可以给我一点反馈。: )

 

谢谢你的举手之劳。

 

▶关于作者:张帆(Zachary,个人微信号:Zachary-ZF)。坚持用心打磨每一篇高质量原创。欢迎扫描下方的二维码~。

定期发表原创内容:架构设计丨分布式系统丨产品丨运营丨一些思考。

 

如果你是初级程序员,想提升但不知道如何下手。又或者做程序员多年,陷入了一些瓶颈想拓宽一下视野。欢迎关注我的公众号「跨界架构师」,回复「技术」,送你一份我长期收集和整理的思维导图。

如果你是运营,面对不断变化的市场束手无策。又或者想了解主流的运营策略,以丰富自己的“仓库”。欢迎关注我的公众号「跨界架构师」,回复「运营」,送你一份我长期收集和整理的思维导图。

分布式系统关注点——360°全方位解读「缓存」


推荐阅读
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • 深入解析Spring Cloud微服务架构与分布式系统实战
    本文详细介绍了Spring Cloud在微服务架构和分布式系统中的应用,结合实际案例和最新技术,帮助读者全面掌握微服务的实现与优化。 ... [详细]
  • Spring Cloud学习指南:深入理解微服务架构
    本文介绍了微服务架构的基本概念及其在Spring Cloud中的实现。讨论了微服务架构的主要优势,如简化开发和维护、快速启动、灵活的技术栈选择以及按需扩展的能力。同时,也探讨了微服务架构面临的挑战,包括较高的运维要求、分布式系统的复杂性、接口调整的成本等问题。最后,文章提出了实施微服务时应遵循的设计原则。 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 本文将详细介绍如何在ThinkPHP6框架中实现多数据库的部署,包括读写分离的策略,以及如何通过负载均衡和MySQL同步技术优化数据库性能。 ... [详细]
  • 前言无论是对于刚入行工作还是已经工作几年的java开发者来说,面试求职始终是你需要直面的一件事情。首先梳理自己的知识体系,针对性准备,会有事半功倍的效果。我们往往会把重点放在技术上 ... [详细]
  • 本文探讨了大型服务端开发过程中常见的几个误区,包括异步任务处理不当、日志同步模式使用、网络操作未设置超时、缓存命中率及响应时间未统计、单一缓存模式、分布式缓存加锁不当以及团队管理上的误区,旨在帮助开发者避免这些常见错误。 ... [详细]
  • 全能终端工具推荐:高效、免费、易用
    介绍一款备受好评的全能型终端工具——MobaXterm,它不仅功能强大,而且完全免费,适合各类用户使用。 ... [详细]
  • Java项目分层架构设计与实践
    本文探讨了Java项目中应用分层的最佳实践,不仅介绍了常见的三层架构(Controller、Service、DAO),还深入分析了各层的职责划分及优化建议。通过合理的分层设计,可以提高代码的可维护性、扩展性和团队协作效率。 ... [详细]
  • 并发编程 12—— 任务取消与关闭 之 shutdownNow 的局限性
    Java并发编程实践目录并发编程01——ThreadLocal并发编程02——ConcurrentHashMap并发编程03——阻塞队列和生产者-消费者模式并发编程04——闭锁Co ... [详细]
  • 优化SQL Server批量数据插入存储过程的实现
    本文介绍了一种改进的SQL Server存储过程,用于生成批量插入语句。该方法不仅提高了性能,还支持单行和多行模式,适用于SQL Server 2005及以上版本。 ... [详细]
  • 本文探讨了2019年前端技术的发展趋势,包括工具化、配置化和泛前端化等方面,并提供了详细的学习路线和职业规划建议。 ... [详细]
  • 字节跳动夏季招聘面试经验分享
    本文详细记录了字节跳动夏季招聘的面试经历,涵盖了一、二、三轮面试的技术问题及项目讨论,旨在为准备类似面试的求职者提供参考。 ... [详细]
  • 迎接云数据库新时代:程序员如何应对变革?
    在数据无处不在的时代,数据库成为了管理和处理数据的核心工具。从早期的信息记录方式到现代的云数据库,数据库技术经历了巨大的变革。本文将探讨云数据库的特点及其对程序员的影响。 ... [详细]
  • 性能测试工具的选择与应用
    本文探讨了性能测试工具的重要性及其在软件测试中的作用,重点介绍了选择合适性能测试工具的考量因素,并对几种常用的性能测试工具进行了对比分析。 ... [详细]
author-avatar
笑竹舞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有