当前位置: 首页 > news >正文

小榄网站设计德州手机网站建设服务

小榄网站设计,德州手机网站建设服务,网站如何防采集,个人小程序怎么做当我们在项目中使用到redis的时候,那么势必会考虑如果出现缓存雪崩,缓存击穿,缓存穿透之后会怎么办。下面我们来讲讲解决方案缓存击穿什么是缓存击穿呢?当一个key是热点的时候,在不停的被高流量的请求进行访问的时候。…

当我们在项目中使用到redis的时候,那么势必会考虑如果出现缓存雪崩,缓存击穿,缓存穿透之后会怎么办。下面我们来讲讲解决方案

缓存击穿

什么是缓存击穿呢?当一个key是热点的时候,在不停的被高流量的请求进行访问的时候。如果key在瞬间出现了失效,那么这些大量的请求直接打到数据库中则会可能会导致整个服务的瘫痪或者性能的严重下降。这种情况则是缓存击穿。

那么如何防止出现缓存击穿这种情况呢?

public Object getData(String key) {// 1. 尝试从缓存获取数据Object data = redis.get(key);if (data != null) {return data; // 缓存命中直接返回}// 2. 缓存未命中,获取键对应的锁Lock keyLock = keyLocks.computeIfAbsent(key, k -> new ReentrantLock());try {// 3. 尝试获取锁if (keyLock.tryLock(0, TimeUnit.SECONDS)) {try {// 4. 再次检查缓存(双重检查锁定)data = redis.get(key);if (data != null) {return data;}// 5. 从数据库加载数据data = db.query(key);if (data != null) {// 6. 设置缓存(可设置随机过期时间避免集体失效)int expireTime = 3600 + new Random().nextInt(300); // 基础时间+随机时间redis.setex(key, expireTime, data);} else {// 处理数据库也不存在的情况(防止缓存穿透)// 可设置空值或特殊标记短暂缓存redis.setex(key, 60, "NULL"); // 短暂缓存空值}return data;} finally {// 7. 释放锁keyLock.unlock();keyLocks.remove(key); // 从映射中移除锁}} else {// 8. 未获取到锁,等待并重试Thread.sleep(50);return getData(key); // 递归重试}} catch (InterruptedException e) {Thread.currentThread().interrupt();throw new RuntimeException("获取缓存中断", e);}}
}

上述代码则是主要针对缓存击穿的解决方案:采用单机线程锁的方式来实现。当未在redis查询到当前数据的时候则通过获取当前key的单机锁来实现。并且进行双重校验(防止重复从mysql中取数据)。

为什么使用单机锁而不是分布式锁呢?如果一个集群中有多台机器,那么当前数据的最大并发量最多则是集群的机器数,这些并发量对于数据库来说是扛得住的。同时不采用分布式锁也降低了使用成本。

总的来说一般防止缓存击穿则是在查询不到缓存数据的时候采用单机锁或者分布式锁的方式保证只能一个线程来访问当前数据库这样就不会出现大量请求直接访问数据库的情况了。还有一种方式则是不设置过期时间,也就是key永久存在(不过一般不会这样因为会增大内存的压力)

缓存雪崩

什么是缓存雪崩呢?缓存雪崩则是同一时间出现大量的key过期导致整个系统直接访问数据库的请求过多出现性能下降。

那么这种方式的预防方案则是每个key都加随机时间,这样将每个key散落在不同时刻过期从而减缓了整个系统的压力

