1、缓存穿透: 要重视,尤其是@Cacheable、返回值可能为null的场景下

import org.springframework.cache.interceptor.CacheAspectSupport;
import org.springframework.cache.interceptor.CacheOperationInvoker;import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;/*** Optional包装工具类,代替@Cacheable场景下的Optional来使用* <p>* {@link org.springframework.cache.interceptor.CacheAspectSupport#execute(CacheOperationInvoker, Method, CacheAspectSupport.CacheOperationContexts)}* <p>* 因为spring-cache不支持Optional.EMPTY, 在将Optional对象set入cache时, 会做拆包* cacheValue = this.unwrapReturnValue(returnValue)* 进而导致从cache中get时,无法区分以下两种情况(为null默认缓存未命中,框架的逻辑,无法绕过):* 1、key存在,value为null* 2、key不存在* 进而导致Optional.EMPTY也无法绕过,引发缓存穿透问题,故写此工具类,代替Optional* <p>* 其次,Optional没有implements Serializable,因此无法使用JDK序列化放入redis* <p>* {@link com.company.ec.cache.redis.RedisClient#put(String, Object, int)} byte[] values = SerializeUtils.serialize(value);* <p>*/
public final class OptionalWrapUtil<T> implements Serializable {private static final long serialVersionUID = 1L;/*** Common instance for {@code empty()}.*/private static final OptionalWrapUtil<?> EMPTY = new OptionalWrapUtil<>();/*** If non-null, the value; if null, indicates no value is present*/private final T value;/*** Constructs an empty instance.** @implNote Generally only one empty instance, {@link OptionalWrapUtil#EMPTY},* should exist per VM.*/private OptionalWrapUtil() {this.value = null;}/*** Constructs an instance with the value present.** @param value the non-null value to be present* @throws NullPointerException if value is null*/private OptionalWrapUtil(T value) {this.value = Objects.requireNonNull(value);}/*** Returns an empty {@code Optional} instance.  No value is present for this* Optional.** @param <T> Type of the non-existent value* @return an empty {@code Optional}* @apiNote Though it may be tempting to do so, avoid testing if an object* is empty by comparing with {@code ==} against instances returned by* {@code Option.empty()}. There is no guarantee that it is a singleton.* Instead, use {@link #isPresent()}.*/public static <T> OptionalWrapUtil<T> empty() {@SuppressWarnings("unchecked")OptionalWrapUtil<T> t = (OptionalWrapUtil<T>) EMPTY;return t;}/*** Returns an {@code Optional} with the specified present non-null value.** @param <T>   the class of the value* @param value the value to be present, which must be non-null* @return an {@code Optional} with the value present* @throws NullPointerException if value is null*/public static <T> OptionalWrapUtil<T> of(T value) {return new OptionalWrapUtil<>(value);}/*** Returns an {@code Optional} describing the specified value, if non-null,* otherwise returns an empty {@code Optional}.** @param <T>   the class of the value* @param value the possibly-null value to describe* @return an {@code Optional} with a present value if the specified value* is non-null, otherwise an empty {@code Optional}*/public static <T> OptionalWrapUtil<T> ofNullable(T value) {return value == null ? empty() : of(value);}/*** If a value is present in this {@code Optional}, returns the value,* otherwise throws {@code NoSuchElementException}.** @return the non-null value held by this {@code Optional}* @throws NoSuchElementException if there is no value present* @see Optional#isPresent()*/public T get() {if (value == null) {throw new NoSuchElementException("No value present");}return value;}/*** Return {@code true} if there is a value present, otherwise {@code false}.** @return {@code true} if there is a value present, otherwise {@code false}*/public boolean isPresent() {return value != null;}/*** Return the value if present, otherwise return {@code other}.** @param other the value to be returned if there is no value present, may*              be null* @return the value, if present, otherwise {@code other}*/public T orElse(T other) {return value != null ? value : other;}
}

