缓存的有关问题

本文探讨了使用JVM缓存的空间换时间策略,分析了缓存模型的局限性和扩展性问题,并介绍了如何利用AspectJ进行代码改造,实现缓存的高效管理和避免缓存击穿与雪崩现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 使用jvm的空间换时间

当缓存达到一定程度后,容易引发OOM问题

2.该缓存位于一个jvm 里面

该缓存不能共享
在这里插入图片描述

3 缓存的模型对代码的改造太大,不容易扩展

在这里插入图片描述

在这里插入图片描述
.3.1 引入切面的包

    aspectj
    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.7</version>
    </dependency>

3.2 定义一个切面类
在这里插入图片描述

3.3 切点的切入
大家有会切面表达时的写法
@Around(“execution (* com.sxt.service.impl.MenuServiceImpl.loadAllMenu())”)
3.4 实现环绕通知的逻辑

@Component
@Aspect
public class CacheAspect {

	private static Map<String,Object> caches = new HashMap<>();
	
	private static final String ALL_MENU_LABEL = "alll-menu-data"; 
	
	@Around("execution (* com.sxt.service.impl.MenuServiceImpl.loadAllMenu())")
	public Object cache(ProceedingJoinPoint ponit) {
		if(caches.containsKey(ALL_MENU_LABEL)) {
			System.out.println("缓存里面有");
			return caches.get(ALL_MENU_LABEL);
		}
		
		Object result = null ; 
		try {
			System.out.println("执行真实方法的调用");
			result = ponit.proceed(ponit.getArgs()); // 在此实现了真实方法的调用
//			放入缓存
			caches.put(ALL_MENU_LABEL, result);
		} catch (Throwable e) {
			e.printStackTrace();
		}

		return result;
	}
}

缓存的击穿

在这里插入图片描述

Select * from t_user where id = -10;
查询的数据一致无法命中缓存(缓存里面一直没有)
在这里插入图片描述
那缓存击穿的本质原因是:
有些数据在缓存中没有,在数据库中也没有,这样导致每次访问缓存,都查不到,结果必须落到去查数据库,但是数据库也没有,这样就导致每次一访问这样的数据,都会既查缓存,又查数据库,大大的浪费了时间,还增加了访问压力。
通常可以用这样的方式避免这个问题,如果在数据库中不存在的话,就在缓存中做一个空标志,(比如new 一个新对象,但是这个对象的字段都是空的。)数据库数据实时同步到缓存中,以后对这些数据的访问,直接就能在缓存中查到,就不需再查数据库了,通过查询缓存发现得到的为空的标志,就直接返回。
1 在执行查询之前,如果预先知道数据库里面没有这个值,我可以不查询数据库
2 查询数据库,发现没有该值,现在我在缓存里面缓存一个null 值

缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。

缓存击穿和缓存雪崩有点类似,区别是缓存击穿针对的是某一个非常热点的key,这个key在某一时刻失效造成所有请求都访问数据库;缓存雪崩是针对一系列缓存同时失效,造成大量请求访问数据库造成雪崩。

缓存击穿也可以使用加锁的方式,让只有一个线程查询数据库写缓存,其他线程等待。

缓存的雪崩

在这里插入图片描述
当黑客使用大量的数据测试(不止是-1 ,-1–> 无穷)则缓存里面可能缓存很多null,null 也占用空间,过一个缓存慢了,无法存入新的值了,该现象被称为缓存的雪崩。

解决方案

产生的原因是:数据库里面,没有该值产生的
若实现知道该数据库里面没有该值,这个问题就可以解决。要求不能查数据。
HashSet
在这里插入图片描述
在这里插入图片描述
什么数据结构不占内存
1 int = 4个字节=48 = 32 bit
1bit 内存占用下来了
图片怎么存储(1980
1080p)
位图-> 存储图片

在这里插入图片描述
借着该图片的存储,我们可以使用BloomFilter

在这里插入图片描述
有关的优秀文章


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值