60-分布式缓存架构-缓存雪崩&穿透&命中率

1. Redis雪崩效应产生的原因

缓存雪崩的原因

2. Redis雪崩效应解决方案
  1. 分布式锁或者本地锁
  2. 使用消息中间件(最靠谱)
  3. 一级和二级缓存(redis+ehcache)
  4. 均摊分配redis key的失效时间。比较靠谱
3. 使用锁解决redis雪崩效应
@RequestMapping("/getUsers")
	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;
	}
4. 使用mq解决redis雪崩效应

mq处理缓存雪崩

5. 穿透与命中率问题

在这里插入图片描述

6. 穿透解决方案
public String getByUsers2(Long id) {
		// 1.先查询redis
		String key = this.getClass().getName() + "-" + Thread.currentThread().getStackTrace()[1].getMethodName()
				+ "-id:" + id;
		String userName = redisService.getString(key);
		if (!StringUtils.isEmpty(userName)) {
			return userName;
		}
		System.out.println("######开始发送数据库DB请求########");
		Users user = userMapper.getUser(id);
		String value = null;
		if (user == null) {
			// 标识为null
			value = SIGN_KEY;
		} else {
			value = user.getName();
		}
		redisService.setString(key, value);
		return value;
	}

热点key

热点key:某个key访问非常频繁,当key失效的时候有大量线程来构建缓存,导致负载增加,系统崩溃。

解决办法:
①使用锁,单机用synchronized,lock等,分布式用分布式锁。
②缓存过期时间不设置,而是设置在key对应的value里。如果检测到存的时间超过过期时间则异步更新缓存。
③在value设置一个比过期时间t0小的过期时间值t1,当t1过期的时候,延长t1并做更新缓存操作。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值