面试准备-高并发缓存研究

高并发口诀: 读多写少用缓存,写多读少用队列

使用缓存时难免遇到两个问题: 缓存雪崩、缓存击穿

 

缓存雪崩是指:大批量缓存失效,或者单个缓存的时间突然失效的时间点大批量访问导致都查数据库。

大批量失效我们可以吧过期时间设置成随机的均匀分布。

单个的失效大批量访问,可以加锁,让查库的动作一个人来做。

Lock 这个Api可以实现锁,但是个粗粒度的锁,可以以车次号为键做细粒度的锁。

对于没拿到锁的人可以根据需求做不同的降级策略。

  1. 可以直接让他等锁开,但这样服务器压力大。
  2. 可以给个异常值,直接告诉正忙。
  3. 可以给个特殊值。
  4. 可以查询二级缓存(无过期时间的那种),给他几分钟前的值,二级没有的再给特殊值。

细粒度锁+降级,综合起来比较好。

 

缓存击穿是指,攻击者去访问一个不存在的键去查询。不存在也就没有缓存,直接查到了数据库。

对于不存在的某个键了,多次访问的情况。可以给做空缓存缓解。

但是当大批量不存在的键一起查时,加空缓存杯水车薪。

这是需要给数据库里的数据缓存一个白名单,查库之前先查白名单,有了才能查库。

使用普通的JVM 里的list 的方式可以实现小数据量级别。

当大数据时,存储都是问题,更不用提查找的效率。

这时引入布隆过滤器,需要一个把数据库里的id先进行哈希计算,计算出哈希code,然后存进一个二进制数组中去。

不使用二进制数组之前,一个位置存一个字节的话需要8B,使用之后8个位置才占1B,淘宝10亿商品原来需要存32GB的数据量,现在在一个512M的数组里就可以实现哈希查找。

这里的大数组用redis里的bigmap实现

Long size = Math.pow(2,32);

for(String id:ids){

   long num = (long)Math.abs(id.hashcode() % size);

   redis.setBigMap("bigMap",num,true);

}

找的时候,再算哈希值,利用哈希值查询是否存在。

不存在的话直接返回,避免查库。

 

 

 

你可能感兴趣的:(面试)