版权声明:已标记,所属内容不得不转载 https://blog.csdn.net/qq_42350238/article/details/89016465
1.概念: redis是一款高性能的NOSQL系列的非关系型数据库
Redis 本质上是一个 Key-Value 类型的内存数据库,纯内存操作
redis 最大的魅力是支持保存多种数据结构,此外单 个 value 的最大限制是1GB,另外 Redis 也可以对存入的 Key-Value 设置 expire 时间。
2.支持的数据类型 values
string list set hash sorted set
3.Reis 的持久化
redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
RDB:默认)指定的时间间隔内生成数据集的时间点快照,定时的时间快照,那个时间段内出现问题,数据会丢失的,有点危险,
AOF:记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集
要想数据的尽量少丢失,选用aof,因为aof可以每秒钟度写入一次命令,就算是出现故障也就是会丢失那一秒钟的数据,如果磁盘存满的话,redis-check-aof 工具也可以轻易地修复这种问题。会修复这个问题;
用这个技术的时候有没有遇到问题????
问题:缓存雪崩,以及缓存穿透,
缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
方案一:缓存空对象
* 此种方式存在漏洞,不经过判断就直接将Null对象存入到缓存中,
* 如果恶意制造不存在的id那么,缓存中的键值就会很多,恶意攻击时,很可能会被打爆,所以需设置较短的过期时间。
*
* @param id
* @return
*/
public Object getObjectInclNullById(Integer id) {
// 从缓存中获取数据
Object cacheValue = cache.get(id);
// 缓存为空
if (cacheValue != null) {
// 从数据库中获取
Object storageValue = storage.get(key);
// 缓存空对象
cache.set(key, storageValue);
// 如果存储数据为空,需要设置一个过期时间(300秒)
if (storageValue == null) {
// 必须设置过期时间,否则有被攻击的风险
cache.expire(key, 60 * 5);
}
return storageValue;
}
return cacheValue;
}
缓存空对象会有一个必须考虑的问题:
空值做了缓存,意味着缓存层中存了更多的键,需要更多的内存空间(如果是攻击,问题更严重),比较有效的方法是针对这类数据设置一个较短的过期时间,让其自动剔除