# redis 使用规范 ### 1、核心业务数据和边缘业务数据分离 这两类数据分开为不同的缓存实例,避免边缘业务影响核心业务服务; ### 2、数据缓存按业务功能分离 不能将众多的业务服务依赖同一缓存实例,而应该按业务进行拆分(尤其是核心的高并发的数据应单独的缓存服务实例)。 ### 3、缓存key命名规范 包括三个维度来命名(命名空间、数据分类名、变量),三者之间采用冒号“:”隔开 ### 4、提升访问性能(pipline) 多个操作命令发送到服务端,客户端不依赖每个操作命令返回的结果(即可批量化)时,可以使用pipline机制减少tcp往返次数,提升redis访问性能; ### 5、实现优雅删除(unlink) del指令会同步释放对象内存,大部分情况下没有问题,当遇到比较大的key时(如上千万记录的list、hash等),则该指令会造成服务卡顿;因此redis从4.0版本开始发布了unlink指令来解决该问题。 unlink用于替代del指令,解决大key删除卡顿问题。在执行unlink指令时redis第一步将key从redis空间摘除此key的引用,第二步会在一个异步线程中释放此key的内存(因是异步的,不会对工作线程造成影响)。 ### 6、安全遍历(scan) 线上应避免使用keys指令,keys会遍历redis中所有的key,当key的数据达到千万时,执行该指令会导致服务卡顿;可以采用scan指令带上limit参数来替代keys。 redis是单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用**scan**指令,**scan**指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。 ### 7、预防缓存击穿(缓存默认值) 当查询的数据在Redis数据库本身不存在时,每次请求一般都会查询数据库。恶意用户会利用此场景对数据库进行攻击从而影响服务。可以采用下发的方式进行预防: 从数据库查询不到数据时,在缓存中设置一个特殊的默认值并设置一个较短的过期时间。 #### 常见攻击 - 缓存击穿 当我们缓存key设置过期时间,恰巧在这一刻这个key在某一刻被高并发的访问,把所有的请求都打到了DB中这就可能会导致DB挂了。 **缓存击穿**的话,设置热点数据永远不过期。或者加上互斥锁就能搞定了 或者 **使用分布锁,使一个线程去重新回原数据,其他请求返回空值,UI友好提示。** - 缓存穿透 使用大量不存在的key发布访问,由于缓存中找不到,故把所有请求全都打到DB中,使用DB压力巨增,导致DB挂掉。 **缓存穿透**我会在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等。 **1. 使用Boolm过滤器,2. 使用Hystrix第三方组件进行限流、溶断,从而保护服务器。** - 缓存雪崩 雪崩指的是多个key同时失效,当高并发的请求过来所有请求都打到数据库导致挂了 **处理缓存雪崩简单,在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效** ``` setRedis(Key,value,time + Math.random() * 10000); ``` 或者设置热点数据永远不过期,有更新操作就更新缓存就好了 ### 8、缓存失效(加锁) 高并发时,如果缓存失效,会有大量的请求打到数据库,对数据库造成瞬间冲击,影响服务质量,因此在查询数据库加载到缓存时需要加锁,以预防数据库瞬间流量冲击。