java分布式缓存方案

目录
  • 一、从数据说起
    • 2.1. 同步使用加载
    • 2.2. 延迟异步加载
  • 二、本地缓存
  • 三、远程缓存
  • 四、内存网格
  • 五、缓存常见问题
    • 1. 缓存穿透
    • 2. 缓存击穿
    • 3. 缓存雪崩
    • 番外:

一、从数据说起

我们再做缓存之前需要把数据先分好类

按变化频率:

  • 静态数据:一般不变的,类似于字典表
  • 准静态数据:变化频率很低,部门结构设置,全国行政区划数据
  • 中间状态数据:一些计算的可复用中间数据,变量副本,配置中心的本地副本

按使用频率:

  • 热数据:使用频率高的
  • 读写比大的:读的频率远大于写的频率

这些数据就比较适合使用缓存。

缓存无处不在。内存可以看作是cpu和磁盘之间的缓存。cpu与内存的处理速度也不一致,所以出现了L1&L2 Cache

缓存的本质:系统各级之间处理速度不匹配,利用空间换时间。

缓存加载时间

1. 启动时全量加载

2. 懒加载

2.1. 同步使用加载

先看缓存里是否有数据,没有的话从数据库读取。读取的数据,先放到内存,然后返回给调用方。

2.2. 延迟异步加载

从缓存里获取数据,不管有没有都直接返回。

策略1:如果缓存为空的话,则发起一个异步线程负责加载。

策略2:异步线程负责维护缓存的数据,定期或根据条件触发更新。

缓存过期策略

  • 按FIFO或LRU
  • 固定时间过期
  • 根据业务进行时间的加权。

二、本地缓存

1.Map 缓存

public static final Map<String,Object> CACHE=new HashMap();
CACHE.put("key","value");

2.Guava缓存

Cache<String,String> cache = CacheBuilder.newBuilder() .maximumSize(1024) .expireAfterWrite(60,TimeUnit.SECONDS) .weakValues() .build();
cache.put("word","Hello Guava Cache");
System.out.println(cache.getIfPresent("word"));

3.Spring Cache

  • 基于注解和AOP,使用方便
  • 可以配置Condition和SPEL,非常灵活
  • 需要注意:绕过Spring的话,注解无效

核心功能:@Cacheable、@CachePut、@CacheEvict

本地缓存的缺点:

  • 在集群环境中,如果每个节点都保存一份缓存,导致占用内存变大
  • 在JVM中长期存在,会影响GC
  • 缓存数据的调度处理,影响业务线程,争夺资源

三、远程缓存

1.Redis
Redis是一个开源的使用ANSI C语言编写的,基于内存也可以持久化的key-value数据库,并提供多种语言的API
2. Memcached

memcached是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但被许多网站使用。这是一套开放源代码软件,以BSD license授权发布。

四、内存网格

  1. Hazelcast
  2. lgnite

五、缓存常见问题

1. 缓存穿透

问题描述:大量并发查询不存在的KEY,导致都直接把压力透传到数据库上。

分析:因为数据库里没有值,所以没有建立缓存,导致一直打到数据库上。

解决办法:

  1. 缓存空值的KEY
  2. Bloom过滤或RoaringBitmap判断KEY是否存在
  3. 完全以缓存为准,使用延迟异步加载的方式去加载数据库数据到缓存。

Bloom过滤器示例:
(引入guava依赖)

public static void main(String[] args) {
        BloomFilter<CharSequence> filter = BloomFilter.create(
                Funnels.stringFunnel(Charsets.UTF_8),//Funnels.integerFunnel(), //数据格式
                1000000,//预计存入数据量
                0.01);//误判率

        System.out.println(filter.mightContain("abcdefg"));
        filter.put("abcdefg");
        System.out.println(filter.mightContain("abcdefg"));
    }

RoaringBitmap示例:
引入依赖:

<dependency>
			<groupId>org.roaringbitmap</groupId>
			<artifactId>RoaringBitmap</artifactId>
			<version>0.8.1</version>
		</dependency>
public static void test3(){
        Roaring64NavigableMap roaring64NavigableMap = Roaring64NavigableMap.bitmapOf(3, 4, 5, 90);
        //是否包含
        boolean contains = roaring64NavigableMap.contains(3);
        long l = roaring64NavigableMap.rankLong(3);
        System.out.println(l);
        System.out.println(contains);
    }