if (keyLock.tryLock()) {try {// 4. 再次检查缓存(双重检查锁定)data = redis.get(key);if (data != null) {if ("NULL".equals(data)) {return null;}return data;}// 5. 从数据库加载数据data = db.query(key);// 6. 设置缓存,为每个key设置随机过期时间if (data != null) {// 为每个key生成不同的随机过期时间int expireTime = BASE_CACHE_TIME + random.nextInt(RANDOM_RANGE);redis.setex(key, expireTime, data);}return data;} finally {// 7. 释放锁并从映射中移除keyLock.unlock();keyLocks.remove(key);}} else {// 8. 未获取到锁,等待并重试(但有最大重试次数限制)if (retryCount < MAX_RETRY) {Thread.sleep(LOCK_WAIT_TIME);return getDataWithRetry(key, retryCount + 1);} else {// 超过最大重试次数,直接查询数据库(降级方案)return db.query(key);}}} catch (InterruptedException e) {Thread.currentThread().interrupt();// 中断时直接查询数据库return db.query(key);}}

上述代码则是在将mysql数据库中的数据放回至redis中采用了随机时间的方式来实现的。

还有一种方式则是不添加过期时间

缓存穿透

缓存穿透则是在redis和数据库中都没有这个数据而大量请求请求这个数据则会一直绕过redis来访问数据库从而导致了整个系统的性能下降

预防缓存穿透则是可以每次不管从数据库有没有取到数据都放在redis当中

3. 尝试获取锁(非阻塞方式)if (keyLock.tryLock()) {try {// 4. 再次检查缓存(双重检查锁定)data = redis.get(key);if (data != null) {if ("NULL".equals(data)) {return null;}return data;}// 5. 从数据库加载数据data = db.query(key);// 6. 设置缓存,为每个key设置随机过期时间if (data != null) {// 为每个key生成不同的随机过期时间int expireTime = BASE_CACHE_TIME + random.nextInt(RANDOM_RANGE);redis.setex(key, expireTime, data);} else {// 处理数据库也不存在的情况(防止缓存穿透)redis.setex(key, NULL_CACHE_TIME, "NULL"); // 短暂缓存空值}return data;} finally {// 7. 释放锁并从映射中移除keyLock.unlock();keyLocks.remove(key);}} else {// 8. 未获取到锁,等待并重试(但有最大重试次数限制)if (retryCount < MAX_RETRY) {Thread.sleep(LOCK_WAIT_TIME);return getDataWithRetry(key, retryCount + 1);} else {// 超过最大重试次数,直接查询数据库(降级方案)return db.query(key);}}} catch (InterruptedException e) {Thread.currentThread().interrupt();// 中断时直接查询数据库return db.query(key);}}

或者采用布隆过滤器的方式来进行实现,布隆过滤器则有两种方式分别是白名单和黑名单。白名单则是将数据库有的数据放入到布隆过滤器中,而黑名单则是将redis和库都没有的数据放入到布隆过滤器中。这几种方式则是解决缓存穿透的预防方案

布隆过滤器有着可以判断当前数据是否可能存在而不会准确的判断一定存在。但是如果当前数据存在则不会误判,而当前数据如果不存在则可能误判为存在。

http://www.dtcms.com/a/616519.html

相关文章:

  • 适合大学生做的兼职网站有哪些厦门网上房地产
  • 下载正品官方网站校园网站建设合同百度文库
  • 简单的网页设计作业360优化大师历史版本
  • 苏州手机网站建设多少钱网站建设有哪些项目
  • 网站建设教程吧加强文明网站内容建设
  • 科技网站欣赏江苏城乡建设官网
  • 企业网站建设开发费用小蘑菇网站建设下载
  • django网站开发逻辑设计dedecms 5.7 关闭网站
  • 做网站建设跑业务建设银行手机银行网站登录
  • 网站分站怎么做登陆建设银行网站异常
  • 网站系统建设架构修网络的上门电话多少
  • 罗湖区做网站的公司网站开发语言 .net
  • 企业网站建设与管理简述行唐县做网站电话
  • 苏州专业网站建设招人制作网站
  • 如何建立网站快捷方式深圳小语种网站建设
  • nim_duilib界面库快速上手(Windows系统,VS 2022)
  • 智慧团建网站首页品牌广告
  • 设计网站公司都选亿企邦直播开放平台抖音
  • 重庆永川微网站建设做国外网站销售
  • 做的网站怎么进入互联网微信小程序怎么做调查问卷
  • 湘潭网站制作牙科医院网站建设
  • 网站建设企业熊掌号文档下载免费网站
  • aspx网站模板南昌网站设计专业排名
  • 网站关键词几个知识搜索引擎
  • 苏州 网站建设 app互联网行业分析
  • 卖主机网站网址导航浏览器下载
  • 网站建设项目运营岗晋城市网站建设管理人员
  • 网站建设 淘宝客末班wordpress 整体搬家
  • 广州网站建设互广网站建设费用初步预算
  • 自助游戏充值网站怎么做中国建筑怎么样