2、缓存雪崩: 接口调用比较集中的场景下,注意要预防缓存雪崩,可通过给缓存失效时间添加随机值的方式,来避免缓存集中失效,例如:

    @Overridepublic void put(Object key, Object value, int expireTime) {// 此处不存在安全问题,密码用到的随机数才有安全问题,对于密码学来说ThreadLocalRandom与Random都不安全// 关于线程安全:ThreadLocalRandom与Random都是线程安全的,都做了正确的同步,在并发场景下ThreadLocalRandom性能相比Random以及Math.random()高// Math.random()原理:整个Java应用共用一个Random对象,并发情况下会出现竞争,CAS空转,引起CPU飙高// ThreadLocalRandom原理:每个线程持有自己的Random对象,并发场景下性能较好// 而每次new Random()的话,则会创建大量对象int randomTime = ThreadLocalRandom.current().nextInt(60);super.put(key, value, expireTime + randomTime);}

【Redis】Redis相关相关推荐

  1. php reids的geo功能,Redis GEO相关命令和功能,你造吗?

    Redis 是一个高性能的key-value数据库,其最大优点就是,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用.同时Redis还提供 ...

  2. Redis的相关命令

    最近在学习redis,学习的初衷是做一个分布式的Python爬虫,需要用到redis和scrapy结合,现在才刚刚入门,学习redis相关命令,记录下来. 之前学习过Mysql之类的关系型数据库,初次 ...

  3. 【面试 redis】【第十二篇】redis的相关面试问题【完结】

    redis的相关面试问题==完结,详情查看日记 ========================================== redis教程:http://www.redis.net.cn/t ...

  4. Redis数据库相关知识总结

    Redis数据库相关知识总结 1.NoSQL概述 1.1 为什么用NoSQL 1.单机MySQL的美好年代 在90年代,一个网站的访问量一般不大,用单个数据库完全可以轻松应付! 在那个时候,更多的都是 ...

  5. redis radix相关数据结构

    redis radix相关数据结构如下:

  6. Redis操作相关命令:查看、停止、启动

    一.查看redis是否在运行 ps aux | grep redis 二.命令行直接启动/停止/重启redis 如果是用apt-get或者yum install安装的redis,可以直接通过下面的命令 ...

  7. php 不识别redis,redis,_redis卡死无法读取数据如何解决?,redis - phpStudy

    redis卡死无法读取数据如何解决? 之前是redis dump.rdb 的时候会卡死,然后我关掉了save功能,但是过了一段时间之后又卡死了,这次不知道什么原因,怎样解决了. 以下是info的信息: ...

  8. redis—redis事务

    文章目录 Redis事务的概念 总结: Redis事务的三个阶段 Redis事务相关命令 Redis事务支持隔离性吗? Redis为什么不支持事务回滚? Redis事务其他实现 ----------- ...

  9. Redis——Redis事务性原理

    摘要 本文主要介绍redis事务相关的原理与实战.很多读者看到网络说redis是么有事务处理,但是这个是错误.redis同样的有事务特性.这个和很多人理解的不一样. 一.java传统的事务的处理 事务 ...

  10. Redis Redis Sentinel 基本使用

    Redis & Redis-sentinel 基本使用 本文主要介绍如下几点内容: Redis基本配置 Redis Sentinel基本配置 Redis Client客户端基本内容 Redis ...

最新文章

  1. Hybrid error correction and de novo assembly of single-molecule sequencing reads
  2. spark submit 入门
  3. 信息系统项目管理师-人力资源管理知识点
  4. 【C++】读取文件夹下所有文件名
  5. Spark SQL CLI 运行
  6. 公开调用私有Java方法?
  7. RuntimeError: Can‘t call numpy() on Variable that requires grad. Use var.detach().numpy()
  8. 【gradle】mac下 gradle默认本地仓库位置
  9. 《深入理解Java虚拟机》——垃圾收集器的具体实现
  10. 【报告分享】2019中国社交电商白皮书.pdf
  11. spring cloud微服务分布式云架构-Gateway入门 1
  12. Swift App启动干了什么事情, 删掉UIApplicationMain,自定义实现main类, Main Runloop
  13. 《概率论与数理统计》(浙大第四版)第六章总结笔记(纯手写)
  14. vivox50支持鸿蒙,vivo X50系列极致轻薄的机身下,还有哪些功能和亮点?
  15. TiDB的设计哲学——Make It Work! Make It Right! Make It Fast!
  16. GF(256)下的乘法
  17. 2021-10-17
  18. 研究日记:虚拟歌姬自动调教之歌曲音频切割的问题
  19. 安装torchvision:ImportError:DLL load failed:找不到指定的模块
  20. 字节跳动今日头条笔试题目经历2018

热门文章

  1. 五星填数(全排列问题)
  2. npm中node更新_如何在Node中管理NPM和功能时保持理智
  3. KVM虚拟化介绍和安装使用方法
  4. Docker中创建MySQL容器,将宿主机目录直接挂载到目录
  5. 2023值得我们关注的10种软件测试趋势
  6. css3自学教学,css3精通学习教程(全).pdf
  7. ubuntu18.04应用图标怎么放到桌面
  8. 高仿优酷Android客户端图片左右滑动(自动切换)
  9. Java锁深入理解5——共享锁
  10. warcraft 3 经典语句之月之女祭司(Priestess of the moon)