暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

缓存 Cache

花间剑指编程 2021-04-06
638

1、简介

缓存:就是将程序或系统经常要调用的对象存在内存中,使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。(可以进行高速数据交换的存储器)。


2、缓存与内存的区别和相同点

2.1、缓存的常用淘汰策略:

  • FIFO(先进先出算法):如果一个数据最先进入缓存,则最应该先被淘汰。

  • LRU( The Least Recently Used:最不经常使用算法): 判断数据最近使用的时间,时间最远的数据优先淘汰。

  • LFU(Least Frequently Used:最近最少使用算法): 在一段时间,数据使用的越少,则优先淘汰。

2.2、缓存的使用:

1)将数据库部分经常使用的数据存入缓存中。

2)将分页/列表/排序等不常改变的内容存入缓存中。

3)并发计数 / 访问计数通过缓存来计算。

4)详情内容数据、页面放入缓存。

5)分布式session:Redis,memcached。

6)热点数据的排名:积分排名,等级排名。

7)发布订阅:mq。

8)分布式锁:sql、redis、zookeeper。


3、发展过程

3.1、从单体架构看缓存(发展过程)

早期为无缓存实现方式,后来,由于用户量的剧增,带来性能的不足,加入本地缓存。经过进一步发展,进一步发展为第三方缓存、集中式缓存。

3.2、从集群架构看缓存(发展过程)

由于业务的集群部署,相比单体架构带来了不少提高。但由于访问同一块缓存,难免会负载过大。对缓存进行集群处理,将一些变化较小的数据放入本地缓存;变化较大的数据进行集中式缓存。

4、集群架构与微服务架构

4.1、集群架构

【1】集群架构的特点:以单体项目为基础进行业务系统的划分,系统之间存在数据冗余,系统耦合度较高。

【2】优点:

(1)项目架构简单,开发成本低。

(2)可以针对系统的某一瓶颈进行扩展。

(3)不同系统可以用不同的技术实现。

【3】缺点:

(1)以单体为基础所有功能依然全部在一个系统,后期难以维护。

(2)集群到一定程度就会产生性能瓶颈。

(5)从微服务看缓存(演化过程)

4.2、微服务架构

【1】微服务架构的特点:

(1)服务可以独立部署

(2)服务讲究单一原则,一个服务做一件事

【2】优点:

(1)服务拆分方便,更细,并可以重复使用。

(2)可以针对某个服务进行扩展和性能优化。

(3)服务部署相对单体架构更简单,业务服务之间影响相对较小,可以分别对各个服务进行部署升级。

【3】缺点:

(1)服务划分的越多,越难以管理.

(2)服务需要不断进行故障监控,故障预警等才能了解到微服务的健康状态。

5、缓存的分类

5.1、常见的客户端缓存:

(1)页面缓存(页面部分或者全部进行离线缓存和本地缓存)

(2)APP缓存

(3)浏览器缓存(将http获取的资源缓存在本地)

(4)服务端缓存


5.2、常见的服务端缓存:

(1)数据库级缓存:

  • MySQL的查询缓存,Query Cache,在数据库修改程度较小的情况下,使用Query Cache能很大幅度提高查询效率,否则,反之。


(2)平台级缓存(具有缓存功能的专用三方库和框架):

  • 平台级缓存的特点:

    • (1)基于应用程序的缓存

    • (2)具有一定的分布式能力

    • (3)数据不能保证强一致性

    • (4)无法保证高可用性


(3)应用级缓存(通过代码实现缓存机制)

  • 如CDN缓存(Content Delivery Network : 内容分发网络)

  • 使用CDN缓存有哪些优点:

    • 本地Cache加速

    • 实现跨运营商的网络加速

    • 远程加速

    • 带宽优化

6、分布式缓存系列知识

6.1、缓存雪崩

缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间所有原本应该访问缓存的请求都去查询数据库了,而对数据库 CPU 和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。一般有三种处理办法:
  • 一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。

  • 给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。

  • 为 key 设置不同的缓存失效时间。

6.2、缓存穿透

缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。
有很多种方法可以有效地解决缓存穿透问题,最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力。另外也有一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。
通过这个直接设置的默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。

6.3、缓存预热

缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据。

6.4、缓存更新

缓存更新除了缓存服务器自带的缓存失效策略之外(Redis默认的有 6 中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种:
  • 定时去清理过期的缓存;

  • 当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。

6.5、缓存降级

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。

文章转载自花间剑指编程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论