缓存特征

(1)命中率:命中数/(命中数+没有命中数)
(2)最大元素(空间):代表缓存中可以存放的最大元素的数量,一旦缓存中元素的数量超过这个值,或者缓存数据所占的空间超过了最大支持的空间,将会触发缓存清空策略。根据不同的场景,合理设置最大元素(空间)的值,在一定程度上可以提高缓存的命中率,从而更有效的使用缓存。
(3)清空策略:FINO(先进先出)、LFU(最少使用)、LRU(最近最少使用)、过期时间、随机等

  • FINO(先进先出):最先进入缓存的数据,在缓存空间不够或超出最大元素限制的情况下,会优先被清除掉,以腾出新的空间来接收新的数据。这种策略的算法主要是比较缓存元素的创建时间,在数据实时性较高的场景下,可以选择这种策略,优先保证最新策略可用。
  • LFU(最少使用):无论元素是否过期,根据元素的被使用次数来判断,清除使用次数最少的元素来释放空间。算法主要是比较元素的命中次数,在保证高频数据有效的场景下,可以选择这种策略。
  • LRU(最近最少使用):无论元素是否过期,根据元素最后一次被使用的时间戳,清除最远使用时间戳的元素,释放空间。算法主要是比较元素最近一次被获取的时间,在热点数据场景下,可以选择这种策略。
  • 过期时间:根据过期时间判断,清理过期时间最长的元素,或者清理最近要过期的元素。

缓存命中率影响因素

(1)业务场景和业务需求
缓存往往适合读多写少的场景。业务需求对实时性的要求,直接会影响到缓存的过期时间和更新策略。实时性要求越低,就越适合缓存。在相同Key和相同请求数的情况下,缓存的时间越长,命中率就会越高。
(2)缓存的设计(粒度和策略)
通常情况下,缓存的粒度越小,命中率越高。缓存的更新和命中策略也会影响缓存的命中率,当数据发生变化时,直接更新缓存的值会比移除缓存或使缓存过期的命中率更高。
(3)缓存容量和基础设施
缓存的容量有限,则容易引起缓存失效和被淘汰(目前多数的缓存框架或中间件都采用了LRU算法)。同时,缓存的技术选型也是至关重要的,比如采用应用内置的本地缓存就比较容易出现单机瓶颈,而采用分布式缓存则毕竟容易扩展。所以需要做好系统容量规划,并考虑是否可扩展。此外,不同的缓存框架或中间件,其效率和稳定性也是存在差异的。
(4)其他因素
当缓存节点发生故障时,需要避免缓存失效并最大程度降低影响,这种特殊情况也是架构师需要考虑的。业内比较典型的做法就是通过一致性Hash算法,或者通过节点冗余的方式。
有些朋友可能会有这样的理解误区:既然业务需求对数据时效性要求很高,而缓存时间又会影响到缓存命中率,那么系统就别使用缓存了。其实这忽略了一个重要因素--并发。通常来讲,在相同缓存时间和key的情况下,并发越高,缓存的收益会越高,即便缓存时间很短。

提高缓存命中率的方法

从架构师的角度,需要应用尽可能的通过缓存直接获取数据,并避免缓存失效。这也是比较考验架构师能力的,需要在业务需求,缓存粒度,缓存策略,技术选型等各个方面去通盘考虑并做权衡。尽可能的聚焦在高频访问且时效性要求不高的热点业务上,通过缓存预加载(预热)、增加存储容量、调整缓存粒度、更新缓存等手段来提高命中率。
对于时效性很高(或缓存空间有限),内容跨度很大(或访问很随机),并且访问量不高的应用来说缓存命中率可能长期很低,可能预热后的缓存还没来得被访问就已经过期了。

缓存的分类和应用场景

(1)本地缓存:编程实现(成员变量、局部变量、静态变量)、Guava Cache
(2)分布式缓存:Memcached、Redis

高并发场景下缓存常见问题

(1)缓存的一致性
更新数据库成功---更新缓存失败
更新缓存成功---更新数据库失败
更新数据库成功---淘汰缓存失败
淘汰缓存成功---更新数据库失败

(2)缓存并发
并发时请求缓存时已过期或者没有命中或者更新的情况下有大量的请求访问数据库,
解决办法:在缓存更新或者过期的情况下,先尝试获取到lock,当更新完成后,尝试释放锁,其他的请求只需要牺牲一定的等待时间

(3)缓存穿透
在高并发的场景下,如果某一个key被高并发的访问没有被命中,出于对容错性的考虑会尝试从后端的数据库获取,从而导致大量的请求访问了数据库,主要是当key对应的数据为空或者为null的情况下,这就导致数据库中并发的执行了很多不必要的查询操作。从而导致了巨大的冲击和压力。
解决方法:
缓存空对象:对查询结果为空的对象也进行缓存,如果是集合可以缓存一个空的集合,而不是null,如果是单个对象可以通过字段标识来区分,需要保证缓存数据的时效性(实现相对简单),适合命中不高但可能会频繁更新的数据。
单独过滤处理:对所有可能对应数据为空的key进行统一的存放,并在请求前做拦截(实现相对复杂),适合命中不高更新不频繁的数据

(4)缓存颠簸问题
缓存的颠簸问题,有些地方可能被称为“缓存抖动”,可以看作是一种比“雪崩”更轻微的故障,但是也会在一段时间内对系统造成冲击和性能影响。一般是由于缓存节点故障导致。业内推荐的做法是通过一致性Hash算法来解决

