本篇主要是个人的一些感受。在没有缓存之前,高并发下所有的请求都会直接怼到数据库,如mysql上。如果服务器是机械硬盘,则mysql的并发请求也就在300左右,如果是固态硬盘则是700左右就已经不错了。如果并发量再大一点,mysql就会抛出异常,too many connections ,也就是数据库瘫痪了。
缓存此时应运而生,缓存作为数据库的屏障,可以先挡下大部分请求。以redis缓存为例,我们可以先从缓存中取数据,如果取不到,则查询数据库,然后将查询的数据再次放入redis。这里涉及一个问题是数据的同步性,如果数据库的数据变了,如果更新缓存,有三种方法
1.强一致性,通过aop或缓存工具类实现,每次更新数据库,手动更新缓存,缺点是耦合性大
2.准一致性,消息队列实现
3 弱一致性,将缓存设置有效期,失效后,重新查询数据库,优点是简单,无耦合
方案3会引入另一个问题,缓存雪崩,如果大量的key同一时间失效,还是会有很多请求怼到数据库,依然会瘫痪,首先想到的是加锁,建议用lock锁,加锁之后,数据库不会瘫痪,但是吞吐量会下降很多。比如一万个请求去竞争一把锁,那如何才能提高效率呢?我们可以多设置几把锁,我们维护一个concurrentHashMap ,不用hashMap是因为线程不安全。 ConcurrentHashMap<String,Lock> 类似一个这样的接口,map的key为我们的请求参数,这个需要我们根据实际场景去定义,比如一张表存有全中国人的工资,我们查询每个中国人的工资,可以将省份作为key,这样我们就有34把锁,因为是34个省份。也可以将性别作为key,只有两把锁这样。这样我们就可以提高吞吐量。
缓存为何出现及演变过程
最新推荐文章于 2022-02-07 13:46:55 发布