Redis教程

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

本文主要是介绍Redis 雪崩、穿透、预热、降级,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

雪崩

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

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

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

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

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

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

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

 

穿透

  • 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);
}

 

预热

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

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

降级

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

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

这篇关于Redis 雪崩、穿透、预热、降级的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!