1. redis 使用规范

1.1. 1、核心业务数据和边缘业务数据分离

这两类数据分开为不同的缓存实例,避免边缘业务影响核心业务服务;

1.2. 2、数据缓存按业务功能分离

不能将众多的业务服务依赖同一缓存实例,而应该按业务进行拆分(尤其是核心的高并发的数据应单独的缓存服务实例)。

1.3. 3、缓存key命名规范

包括三个维度来命名(命名空间、数据分类名、变量),三者之间采用冒号“:”隔开

1.4. 4、提升访问性能(pipline)

多个操作命令发送到服务端,客户端不依赖每个操作命令返回的结果(即可批量化)时,可以使用pipline机制减少tcp往返次数,提升redis访问性能;

1.6. 6、安全遍历(scan)

线上应避免使用keys指令,keys会遍历redis中所有的key,当key的数据达到千万时,执行该指令会导致服务卡顿;可以采用scan指令带上limit参数来替代keys。

redis是单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。

1.7. 7、预防缓存击穿(缓存默认值)

当查询的数据在Redis数据库本身不存在时,每次请求一般都会查询数据库。恶意用户会利用此场景对数据库进行攻击从而影响服务。可以采用下发的方式进行预防:

从数据库查询不到数据时,在缓存中设置一个特殊的默认值并设置一个较短的过期时间。

1.7.1. 常见攻击

  • 缓存击穿 当我们缓存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);
    

    或者设置热点数据永远不过期,有更新操作就更新缓存就好了

1.8. 8、缓存失效(加锁)

高并发时,如果缓存失效,会有大量的请求打到数据库,对数据库造成瞬间冲击,影响服务质量,因此在查询数据库加载到缓存时需要加锁,以预防数据库瞬间流量冲击。