所有程序猿都对那缓存并不陌生,好似那风一样的女子只为你独自而舞。只见那回眸一笑百媚生,让你甚是吝惜,惹人怜爱。
但随着项目规模不断增大变强,光是单个缓存就难以招架,优而显得力不从心。
这时伴随着多级缓存得化茧成蝶,平台级缓存和分布式缓存在应用上就都相辅相成。
但一山难容二虎,往往存有3大问题——①概念难以区分②我到底应该选择谁③各自适用于什么场景。
如果这个没弄明白,我怕是觉得你还不大行额。
本篇我将已老生常谈的态度来为大家一一揭晓,同时掌握方案与场景,设计技术选型的原理。包括一线大厂在本章节可能涉及的常考点。
![](https://i-blog.csdnimg.cn/blog_migrate/855cb2f71e065f6e3e3c8cca40748ae8.png)
何为平台级缓存与分布式缓存?
平台级缓存是指你所选择编程语言下的缓存技术类型。
它是在语言的前提条件下,来采用的缓存技术,也就是你用什么语言,就采用它存在的缓存技术。
缓存是工具,供编程语言调用。前者为后者服务,得有一个主次的关系。
所以有时 你要控制你自己呀,别给自己飙车的速度,不然翻车了你都不知道
![](https://i-blog.csdnimg.cn/blog_migrate/81fae64450b29dfc823b0efc0de30c07.png)
比如:
你在淘宝开了个新店铺,这时你需要对你的店铺进行装饰打扮,那就需要使用淘宝这个平台上提供的功能来进行装饰。
像上传商品配图、店铺布局风格等。
换句话说平台级缓存是依附于平台的特性而决定的。
上篇也提到在不同的编程语言下,平台级缓存也不相同,比如:
PHP里面Smarty模板库
Java中如Ehcache,Cacheonix,Voldemort,JBoss Cache,OSCache等等。
而且按照应用层的定义来看,平台级缓存可根据进程执行使用的方式划分为进程内缓存和进程外缓存。
那什么是进程内、进程外缓存呢?
进程内缓存
就是缓存数据存在于所属应用进程之内,和应用业务代码、变量、堆栈等类型共同享受应用进程的内存资源。 缓存就是在进程内中的数据段进行站位。
或者说原来你1人住1房间,现在你和别人一起住。
进程外缓存
指缓存数据存储的地方不在使用应用内,而是外部的其它进程来存储。比如像:Redis、memcache之类。
那如果缓存以文件形式保持咋办呀?也算应用进程外?
放心,我乃吒吒辉,而不是渣渣辉。呸,渣男
因大多数缓存都是在内存里面来进行操作,所以常常会忽视以文件形式来保存的数据文件。像这种情况它还是平台级缓存下的进程内缓存,不是进程外缓存。
因为这个文件的缓存是服务于应用进程,而你像Redis那种角色,它是独立的进程,进程和进程本身是有隔离的,而且它们还是不同软件的进程,就更没得啥关系。
而且文件缓存里面的内容都是提前把逻辑处理的数据存入进取。当使用时,就可以减少重复的读取、计算数据的动作从而来达到缓存的效果。
那如果我把Redis独立部署到其它服务器里面,也是进程外缓存吗?
![](https://i-blog.csdnimg.cn/blog_migrate/a8667e4b78c88666d4dd0d825fe618dc.png)
这样的情况它就是了,上面提到进程外缓存是相对应用进程而言的,现在它们存在于不同的服务器。如果是在同一台服务器里面部署。那也算进程外缓存,因为进程是隔离的,但一般Redis部署到其它服务器我们不会这样称呼
那它这叫啥呢?
这种情况称分布式缓存,常说的分布式缓存就是这种形式存在于世。
分布式缓存也很好理解,首先看分布式,它表示把不同的软件分别部署在不同的服务器上或者同一服务器上不同的软件服务。
注:这里【分布式缓存】是个相对概念,如果按分布式概念看,一台服务器上部署了PHP|JAVA和Redis。它们之间的关系也算分布式。
但我们现在是从进程内外缓存的概念划分。这样一看,它就不属于分布式缓存了。大家知道统一的说法即可
哎呀,累死个人,吒男能这样,面面俱到?有点绕,你老慢着点,细细品味
为何使用平台级与分布式缓存?
无论什么类型的缓存,使用它们的根本目标就是减少数据的逻辑运算,加快请求响应,进而提高网站的QPS。只不过体现的地方是不一样的罢了。
那平台级和分布式缓存都有神马好处?
平台级
优点:
时延更低,能够节省内网带宽
平台级缓存,由于数据不需要跨网络传输,直接在本地内存中操作。故性能好,时延低,消耗的带宽也较少。
不需要引入第三方类库,开箱即用
一般平台级缓存,都会有官方提供的相关操作类库,并不需要引入第三方的类库,降低了业务开发的关联。
缺点:
存储容量有限,无法进行大数据存储
由于内存占用了应用进程的内存空间,如 Java 进程的 JVM 内存空间,故不能进行大数据量的数据存储。
微服务架构中,集群部署数据的更新问题。
平台缓存数据存储于应用进程内,故无法被其他应用进程访问,在集群部署中同一缓存数据需要部署多份。
如果对应数据库的数据,存在更新动作,则需要同步更新到不同部署节点的本地缓存,这样才能保证数据一致性。这时复杂度较高并且容易出错。
可以采用如基于 Redis 的发布订阅机制来同步更新各个部署节点或者中间件进行异步数据更新。
数据随应用进程的重启或崩溃而丢失
平台缓存数据是存储在应用进程的内存空间,所以当应用进程重启时,缓存数据也会丢失。所以对于需要持久化的数据,要注意及时保存,否则可能会造成数据丢失。
分布式缓存
优点:
性能、存储容量无上限,理论上可做到无限扩充
虽然本地缓存快,但终究在单机上,资源性能都有上限。
而分布式缓存是独立部署的进程,自身拥有独立的内存空间,不会受到应用进程重启的影响,同时硬件资源也是独享。
如果一台机器性能不够,就可以采用集群的方式拓展,做到线性的扩容。在配合docker容器,瞬间 beautiful
数据集中存储,保证数据一致性,也做到了业务上的解耦
虽然缓存是以分布式的方式存储,但部署模式会采用集群来保证高可用。
![](https://i-blog.csdnimg.cn/blog_migrate/f96119bdd863bbf80a8f2f9e5ac4a7d6.png)
这样所有的缓存数据都维护在缓存集群当中,故不存在像本地缓存数据更新的问题,也保证了不同节点应用进程的数据一致性问题。
以前缓存和业务是在一起使用,现在业务和缓存剥离开来,互不影响,从而做到了业务上的拆分。
数据从业务上做读写分离,保证网站高性能,高可用
分布式缓存一般支持数据副本机制,从业务上课实现读写分离,故可以解决高并发场景中并发读写性能问题。
由于在多个缓存节点也冗余了数据,提高了缓存数据的可用性,避免某个缓存节点宕机导致数据不可用问题。
那什么是读写分离?
读写分离是指把网站中用户请求,按照读、写请求进行划分。常常需要配合MySQL主从,主库针对用户写请求,从库针对用户读请求。
如果不做读写分离那么请求都会走一台机器。所以读写分离在一定程度上也做到了负载均衡,还可以针对单一类型的请求来做到专治。
比如:主库针对写请求,那可以省去索引的创建,而从库针对读请求,需要索引来处理。这样就可以根据请求类型来选择是否使用索引。
毕竟索引维护也是需要消耗资源的。谁让咋的心眼儿细呢?不小心看到了
原来读写分离就是这样的啊,那我知道了
这个,其实这里小吒只是抛转引玉了下,但大致意思都差不多,根本就是把读写请求分开,然后进行专治。
又比如:针对网站架构时,也可以采用读写分离的机制来部署网站子系统,针对搜索的业务,可以完全独立部署search_product.com。由它来提供搜索页面。
再来比如:针对要提高业务的处理能力,咱们缓存的主从架构照样可配合读写分离,加速网站的处理。
还来比如:针对访问量过高,可以通过读写队列来进行流量消费和异步批量写机制,来提高网站的处理能力和写负载过高等问题。
等等还有其它的,但大家要明白读写分离的作用,而且有时候它还会配合业务进行调整的。
你TM吒吒辉有完没完了,一口气说完不行了,我这个暴脾气给你惯得。
![](https://i-blog.csdnimg.cn/blog_migrate/f04ffe1e78bbf7556cd0b063556a3bc0.png)
缺点:
运维和部署上成本高
由于是分布式部署方式,部署、运维起来还是比较有技术难度,因为每台服务器的运行情况你肯定都要知道,外加线上环境的不确定因素。直接头大
但方案能抗住大流量,方案还是可取,同时基于Docker在部署上也会减轻很多压力。 横竖你都占一样嘛,不然咋个办呢?
技术结构复杂,需要考虑缓存雪崩、击穿等问题
![](https://i-blog.csdnimg.cn/blog_migrate/3fb01336b51193dfb18b02de80f8af5f.png)
分布式缓存中的数据量肯定不少,对业务方来说需要,考虑缓存的击穿、雪崩、穿透等问题,防止意外情况下请求直接打到数据库造成数据库崩溃的问题。
数据跨网络传输,性能低于本地缓存
分布式缓存部署一般都是与应用进程位于不同的机器,故需要通过外网来进行网络数据传输,相对于平台缓存的进程内部数据读取操作,性能会较低。
平台级与分布式缓存的技术选项?
每个技术都会有自己的立场,在什么情况来选择用什么样的技术内容。还是得根据你项目需求情况来进行选择
看速度?选平台级缓存
平台缓存的优势就是处于应用进程内部,离程序是最近的。如果某部分数据不大,但是访问量比较高,直接使用它来做处理。简直是省心有省力气,在加上AOP切面编程,简直舒服的不要不要的。
例如:
如果想首页、活动页里面的展示一些统计或推荐的信息。有了它就不用每次都去调用相同API来进行运算操作,只要记得定时更新平台缓存即可。
![](https://i-blog.csdnimg.cn/blog_migrate/2aa6157c9ae5edb93a235f42c8537020.png)
看数据量?选分布式缓存
平台缓存受限于应用进程方,存储有限,在大流量、海量数据的规模情况下,肯定选择分布式缓存,基于水平扩容、读写分离来满足业务场景、数据存储、性能需求等。
综合来看,有规模选分布式缓存,规模一般选择进程外缓存。规模小你老看着办?
网站上到大规模,你分布式那都跑不脱。
为了满足高可用、高可靠机制,一般都会采用分布式集群的方式部署,这样一个业务,会有多台机器来提供服务,就算挂了一个主机,还有其它的顶上来。
那选择平台级缓存有何问题?
如果多机器采用平台缓存,那缓存就有多份,一旦数据变更,就需要通知到多个上游服务方来更新数据。
微服务模式下,一个页面模块的展示数据,在调用一个服务时可能需要拿到多个服务的数据聚合之后,才能最后返回给客户端展示。
这样一个服务的数据发生变化就需要通知到刚开始调的服务来更新缓存,业务上就耦合起来,而且还加入了很多附加工作,严重影响性能。
数据的一致性问题,一个服务更新,如果网络有延迟或意外,导致更新的请求失败,那么数据库和缓存的数据就存在不一致。
总结
网站规模建议采用分布式缓存,因为业务方和缓存就不需要在业务上耦合,后期架构调整和维护都比较轻松。
场景上选什么还是得根据业务需求和架构设计来综合考虑,个人不大推荐平台缓存,业务职责更加清晰些,可能更好些。
特推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:
长按订阅更多精彩▼
如有收获,点个在看,诚挚感谢