一.Redis就是一种数据库。不过这种数据库是放在内存中的,读写速度非常快
二.为什么要使用Redis
1.高性能
第一次访问数据库是访问硬盘上的数据库,第一次访问完后就把数据存在了Redis中,下一次在访问直接就从Redis中访问了,速度很快
2.高并发
直接操作缓存(这里他的这个缓存应该是内存)能够接受的请求是远远大于直接操作数据库的能够接受的请求的。
三.Redis能够操作的数据类型
Srting list hash set SortedSet
四:Redis的使用
https://how2j.cn/k/redis/redis-download-install/1367.html //具体参见这个网址
五:缓存雪崩、缓存穿透和缓存击穿
缓存雪崩:在redis中有大量的缓存在同一时间过期,而查询数据量巨大,引起数据库压力过大甚至down机
缓存击穿:指的是在缓存中没有,但是在数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去读数据库,引起数据库压力瞬间增大,造成过大压力
缓存穿透: 缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
六:如果有大量的key设置同一时间过期,需要注意什么
注意可能发生雪崩,可以在时间上加上一个随机值,是的过期时间分散一点
https://blog.csdn.net/qq_35190492/article/details/102841400
七:Redis为什么是单线程的
先说多线程的缺陷:
1.线程过多,造成操作系统需要在他们之间来回切换,会影响性能
2.还要预防死锁
3.线程会占用更多的内存空间
而因为redis是直接从缓存读数据,速度很快(如果是从硬盘读数据,那么读数据这一部分时间CPU闲置,所以这种情况使用多线程可以),所以CPU不是redis的瓶颈,而单线程又容易实现,所以当然选用单线程了
八:Redis的持久化机制
持久化就是把内存中的数据写到硬盘上
1.RDB就是周期性的把缓存中的数据写到硬盘上
2.AOF会把每条命令写到日志文件中,在Redis重启的时候可以通过回放AOF日志文件中的指令来重新构建整个数据集
通过RDB或AOF,都可以将redis内存中的数据给持久化到磁盘上面来,然后可以将这些数据备份到别的地方去,比如说阿里云,云服务
优缺点再议
九:Redis的非注解使用方式
好像好多种方式,不想总结了
十:Redis的注解使用方式
1.使用的图形化工具名字叫做RedisClient,还要安装好redis服务器
2.在application.property文件中配置redis数据,比如服务器密码,端口等
3.在项目的总接口Application中配置,加入@EnableCaching以启动缓存
4.可以开始进行缓存了,在Service层进行操作,因为在service会进行时机的操作
@CacheConfig(cacheNames="categories") //用来配置缓存的名字,写在整个类上面
@Cacheable(key="'categories-one-'+ #p0") //#p0是方法的第一个参数的值,这里就是id的值
有了这个注解在这个方法上,那么查出来的内容就会存在redis缓存里了
第一次访问的时候, redis 是不会有数据的,所以就会通过 jpa 到数据库里去取出来,一旦取出来之后,就会放在 redis里。 key 呢就是如图所示的 categories-one-84 这个 key。
第二次访问的时候,redis 就有数据了,就不会从数据库里获取了
@Cacheble(key="")
每次方法被执行,如果在缓存中发现了key,就返回缓存中相应的value,反之就会触发函数中的目标方法,并结果加入缓存。
//@Cacheable(value=”accountCache”),这个注释的意思是,当调用这个方法的时候,会从一个名叫 accountCache 的缓存中查询,如果没有,则执行实际的方法(即查询数据库),
//并将执行的结果存入缓存中,否则返回缓存中的对象。这里的缓存中的 key 就是参数 userName,value 就是 Account 对象。“accountCache”缓存是在 spring*.xml 中定义的名称。
@Cacheable(value="accountCache")
public Account getAccountByName(String userName) {
// 方法内部实现不考虑缓存逻辑,直接实现业务
System.out.println("real query account."+userName);
return getFromDB(userName);
}
public Category get(int id) {
Category c= categoryDAO.findOne(id);
return c;
}
@CacheEvict(allEntries=true)//清空所有缓存
@CacheEvict(key="'category-one-'+ #p0") 这里默认的allEntries=false ,然后会清除对应的key里面的数据
@CachePut(key="'category-one-'+ #p0") 把数据保存到对应的key中
public void update(Category bean) {
categoryDAO.save(bean);
}
get 的判断逻辑是先看redis有没有,如果有就取出来用了,如果没有就把 get 方法本身返回的数据保存进 redis了