redis缓存雪崩,缓存穿透和缓存击穿

1.redis雪崩产生原因:

          某一段时间内,缓存集中过期失效。导致大量请求直接访问数据库,增加数据库压力甚至造成数据库崩溃。

          redis服务器宕机(可能直接造成数据库崩溃)。

    和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库

 

2.redis雪崩常见解决方案:

   1.通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

    注意:加锁排队只是为了减轻数据库的压力,并没有提高系统吞吐量。假设在高并发下,缓存重建期间key是锁着的,这是过来1000个请求999个都在阻塞的。同样会导致用户等待超时,这是个治标不治本的方法。

public Users getByUsers(Long id) {
		// 1.先查询redis
		String key = this.getClass().getName() + "-" + Thread.currentThread().getStackTrace()[1].getMethodName()
				+ "-id:" + id;
		String userJson = redisService.getString(key);
		if (!StringUtils.isEmpty(userJson)) {
			Users users = JSONObject.parseObject(userJson, Users.class);
			return users;
		}
		Users user = null;
		try {
			lock.lock();
			// 查询db
			user = userMapper.getUser(id);
			redisService.setSet(key, JSONObject.toJSONString(user));
		} catch (Exception e) {

		} finally {
			lock.unlock(); // 释放锁
		}
		return user;
	}

 

2.不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

 

3.做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期。

 

4.采用mq消息中间件来存储操作数据库的 请求,每次数据库(消费者)只让指定数量的请求连接数据库,其余的则在消息队列中等待,当操作数据库成功后把值写入到redis缓存中,再返回给客户端。

 

 

 

3.redis缓存穿透产生原因:

 缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空。这样请求就绕过缓存直接查数据库,增加数据库的压力,这也是经常提的缓存命中率问题。

 

4.redis缓存穿透解决方案:

    1.查询数据库没有找到值的时候,直接返回null,然后将null或者特定的字符写入redis缓存中。缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。

    2.网关判定查询条件的规则 ,不符合规则的查询条件直接返回null。

    3.布隆过滤器 :布隆过滤器是一种非常高效的数据结构,把所有数据库的value对应的key 存储到布隆过滤器里,几乎不消耗什么空间,而且查询也是相当的快!但是请注意,它只能判断 key 是否存在(而且会有一定的误差)。

 

5.缓存击穿产生原因:

    缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力

 

6.缓存击穿解决方案:

  1. 设置热点数据永远不过期。
  2. 加锁。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值