- Redis的数据类型及其底层数据结构
- String:SDS
- List:双向链表/压缩列表
- Set: 哈希表
- Zset:哈希表+跳表
- Hash:哈希表/压缩列表
- Redis持久化方式
- AOF:追加记录写操作命令
- 刷盘时间节点为:立即、每秒、由操作系统决定
- 当AOF日志文件过大会触发重写机制
- RDB:将内存数据以二进制方式写入(save/bgsave)
- 混合:AOF+RDB
- AOF:追加记录写操作命令
- Redis常用命令
- del、exists、TTL、expire、persist key、type key
- Redis过期策略
- 惰性删除(CPU友好,内存不友好):不删除过期key,当key被访问时检查是否过期,过期则删除
- 定期删除(CPU不友好,内存友好):定期从key中抽取一定量的key,删除其中的过期key,如果过期key的比例大于一定值则继续抽取删除
- Redis淘汰策略
- 在设置了过期时间的key中进行淘汰
- 随机、淘汰最早过期的、淘汰最少使用的(LFU)、淘汰最久未使用的(LRU)
- 在所有key中进行淘汰
- 随机、LRU、LFU
- 在设置了过期时间的key中进行淘汰
- Redis缓存雪崩、击穿、穿透的解决方式
- 缓存雪崩:大量key同时过期,对应的请求全落在了数据库上,造成很大压力
- 尽量让每个key的过期时间设置的随机,例如在原有的过期时间上加上一个随机值
- 缓存击穿:热点key的过期带来了大量的直接访问数据库的并发请求压力
- 互斥锁方案,在setnx方法上设置一个状态位,同一时间只有一个线程能访问缓存,其他的线程要么阻塞要么返回默认值
- 针对热点key设置后台线程异步更新、或者热点key过期前提前通知后台线程进行更新
- 缓存穿透:大量请求访问的数据不在缓存也不在数据库中(原因是业务误删或者恶意攻击)
- 提前检测请求参数是否合法,请求字段是否存在来避免恶意攻击
- 针对数据库中不存在的数据设置空值缓存
- 使用布隆过滤器来快速判读数据是否存在
- Redis热点key和大key的处理方式
- 大key问题:操作大key时容易引起阻塞、内存分布不均
- 定位大key:redis -cli --bigkeys
- 定位大key:使用rdb dump.rdb如何分析
- 热点key:发现与解决
- 发现:预估或者通过proxy收集
- 解决:备份,将热点key备份在多台机器上
- 解决:二级缓存,将热点key备份在jvm的本地缓存
- 大key问题:操作大key时容易引起阻塞、内存分布不均
- 删除大key时使用unlink,而不是del,因为del是主线程处理,会阻塞主线程;
- Redis为什么单线程还这么快
- Redis是大部分操作基于内存的,而且采用了高效的数据结构,其性能瓶颈不是CPU
- Redis采用的是单线程,避免了多线程竞争切换带来的开销
- Redis采用了I/O多路复用机制,一个线程可以处理多个I/O流
- Redis实现服务高可用
- 主从复制
- 哨兵机制:监控,选主、通知
- Redis实现延迟队列
- 利用zset的score属性:zadd score1 value1
- Redis实现分布式锁(set NX)
- 注意点:需要设置合理的超时时间、锁变量的值唯一标识身份
- 缺点:超时时间不会设置,主从异步复制可能引起分布式锁失效