用空间换时间。使用缓存后,运行时间更短了!
例子:
读取上图中的收益详情:138.24
比较从数据库读或者从缓存中读时的时间。
当一个语句的查询时间超过300毫秒的时候,就要优化语句了。
用mybatis实现
收益的实体类为:
Mapper接口如下:
业务代码如下:
注入数据库的Dao层
private ProfitDetailMapper mapper;
注入一个缓冲的操作类:
private CacheService cs;
解决缓存一致性的问题
第一种方法:更新数据库的时候,同时更新缓存。不会出现雪蹦。
耦合大,不适合写操作少的粗粒度场景。适合对实时性要求高的数据,例如证券的股票
例如一个user的信息就是细粒度的数据。收益,属于统计类的数据,属于粗粒度的数据。
第二种方法:数据准实时更新,数据有较短的延迟,数据不一致的时间很短。不适合写操作频繁。大多使用MQ
在该方案中3、4、5步需要一致型,需要补偿机制。
1.设计重试机制,例如数据库连接不好,连接不上,就重试设定的次数。重试几次不成功的话,将该信息存入方法表中,后续提供给运维人员查看,或者邮件或者短信通知运维人员。
基本上很多互联网都是这种读多大幅度多余写场景,所以这种方式在互联网中使用场景很多。
第三种方法:缓存失效机制
设置缓存失效时间:
设置缓存失效时间是3秒
优点:业务代码不用管缓存。存在缓存雪崩。一般是合适和第一种,或者第二种方法结合使用
适合读多写少的互联网场景,能接受数据的延时。能保重最终一致性。
例如点赞,就是缓存的使用场景。允许一定的延时
在使用缓存失效机制时,就会带来了缓存雪崩问题。
缓存是数据库的屏障。在数据请求的一瞬间,缓存失效了,就需要去数据库的查询了。
数据库的连接池耗光了,系统崩了!
模拟高并发
模拟1000个线程并发
第一个线程准备后,让其运行run后,在run中阻塞住,只有所有1000个创建完成后,在一起运行,实现并发。
加一个锁,防止1000个线程过来了。把请求后的数据,再放到缓存中,防止后续的线程的数据库锁请求