(5)缓存雪崩现象
缓存雪崩就是指由于缓存的原因,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃,发生灾难。导致这种现象的原因有很多种,上面提到的“缓存并发”,“缓存穿透”,“缓存颠簸”等问题,其实都可能会导致缓存雪崩现象发生。这些问题也可能会被恶意攻击者所利用。还有一种情况,例如某个时间点内,系统预加载的缓存周期性集中失效了,也可能会导致雪崩。为了避免这种周期性失效,可以通过设置不同的过期时间,来错开缓存过期,从而避免缓存集中失效。
从应用架构角度,我们可以通过限流、降级、熔断等手段来降低影响,也可以通过多级缓存来避免这种灾难。
此外,从整个研发体系流程的角度,应该加强压力测试,尽量模拟真实场景,尽早的暴露问题从而防范。

(6)缓存无底洞现象
该问题由 facebook 的工作人员提出的, facebook 在 2010 年左右,memcached 节点就已经达3000 个,缓存数千 G 内容。他们发现了一个问题---memcached 连接频率,效率下降了,于是加 memcached 节点,添加了后,发现因为连接频率导致的问题,仍然存在,并没有好转,称之为”无底洞现象”

注意:部分内容为转载,感谢那些为技术的发展默默付出的前辈们。

高并发之——缓存思路相关推荐

  1. 并发编程-24 高并发处理手段之扩容思路 + 缓存思路

    文章目录 概述 扩容思路 垂直扩展(纵向扩展) 水平扩展(横向扩展) 缓存思路 缓存特征 缓存命中率影响因素 缓存分类和应用场景 Guava Cache Memcache Redis 概述 这里只是讲 ...

  2. 高并发之服务降级和服务熔断____服务降级、熔断、限流的区别

    高并发之服务降级和服务熔断 服务降级: 服务压力剧增的时候根据当前的业务情况及流量对一些服务和页面有策略的降级,以此环节服务器的压力,以保证核心任务的进行. 同时保证部分甚至大部分任务客户能得到正确的 ...

  3. 高并发之——创建线程池居然有这么多方式...

    来自:冰河技术 前言 在Java的高并发领域,线程池一直是一个绕不开的话题.有些童鞋一直在使用线程池,但是,对于如何创建线程池仅仅停留在使用Executors工具类的方式,那么,创建线程池究竟存在哪几 ...

  4. java 高并发_Java 高并发之无锁(CAS)

    Java 高并发之无锁(CAS) 本篇主要讲 Java中的无锁 CAS ,无锁 顾名思义就是 以不上锁的方式解决并发问题,而不使用synchronized 和 lock 等.. 1. Atomic 包 ...

  5. 应对「高并发」的思路

    大家好,我是Z哥. 最近正好在编写一套新的面试题,其中有一道是与高并发相关的.出题的目的是想了解一下候选人面对大流量场景下的优化思路.在出这道题的过程中,我自己也梳理了一下自己对这个问题的思路. 然后 ...

  6. 【java】高并发之限流 RateLimiter使用

    1.概述 转载原文:高并发之限流 你可能知道高并发系统需要限流这个东西,但具体是限制的什么,该如何去做,还是模凌两可.我们接下来系统性的给它归个小类,希望对你有所帮助. google guava中提供 ...

  7. javaEE高并发之如何更新库存问题

    javaEE高并发之如何更新库存问题 有三个阶段可更新库存:成功加入购物车:点击去支付,生成订订单:点击支付. 分析: 1.加入购物车并不代表用户一定会购买,如果这个时候开始预占库存,会导致想购买的无 ...

  8. 高并发之并发容器详解

    高并发之并发容器详解 一.vector Vector 是矢量队列,它是JDK1.0版本添加的类.继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口 ...

  9. 高并发下缓存与数据库双写不一致解决方案

    高并发下缓存与数据库双写不一致解决方案 参考文章: (1)高并发下缓存与数据库双写不一致解决方案 (2)https://www.cnblogs.com/wlwl/p/11601632.html (3) ...

最新文章

  1. 理解特征统计偏差、方差、平均值、中位数、百分数等等
  2. sqlite导入 mysql_Sqlite向MySql导入数据
  3. python 堆排序的两种实现
  4. 【蓝桥杯】基础练习 十六进制转八进制(Java实现)
  5. COLING 2020 | 字符感知预训练模型CharBERT
  6. 如何快速把kux格式转换成mp4
  7. ubuntu安装freeradius3, freeradius3-mysql并配置
  8. JAVAFX的webview中的webkit支持WindowsXP系统
  9. java 返回指定月份的最后一天的59分59秒
  10. 工控安全之系统加固篇
  11. 你还在为校园内丢失东西无处可寻而发愁吗?速戳进来
  12. 阿里巴巴-新加坡南洋理工大学成立联合研究院 开展全方位AI合作
  13. Qt下 汉字转换拼音
  14. 科技交流英语(2022秋)Unit 6 test
  15. UR机器人TCP通讯示例
  16. 金融经济学期末梳理(王江)第二、三章
  17. 伯努利分布(Bernoulli distribution)
  18. 个人对宏观经济学的理解
  19. 规范自己的JavaScript书写 – Dojo Javascript 编程规范
  20. 获取加速乐的__jsl_clearance

热门文章

  1. 微软硬件25周年庆典专题
  2. Ubuntu20.04编译Linux内核
  3. 华为云下载加速解决方案了解一下
  4. ASP.NETIT产品网上物流管理信息系统的设计与实现(源代码+论文)
  5. opencv imshow函数详解
  6. “北外女孩”真相:腾讯网与普天同庆联手炒作
  7. WPS文字 JSA 学习笔记 - 设置自定义编号
  8. 《深入分析JavaWeb技术内幕》之读书笔记(篇一)
  9. 使用 imgaug 对图像进行数据增强 Data Augmentation
  10. Python中的元类