Redis简介
概括:
Redis是一款功能强大、性能卓著的内存数据库,是现代互联网应用架构中不可或缺的组件之一。将数据主要存储在内存中,因此读写速度非常快,通常能达到每秒数十万次升值上百万次的读写操作。程序员使用Redis的最主要的场景是缓存,可以显著减少数据库的压力,提高应用的响应速度。
什么是缓存?
缓存Cache, 就是数据交换的缓冲区,俗称的缓存就是缓冲区内的数据,一般从数据库中获取,存储于本地代码。
为什么要使用缓存?
1.缓存数据存储于代码中,而代码运行在内存中,内存的读写性能远高于磁盘,缓存可以大大降低用户访问并发量带来的服务器读写压力;
2.实际开发过程中,企业的数据量,少则几十万,多则几千万,这么大数据量,如果没有缓存来作为"避震器",系统是几乎撑不住的,所以企业会大量运用到缓存技术;
3.但是缓存也会增加代码复杂度和运营的成本
redisson实现分布式锁的原理是什么?
分布式锁的核心:使用Redis的set命令配合Lua脚本,结合客户端的看门狗机制,使一个操作要么完全执行成功,要么完全不执行,确保操作的原子性(不可分割);
流程:
1.加锁:当一个线程尝试获取锁时会检查key是否存在,Redisson会向Redis发送一个Lua脚本,类型通常是Hash,key是锁名,field是客户端的唯一标识(客户端Id或线程Id),vlaue是重入次,并设置一个过期时间;如果key不存在就会创建;
如果key已存在,且field正好是客户端的标识,说明可以重入,将value加一,并刷新过期时间;
2.自动续期:成功加锁后,客户但后台会启动一个看门狗的线程,会周期性的检查,当前线程是否还持有这把锁,并重置刷新过期时间;
作用:防止业务逻辑执行时,时间超过过期时间,导致锁自动释放,而业务还没执行完成,引起并发问题;只要线程还在,锁就不会轻易过期;
3.解锁:解锁时,同样会运行Lua脚本,检查锁的持有者是否对应当前客户端;如果是,则将value减一;当value的值为0时,则删除整个锁,真正释放锁,并停止对应的看门狗线程;
简单来说:
把锁看出一个特殊的钥匙,存在Redis里面,哪个线程先成功拿到钥匙,就可以进行后续操作,在这个过程中其他线程无法拿到钥匙,只有等到该程序完成,再重复这个过程;
Redis的缓存穿透,缓存雪崩和缓存击穿是什么?
1.缓存穿透:是指查询一个数据库和缓存中都不存在的数据,导致每次查询都会绕过缓存,直接访问数据库;
危害:恶意攻击者可以利用这个不断的发起请求;缓存中没有,每次都要查询数据库,导致数据库压力剧增;
解决方案:
a.当查询操作时,缓存和数据查询结果都为空时,将一个特殊值(如null)存入缓存,并设置一个较短的时间(1-5分钟);后续相同请求直接从缓存中返回特殊值,不再查询数据库;
b.在缓存层前加一个布隆过滤器,用于快速判断key值是否可能存在;如果过滤器认定不存在,则直接返回,不再查询缓存和数据库;优点空间效率搞,查询快;缺点有极低的误判率;
2.缓存雪崩:是指大量缓存数据在同一时间集中过期,导致所有请求瞬间打回数据库,形成雪崩效应;常见原因:缓存预热不足,导致大量key设置了相同的过期时间;Redis服务宕机或是网络故障;
危害:数据库无法承受巨大流量,可能直接宕机;
解决方案:
a.给缓存的过期时间加一个随机值,避免集体过期;
b.使用Redis集群、主从复制、哨兵,避免单点故障;
c.当服务器压力过大时,返回默认值或提示,保护数据库;
d.使用本地缓存作为第一层,Redis作为第二层,减少对Redis的直接冲击;
3.缓存击穿:是指某个热点数据在缓存过期的瞬间,大量请求涌入,全都放到数据库中,导致数据库压力剧增;
危害:导致数据库压力过大;
解决方案:
a.使用互斥锁,当缓存失效时,不让所有请求都去查数据库,而是让一个线程去重建缓存,其他线程等待;
b.缓存数据不设置Redis过期时间,而是在value中存一个逻辑过期时间;在查询时判断是否过期,如果没有过期直接返回,如果已过期,启动一个异步线程去更新缓存;
c.对于极热点数据,可以设置永不过期,通过后台定期更新;
浙公网安备 33010602011771号