2. 缓存击穿

问题:当某个KEY失效的时候,正好有大量并发请求访问这个KEY

分析:跟缓存穿透比较像,这个是属于偶然的

解决办法:

  1. KEY的更新的时候添加全局互斥锁
  2. 完全以缓存为准,使用延迟异步加载的策略

3. 缓存雪崩

问题:当某一个时刻发生大规模的缓存失效的情况,会有大量请求打到数据库,导致数据库压力过大而宕机

分析:一般来说,由于更新策略、或者数据热点、缓存服务宕机等原因,导致缓存数据同时大规模不可以。

解决办法:

  1. 缓存更新、失效策略在时间上做到比较均匀
  2. 使用的热数据尽量分散到不同机器上
  3. 多台机器做主从复制,实现高可用
  4. 实现熔断限流机制,对系统进行负载能力控制
  5. 使用本地缓存兜底

番外:

布隆过滤器:

目标就是要基于过滤器已存储生成的原始元数据,进行比较过滤,如果是在原始元数据集合里面的,一定会被发现。也有可能不是里面的被误杀。

BloomFilter 会开辟一个m位的bitArray(位数组),开始所有数据都部署为0,当一个元素过来的时候,通过多个hash函数计算出不同的值,然后根据hash值找到对应的下标处,将里面的值改为1.

优点:使用计算,节省存储空间。

缺点:有失误率。不是在过滤器原始表里的数据也会被误算进去。

使用场景:目标就是要基于过滤器已存储生成的原始元数据,进行比较过滤,如果是在原始元数据集合里面的,一定会被发现。布隆过滤器核心正确的使用就是进行过滤禁止,进行正确的否定。

举例:如我们有100万个黑名单的url地址,过来一个地址我们算出来不在里面,那就肯定可以放行。

BitMap:

BitMap的基本思想是用一个bit位来标记某个元素对应的值,这样就可以大大节省空间。

在Java中一个int占4个字节,也就是32bit。按int存储和按位存储的大小差距是32倍。

那么怎么表示一个数呢?可以使用1表示存在,0表示不存在。

如下面:表示{2,6}

一个byte只有8个位置,如果想表示13怎么办呢?只能再用一个byte了,就成了一个二维数组了

1个int占32位,那么我们只需要申请一个int数组长度为 int tmp[1+N/32] 即可存储,其中N表示要存储的这些数中的最大值

使用场景:

  • 1.快速排序

把数放进去之后,遍历一遍,把值是1的都取出来就排好序了。

  • 2.快速去重

20亿个整数中找出不重复的整数的个数?

内存不足以容纳这20亿个整数。我们怎么表示数字的状态呢?一个数的状态可以分为3种,不存在、存在一次、存在两次及以上。这就需要两个bit来表示。00代表不存在,01代表一次,11代表两次及以上。

接下来我们就把这20亿个整数放进去,如果状态为00,就改为01,如果状态为01就改为11.如果状态为11,就不动了。都放完后,遍历取出值为01的,就是不重复的数据的个数。。

  • 3. 快速查找

给定一个整数M,M/32就能得到int数组的下标,M%32就知道在这个下标里面的具体位置。

如13,就能算出在int[0]里面的第13个

