微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Redis 雪崩、穿透、预热、降级

雪崩

  • Redis缓存雪崩和穿透乍一看好像差不多,概念容易混淆。而解决方案的思路是让失效时间达到均匀的情况。

  • 缓存雪崩是指在我们设置缓存失效时间上时采用了相同的过期时间,导致缓存在某一时刻同时失效。请求全部打到后端数据库数据库一时请求过大,数据库cpu和IO一时负载过大,造成雪崩。如果不能理解的话,闭上眼睛想象一下,雪山崩塌的场景。

  • 业界有常见的解决方案,没有哪一种方案是完美的,需要结合实际的并发情况选择最合适的方案。

  • 第一种是加锁排队,其本质是一种缓冲方案,允许等待。弊端是从用户角度来说体验不是很好。

  • 第二种是mutex互斥锁,比如Redis分布式锁SetNX。如果缓存里面没有并不是去加载数据库

  • 第三种是限流,在@R_502_6223@来时缩紧。或者使用令牌桶,漏桶算法。

  • 第四种是二级缓存,比如在缓存服务的基础上加上本地缓存,在缓存服务失效的情况下查询本地缓存而不是数据库

 

穿透

  • Redis穿透是大量的请求在缓存没有命中,比如每次都查询一个不存在的值。导致每次都要去数据库查询,这样导致缓存被穿透了,从而增加数据库的压力。

  • Bloom filter,布隆过滤器实际上是一个很长的二进制向量和一系列随机映射函数

  • 我们知道Redis 之所以快是因为单线程避免了cpu上下文切换。并且采用了epoll 机制,还有一个重要的原因就是他的存储结构,时间复杂度是o(1)。为了减少存储空间Bloom Filter 是一种改善方案。

  • 但是使用起来一定要谨慎,Bloom Filter 存在一定的概率误判,我们在学术上成为假阳性。随着元素的增加这种误判的几率会随之增加,但是一般情况下可以忽略。

  • 缓存这些空对象,但是注意失效时间设置小一点,防止Redis的key过多。

  • 在Guava中的实现,funnel:输入的数据,xpectedInsertions:预估计插入的元素总量,fpp:你自己想达到的误判率,strategy:实现的实例。

static <T> BloomFilter<T> create(
Funnel<? super T> funnel, long expectedInsertions, double fpp, Strategy strategy) {
checkNotNull(funnel);
checkArgument(
expectedInsertions >= 0, "Expected insertions (%s) must be >= 0", expectedInsertions);
checkArgument(fpp > 0.0, "False positive probability (%s) must be > 0.0", fpp);
checkArgument(fpp < 1.0, "False positive probability (%s) must be < 1.0", fpp);
checkNotNull(strategy);
if (expectedInsertions == 0) {
  expectedInsertions = 1;
}
/*
 * Todo(user): Put a warning in the javadoc about tiny fpp values, since the resulting size
 * is proportional to -log(p), but there is not much of a point after all, e.g.
 * optimalM(1000, 0.0000000000000001) = 76680 which is less than 10kb. Who cares!
 */
long numBits = optimalNumOfBits(expectedInsertions, fpp);
int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits);
try {
  return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, strategy);
} catch (IllegalArgumentException e) {
  throw new IllegalArgumentException("Could not create BloomFilter of " + numBits + " bits", e);
}

 

预热

  • 缓存预热就是系统发布之前,先把缓存数据加载到系统里面,这样避免了活动正式开始之前首次没有命中,需要查询数据库的问题。

  • 另外一方面预热也是提前对流量的一种预估方式,很多大型活动或者秒杀,都会提前来一波预热。

降级

  • 并发量很大的时候,响应慢或者超时,影响到核心业务处理(比如下单,支付),或者导致到上游的系统的系统扇出,这种情形下需要对服务进行降级,也就是丢车保帅的做法。

  • 级,也就是丢车保帅的做法。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