【Redis】Redis相关
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相关相关推荐
- php reids的geo功能,Redis GEO相关命令和功能,你造吗?
Redis 是一个高性能的key-value数据库,其最大优点就是,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用.同时Redis还提供 ...
- Redis的相关命令
最近在学习redis,学习的初衷是做一个分布式的Python爬虫,需要用到redis和scrapy结合,现在才刚刚入门,学习redis相关命令,记录下来. 之前学习过Mysql之类的关系型数据库,初次 ...
- 【面试 redis】【第十二篇】redis的相关面试问题【完结】
redis的相关面试问题==完结,详情查看日记 ========================================== redis教程:http://www.redis.net.cn/t ...
- Redis数据库相关知识总结
Redis数据库相关知识总结 1.NoSQL概述 1.1 为什么用NoSQL 1.单机MySQL的美好年代 在90年代,一个网站的访问量一般不大,用单个数据库完全可以轻松应付! 在那个时候,更多的都是 ...
- redis radix相关数据结构
redis radix相关数据结构如下:
- Redis操作相关命令:查看、停止、启动
一.查看redis是否在运行 ps aux | grep redis 二.命令行直接启动/停止/重启redis 如果是用apt-get或者yum install安装的redis,可以直接通过下面的命令 ...
- php 不识别redis,redis,_redis卡死无法读取数据如何解决?,redis - phpStudy
redis卡死无法读取数据如何解决? 之前是redis dump.rdb 的时候会卡死,然后我关掉了save功能,但是过了一段时间之后又卡死了,这次不知道什么原因,怎样解决了. 以下是info的信息: ...
- redis—redis事务
文章目录 Redis事务的概念 总结: Redis事务的三个阶段 Redis事务相关命令 Redis事务支持隔离性吗? Redis为什么不支持事务回滚? Redis事务其他实现 ----------- ...
- Redis——Redis事务性原理
摘要 本文主要介绍redis事务相关的原理与实战.很多读者看到网络说redis是么有事务处理,但是这个是错误.redis同样的有事务特性.这个和很多人理解的不一样. 一.java传统的事务的处理 事务 ...
- Redis Redis Sentinel 基本使用
Redis & Redis-sentinel 基本使用 本文主要介绍如下几点内容: Redis基本配置 Redis Sentinel基本配置 Redis Client客户端基本内容 Redis ...
最新文章
- Hybrid error correction and de novo assembly of single-molecule sequencing reads
- spark submit 入门
- 信息系统项目管理师-人力资源管理知识点
- 【C++】读取文件夹下所有文件名
- Spark SQL CLI 运行
- 公开调用私有Java方法?
- RuntimeError: Can‘t call numpy() on Variable that requires grad. Use var.detach().numpy()
- 【gradle】mac下 gradle默认本地仓库位置
- 《深入理解Java虚拟机》——垃圾收集器的具体实现
- 【报告分享】2019中国社交电商白皮书.pdf
- spring cloud微服务分布式云架构-Gateway入门 1
- Swift App启动干了什么事情, 删掉UIApplicationMain,自定义实现main类, Main Runloop
- 《概率论与数理统计》(浙大第四版)第六章总结笔记(纯手写)
- vivox50支持鸿蒙,vivo X50系列极致轻薄的机身下,还有哪些功能和亮点?
- TiDB的设计哲学——Make It Work! Make It Right! Make It Fast!
- GF(256)下的乘法
- 2021-10-17
- 研究日记:虚拟歌姬自动调教之歌曲音频切割的问题
- 安装torchvision:ImportError:DLL load failed:找不到指定的模块
- 字节跳动今日头条笔试题目经历2018