关于缓存设计:缓存的设计方式

问题状况:当有大量的申请到外部零碎时,若每一个申请都须要咱们操作数据库,例如查问操作,那么对于那种数据根本不怎么变动的数据来说,每一次都去数据库外面查问,是很耗费咱们的性能 尤其是对于在海量数据中进行数据操作的时候,如果都是从 DB 中进行加载,那这是在挑战用户的耐性 简略来看,例如咱们要去小区外面理解一个人在不在家,当没有通信工具的前提下,咱们每一次都要通过小区们的保安,而后再到具体的单元楼,最终到了这家门口,最终才晓得在不在家 如果咱们换了一个比拟优良的保安,他晓得以后小区外面的特定的家外面是否有人,那这个时候,如果咱们间接去问小区保安,天然就无需跑冤枉路了,天然就进步了效率 此处简略的就能够将优良保安看做是一个缓存,咱们每一次去拜访,就会先去拜访缓存 , 这样就能极大的进步拜访效率和零碎性能 能够看出,有一个优良的保安相当重要 缓存的根本设计形式是什么样的设计缓存天然也是为了解决零碎是的低效问题,让零碎能够高性能,高并发 例如咱们间接拜访单机的数据库如mysql 也就是上千级别的 qps,如果是拜访 缓存的时候,就能达到上万,上十几万,这差距不是一点半点,是一个质的飞越 缓存的设计实际上就是 DB 和 缓存操作程序以及谁来操作的事件,大体分为如下 4 种模式 Cache Aside<!----> Read Through<!----> Write Through<!----> Write Behind Caching上述四种模式, Cache Aside 用的形式是最常应用的,咱们后续细说 后续三种模式的含意是 Read Through 是在查问操作的时候更新缓存,若缓存生效了,则是由缓存服务器本人将数据加载到缓存中Write Through 是在更新数据库的时候,如果命中了缓存,则先更新缓存,再由缓存服务器本人去更新数据,<!----> 如果是没有命中缓存,那么就间接更新数据库Write Behind Caching 通过名字咱们晓得,是在写到缓存操作之后才做些操作,实际上这种模式只更新缓存,不会更新数据库,缓存服务器会以异步的形式将数据批量更新到数据库中 很显著,这种,模式速度天然会更快,可这种模式对于保障数据库和缓存数据一致性问题,是个硬伤,且还会存在丢数据的状况,比方,咱们的缓存服务器挂掉了 Cache Aside 读写缓存模式是怎么玩的Cache Aside 读写模式缓存又是如何去解决的呢,一起来看看 Cache Aside 模式读取数据的逻辑是这个样子的: 读取数据时 先读取缓存中的数据,如果缓存中有数据,则间接返回<!----> 若缓存中没有数据,则去读数据库中的数据,并将数据同步到缓存中 写入数据时 写入数据库,写入胜利时,将缓存的数据删除掉 认真的同学可能会思考并提出这样的问题,如果我一个查问操作,当初缓存中无数据,此时会去数据库中查问,在这个过程中,另外有一个写入数据库的操作,且操作结束后,删除了缓存,这个时候,第一个操作实际上从数据库拿到的还是之前的老数据,并且会将数据放到缓存中,那么此时的数据实际上是一个老数据,也能够了解是在脏数据 这个点其实咱们就无需放心了,大佬们曾经论证过这种状况呈现的概率极低 因为咱们的写表操作是要锁表的,且咱们晓得数据库写入操作比读取操作要慢,也就是说,当同时有一个读取和写入 DB 的操作时,天然是写入的操作是要后返回后果的,此处不要杠啥读写数据量不统一的状况,咱们做比照,天然是在同等条件下比拟咯 从图中咱们晓得,同等条件下,先进行查问 DB 的操作,过程中,来了一个写入 DB 操作,天然是 查问操作先返回,写入操作再返回后果 ...

August 24, 2023 · 1 min · jiezi

关于缓存设计:玩转Java并发工具精通JUC成为并发多面手构建高性能缓存