到此这篇关于分布式缓存的文章就介绍到这了,更多相关缓存内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解Java分布式事务的 6 种解决方案

    介绍 在分布式系统.微服务架构大行其道的今天,服务间互相调用出现失败已经成为常态.如何处理异常,如何保证数据一致性,成为微服务设计过程中,绕不开的一个难题. 在不同的业务场景下,解决方案会有所差异,常见的方式有: 阻塞式重试: 2PC.3PC 传统事务: 使用队列,后台异步处理: TCC 补偿事务: 本地消息表(异步确保): MQ 事务. 本文侧重于其他几项,关于 2PC.3PC 传统事务,网上资料已经非常多了,这里不多做重复. 阻塞式重试 在微服务架构中,阻塞式重试是比较常见的一种方式.伪代码

  • 详解Java分布式Session共享解决方案

    分布式Session一致性? 说白了就是服务器集群Session共享的问题 Session的作用? Session 是客户端与服务器通讯会话跟踪技术,服务器与客户端保持整个通讯的会话基本信息. 客户端在第一次访问服务端的时候,服务端会响应一个sessionId并且将它存入到本地cookie中,在之后的访问会将cookie中的sessionId放入到请求头中去访问服务器,如果通过这个sessionid没有找到对应的数据那么服务器会创建一个新的sessionid并且响应给客户端. 分布式Sessio

  • 图文精讲java常见分布式事务理论与解决方案

    目录 CAP理论 C(Consistence):一致性 A(Availability):可用性 P(Partition tolerance):分区容错性 BASE理论 BA(Basically Available):基本可用 S(Soft-state):软状态 E(Eventually Consistent):最终一致性 一致性hash Gossip协议 Gossip协议的特点: Raft算法 选举 复制 分布式事务 2PC 3PC TCC 如何解决某个节点故障的问题?如何解决数据一致性的问题?

  • 浅谈Java实现分布式事务的三种方案

    一.问题描述 用户支付完成会将支付状态及订单状态保存在订单数据库中,由订单服务去维护订单数据库.由库存服务去维护库存数据库的信息.下图是系统结构图: 如何实现两个分布式服务(订单服务.库存服务)共同完成一件事即订单支付成功自动减库存,这里的关键是如何保证两个分布式服务的事务的一致性. 尝试解决上边的需求,在订单服务中远程调用减库存接口,伪代码如下: 订单支付结果通知方法{ ​ 更新支付表中支付状态为"成功". ​ 远程调用减库存接口减库存. } 上边的逻辑说明: 1.更新支付表状态为本

  • java实现分布式项目搭建的方法

    1 分布式 1.1 什么是分布式 分布式系统一定是由多个节点组成的系统.其中,节点指的是计算机服务器,而且这些节点一般不是孤立的,而是互通的. 这些连通的节点上部署了我们的节点,并且相互的操作会有协同.分布式系统对于用户而言,他们面对的就是一个服务器,提供用户需要的服务而已,而实际上这些服务是通过背后的众多服务器组成的一个分布式系统,因此分布式系统看起来像是一个超级计算机一样. 1.2 分布式与集群的区别 集群是同一个系统部在不同的服务器上,例如一个登陆系统部在不同的服务器上. 分布式是不同的系

  • java分布式缓存方案

    目录 一.从数据说起 2.1. 同步使用加载 2.2. 延迟异步加载 二.本地缓存 三.远程缓存 四.内存网格 五.缓存常见问题 1. 缓存穿透 2. 缓存击穿 3. 缓存雪崩 番外: 一.从数据说起 我们再做缓存之前需要把数据先分好类 按变化频率: 静态数据:一般不变的,类似于字典表 准静态数据:变化频率很低,部门结构设置,全国行政区划数据 中间状态数据:一些计算的可复用中间数据,变量副本,配置中心的本地副本 按使用频率: 热数据:使用频率高的 读写比大的:读的频率远大于写的频率 这些数据就比

  • 详解Java分布式缓存系统中必须解决的四大问题

    目录 缓存穿透 缓存击穿 缓存雪崩 缓存一致性 分布式缓存系统是三高架构中不可或缺的部分,极大地提高了整个项目的并发量.响应速度,但它也带来了新的需要解决的问题,分别是: 缓存穿透.缓存击穿.缓存雪崩和缓存一致性问题. 缓存穿透 第一个比较大的问题就是缓存穿透.这个概念比较好理解,和命中率有关.如果命中率很低,那么压力就会集中在数据库持久层. 假如能找到相关数据,我们就可以把它缓存起来.但问题是,本次请求,在缓存和持久层都没有命中,这种情况就叫缓存的穿透. 举个例子,如上图,在一个登录系统中,有

  • 详解Java分布式IP限流和防止恶意IP攻击方案

    前言 限流是分布式系统设计中经常提到的概念,在某些要求不严格的场景下,使用Guava RateLimiter就可以满足.但是Guava RateLimiter只能应用于单进程,多进程间协同控制便无能为力.本文介绍一种简单的处理方式,用于分布式环境下接口调用频次管控. 如何防止恶意IP攻击某些暴露的接口呢(比如某些场景下短信验证码服务)?本文介绍一种本地缓存和分布式缓存集成方式判断远程IP是否为恶意调用接口的IP. 分布式IP限流 思路是使用redis incr命令,完成一段时间内接口请求次数的统

  • 基于Java实现Redis多级缓存方案

    目录 一.多级缓存 1. 传统缓存方案 2. 多级缓存方案 二.JVM本地缓存 1. 实用案例 三.缓存一致性 1. 常见方案 1.1 设置有效期 1.2 同步双写 1.3 异步通知 2. 基于Canal的异步通知 2.1 mysql主从复制 2.2 canal 工作原理 一.多级缓存 1. 传统缓存方案 请求到达tomcat后,先去redis中获取缓存,不命中则去mysql中获取 2. 多级缓存方案 tomcat的请求并发数,是远小于redis的,因此tomcat会成为瓶颈 利用请求处理每个环

  • Java本地缓存的实现代码

    使用场景 在 Java 应用中,对于访问频率高,更新少的数据,通常的方案是将这类数据加入缓存中.相对从数据库中读取来说,读缓存效率会有很大提升. 在集群环境下,常用的分布式缓存有 Redis . Memcached 等.但在某些业务场景上,可能不需要去搭建一套复杂的分布式缓存系统,在单机环境下,通常是会希望使用内部的缓存( LocalCache ). 实现 这里提供了两种 LocalCache 的实现,一种是基于 ConcurrentHashMap 实现基本本地缓存,另外一种是基于 Linked

  • 深入浅出探索Java分布式锁原理

    目录 什么是分布式锁?它能干什么? 分布式锁实现方案 基于数据库的分布式锁实现方案 实现原理 方案分析 基于Redis的分布式锁实现方案 基于sentnx命令的实现原理 方案分析 基于Redisson实现 RedLock 方案分析 基于Zookeeper的分布式锁实现方案 实现原理 方案分析 分布式锁方案到底选哪个? 总结 什么是分布式锁?它能干什么? 相信大家对于Java提供的synchronized关键字以及Lock锁都不陌生,在实际的项目中大家都使用过.如下图所示,在同一个JVM进程中,T

  • 从架构思维角度分析分布式锁方案

    目录 1 介绍 2 关于分布式锁 3 分布式锁的实现方案 3.1  基于数据库实现 3.1.1 乐观锁的实现方式 3.1.2 悲观锁的实现方式 3.1.3 数据库锁的优缺点 3.2基于Redis实现 3.2.1 基于缓存实现分布式锁 3.2.2缓存实现分布式锁的优缺点 3.3 基于Zookeeper实现 3.3.1 实现过程 3.3.2 zk实现分布式锁的优缺点 3.4 三种方案的对比总结 1 介绍 前面的文章我们介绍了分布式系统和它的CAP原理:一致性(Consistency).可用性(Ava

  • java分布式面试降级组件Hystrix的功能特性

    目录 引言 1.面试官:能简单介绍下Hystrix有哪些功能吗? 1.1.fail-fast(快速失败) 1.2.Fallback优雅降级机制 1.3.线程/信号量隔离机制 线程隔离: 信号量隔离: 2.面试官:刚刚说到线程隔离,那实际使用中是否打开超时线程中断开关? 3.面试官:那你是如何估计线程池大小的? 深入分析 Hystrix历史 Hystrix的主要功能特性 HystrixDemo 哪些情况下会触发fallback? 附录:Hystrix策略配置 Sentinel与Hystrixres

  • Java分布式服务框架Dubbo介绍

    目录 1.什么是Dubbo? 2.Dubbo核心组件是? 3.Dubbo的工作原理是? 4.介绍一下Dubbo框架分层? 5.Dubbo支持哪些协议? 1.dubbo默认协议: 2.rmi协议: 3.hessian协议: 4.http协议: 5.webservice协议: 6.thrift协议: 7.redis协议: 8.memcached协议: 6.Dubbo核心配置有哪些? 7.Dubbo有哪几种集群容错方案.哪几种负载均衡策略? 8.Dubbo用到哪些设计模式,简要介绍? 9.Dubbo有

  • SpringBoot redis分布式缓存实现过程解析

    前言 应用系统需要通过Cache来缓存不经常改变得数据来提高系统性能和增加系统吞吐量,避免直接访问数据库等低速存储系统.缓存的数据通常存放在访问速度更快的内存里或者是低延迟存取的存储器,服务器上.应用系统缓存,通常有如下作用:缓存web系统的输出,如伪静态页面.缓存系统的不经常改变的业务数据,如用户权限,字典数据.配置信息等 大家都知道springBoot项目都是微服务部署,A服务和B服务分开部署,那么它们如何更新或者获取共有模块的缓存数据,或者给A服务做分布式集群负载,如何确保A服务的所有集群

随机推荐