引言《玩转Java并发工具、精通JUC、成为并发多面手》构建高性能缓存这部分的集体笔记。本节为单纯的实战,次要是把之前学习并发编程的知识点串起来。 挺有意思的一个demo,能够疾速理解到一些并发编程的时候须要留神的一些问题。目录整个高性能构建的梳理思路如下: 应用最简略的HashMap剖析HashMap实现的问题 高并发拜访反复计算性能问题复用性能较差的问题装璜模式形象计算业务 解决复用性能较差的问题应用Future改写计算实现接口 避免业务反复计算如何解决高并发拜访反复计算性能问题减少泛型缓存过期和减少随机性 为什么须要缓存过期? 避免缓存净化为什么要减少随机性? 避免同一个时刻大量缓存过期减少零碎压力整体测试代码一个简略的小demo,能够间接拷贝上面的包所属的各个版本代码到本人的我的项目浏览即可:https://gitee.com/lazyTimes/interview/tree/master/src/main/java/com/zxd/interview/mycache 一、构建步骤1. 应用最简略的HashMap最根底的版本实现非常简单,这是咱们通常会想到的利用缓存实现计划,这里应用了Lombok的@Slf4j注解进行日志打印。 整个逻辑非常简单,首先通过计算方法匹配缓存,如果有就取缓存内容,否则就调用计算方法而后把后果缓存到HashMap当中。 /** * 初版高速缓存实现 * 1. 应用简略的HashMap * 2. 在高速缓存中进行计算 * * 裸露问题: * 1. 复用性能查 * 2. HashMap线程不平安,有可能反复判断 */ @Slf4j public class MyCacheVersion1 { private final Map<String, Integer> cache = new HashMap<>(); /** * 依据参数计算结果,此参数对于同一个参数会计算同样的后果 * 1. 如果缓存存在后果,间接返回 * 2. 如果缓存不存在,则须要计算增加到map之后才返回 * @param userId * @return */ public Integer compute(String userId) throws InterruptedException { if(cache.containsKey(userId)){ log.info("cached => {}", userId); return cache.get(userId); } log.info("doCompute => {}", userId); Integer result = doCompute(userId); //不存在缓存就退出 cache.put(userId, result); return result; } private Integer doCompute(String userId) throws InterruptedException { TimeUnit.SECONDS.sleep(5); return Integer.parseInt(userId); } }初版存在较多的问题,比较显著的问题是compute这个办法在多线程的环境是不平安的,咱们能够编写测试程序验证。 ...

June 22, 2023 · 12 min · jiezi

关于缓存设计:缓存穿透缓存击穿缓存雪崩

1、背景在高并发环境下,用户长时间对服务器进行操作,可能会呈现缓存穿透、缓存击穿、缓存雪崩等问题。 2、缓存穿透2.1 什么是缓存穿透?高并发前提下,用户拜访数据库和缓存都不存在的数据称之为缓存穿透。缓存之所以存在,除了进步程序运行效率,还有就是爱护数据库。如果有大量的申请拜访数据库跟缓存都没有的数据,那么此时缓存便会生效,这大量的申请必然会间接拜访数据库。 2.2 缓存穿透的解决方案①禁用IP,限度IP的应用(因为拜访不存在的数据基本上属于歹意拜访)②限流,每秒最多拜访3次③应用布隆过滤器 2.3 布隆过滤器2.3.1 介绍布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器能够用于检索一个元素是否在一个汇合中。它的长处是空间效率和查问工夫都比个别的算法要好的多,毛病是有肯定的误识别率和删除艰难。 2.3.2 原理①首先对数据进行预加载。将数据进行hash计算得出的hash值进行特定的函数运算出数组的索引,而后在该坐标地位用二进制向量1示意。如此一来坐标为0的数据肯定不存在,所以能够禁止拜访,而坐标为1可能存在,能够放行拜访。②当一个申请过去了,通过hash加特定的函数算法而后查看数组的二进制的值来判断是否容许通过。③因为是采纳二进制向量存储,所以节俭大量内存空间。 2.3.4 hash碰撞问题如果坐标值是0,那就肯定不存在,然而坐标是1也不代表肯定存在,因为两个不同的key计算的后果是可能是雷同的坐标值,那么如何解决这个问题呢? 2.3.4.1 解决hash碰撞问题要解决hash碰撞的问题,那就要升高hash碰撞的概率。①通过增长数据的个数,来升高坐标值雷同的概率。②通过采纳多种hash函数来计算坐标值,因为不同的hash函数计算出的坐标值后果会有不同,只有正在存在的数据无论通过哪种hash函数计算,坐标值都是向量1,凡是有一个后果不是1,就能够判定这个是不存在的数据。 3、缓存击穿3.1 什么是缓存击穿?某个热点数据在缓存中忽然生效。导致大量的用户间接拜访数据库。导致并发压力过高造成异样的景象。 3.2 缓存击穿的解决方案之所以存在缓存击穿次要是因为数据被设置了超时工夫,当超时工夫一到便会被删除,而此时刚好处于高并发。①尽可能将热点数据的超时工夫,设定的长一点。②设定多级缓存,超时工夫采纳随机算法。只有不同时生效便能够无效阻止这种景象。 4、缓存雪崩4.1 什么是缓存雪崩?在缓存服务器中,因为大量的缓存数据生效,导致用户拜访的命中率过低。导致间接拜访数据库。fluashAll命令和数据大量数据同时超时可能导致缓存雪崩景象。 4.2 缓存雪崩的解决方案①设定超时工夫时,应该采纳随机算法②设定多级缓存

December 15, 2020 · 1 min · jiezi