第一部分:Redis基础知识点
- 1、数据类型 - 5种常用基础类型:string,hash,list,set,zset – 字符串,Hash表,List顺序集合,Set无序集合,ZSet有序集合
- 3中特殊类型:bitmap-字节地图, hyperloglog-统计日志,geospatial-地理位置计算
 
- 2、底层数据结构 - String: 基于SDS字典结构
- Hash表 : 由zipList/quickList组成,底层有Dict保存
- List集合: 基于LinkedList数据接口的ZipList和QuickList结构
- Set集合: intSet和Dict组合,其中Dict由Hashtable和DictEntry和Dict组成
- ZSet集合:HashTable+SkipList+IntSet
- 说明: - ZipList压缩表用于当元素数量小于128时,用于对集合压缩,减少内存占用,但是虽节省内存但是需要连续空间,会造成内存碎片
- QuickList则在ZipList上使用LinkedList来避免申请连续空间,减少内存碎片产生
- SkipList跳表则是采用类似于加索引方式,提升查询效率
 
 
- 3、持久化方式 - rdb快照模式, 数据恢复快,效率高,但是会丢失数据
- aof命令拼接模式:数据恢复慢,效率低,数据安全
- 常用RDB+AOF结合方式。
 
- 4、内存淘汰策略 - allkey-lru,allkey-lfu,allkey-random,nonvice,volite-lru,volite-lfu,volite-ttl
- LRU算法:最近最少使用, - 底层原理基于HashTable+LinkedList即Hash表和双向链表实现
- 即HashTable用于快速查找,LinkedList采用后进先出方式,保证最近访问的放在前面,只淘汰尾部即可
 
- LFU算法:最近不频繁使用 - 底层原理使用RedisObject的lru字段的后半部分保存访问的次数
 
- TTL算法:对于设置了存活时间(TTL)的key,TTL值越小,越先淘汰
- Random算法 :随机算法
 
- 5、集群方式 - 主从模式,哨兵模式,代理分片模式,redis-cluster模式
 
- 6、redis常见问题 - 缓存雪崩,缓存穿透,缓存击穿,bigkey,hotkey,双写一致性
 
- 7、redis特性 - 内存,单线程模型,多路复用,epoll
 
- 8、redis锁八大机制 - 加锁,可重入锁,维持加锁-看门狗机制,锁互斥, 手动释放锁,自动释放锁,加锁超时,超时释放锁
 
- 9、过期策略 - 定时过期,惰性过期,定期过期
 
- 10、redis 集群模式 - 主从模式,哨兵模式,Redis-Clustor
 
- 11、Redis为什么快? - 内存模式+内存淘汰策略:内存模式保证查询快,内存淘汰保证安全
- 网络模型 - RESP协议是CS架构,内部数据结构简单,准确
- epoll,非阻塞的多路复用,基于信号IO驱动
- 零拷贝
 
- 持久化,保证数据安全性
- 原子事务
 
- 12、Redis的特性 - 内存,持久化,事务,Io多路服务,Epoll机制
 
第二部分:Redis实战场景
1、Redis的应用场景
- 1、分布式缓存:旁路缓存,对象缓存,全页缓存,热点数据缓存
- 2、分布式锁
- 3、分布式Session共享
- 4、分布式唯一ID生成
- 5、分布式限流
- 6、计数器
- 7、排行榜
- 8、位统计功能:签到打卡,用户留存率,用户活跃度
- 9、延时操作:
- 10、点赞,关注和推荐,朋友圈可见
- 11、消息队列
- 12、抽奖
- 13、标签
- 14、过滤(布隆过滤器),筛选
- 15、业务处理:交集,差集,并集
2、Redis问题以及解决方案
- 1、缓存雪崩 - 原因: 缓存同时过期
- 方案: - (1)加随机过期时间
- (2)多级缓存
- (3)限流+读锁
 
 
- 2、缓存穿透 - 原因:大量访问缓存和数据库不存在数据
- 方案: - (1)访问校验
- (2)Hash拦截
- (2)布隆过滤
- (3)空值缓存
- (4)混合方式解决,即空值短缓存,频繁请求加校验
 
 
- 3、缓存击穿 - 原因:热点数据过期
- 方案: - (1)多级缓存
- (2)不过期
- (3)加锁
 
 
- 4、热点key问题 - 原因:热点数据超频繁,造成服务过载
- 方案: - (1)多级缓存
- (2)集群扩容,分片负载
- (3)热点分散
 
 
- 5、redis大key问题 - 原因:Hash,List,set,zset等集合由于时间累积造成key过大
- 方案: - (1)定时过期重建key
- (2)压缩value
- (3)拆分bigkey
- (4)定期检查key移除失效元素,进行瘦身
 
 
- 6、双写一致性问题 - 原因:高并发场景下缓存和DB更新导致读写不一致问题
- 方案:
 - 1、更新cache,更新DB-问题:更新DB失败造成脏数据
 - 2、更新DB,更新Cache-问题:更新Cache失败造成脏数据
 - 3、删除cache,更新DB-问题:高并发场景,会读取到未更新DB的脏数据
 - 4、延迟双删,删除Cache,更新DB,删除Cache:一定程度上可以保证,但是
 - 5、更新DB,延迟更新Cache-通过Canol或MQ方式延迟更新Cache,某种方式来说可以解决更新Cache失败问题
 
第三部分:深入Redis原理
1、Redis数据类型以及应用场景
- 数据类型 - string,Hash,List,Set,ZSet,BitMap,Geo,LogLog
 
- 使用场景: - 分布式缓存(旁路缓存,读写缓存),分布式锁,分布式Session,
- 计数器,布隆过滤器,限流器
- 消息队列,秒杀,红包,抽奖.点赞,关注,签到,榜单,
 
2、持久化机制
- 持久化方式 - RDB方式:恢复快,文件小,数据安全低 - RDB持久化:save指定触发后,redis会fork出一个线程,拷贝出当前运行时副本,成功后
 
- AOF方式:内容多,文件大,恢复慢,数据安全高 - AOF大小触发重做后,redis会fork出一个新线程,拷贝出当前运行时数据副本的保存命令,后再执行增量数据命令
 
 
- RDB方式:恢复快,文件小,数据安全低 
- 持久化策略 - 自动保存,手动保存
 
3、redis锁机制,事务机制,原子性等
- 锁机制 - 过程 - getLock,如果true,则setnx,执行程序,主动释放lock,完成,如果程序超时,通过expire被动释放lock
- getLock,如果false,则自旋等待已经占有锁线程释放lock
 
- 作用: - 保证分布式环境下,线程竞争资源的正常运行。
 
 
- 过程 
- 原子性 - redis的原子操作指令:incr和decr,setnx
- 自定义实现方式 - 使用Lua脚本
- 使用事务+监控方式: - 1、监控:watch key,2、事务开始:MULTI,3、定义事务原子操作:SET key 100 4、执行事务: EXEC
 
 
 
- 事务机制 - 原子性,一致性,隔离性,持久性,顺序性
- Redis事务流程 - 事务开始 MULTI,WATCH,命令入队,取消入队DISCARD,事务执行 EXEC
 
 
2、Redis的数据结构
- SDS 动态字符数组,每个数组由头部,len,freelen组成
- LinkedList 双向链表结构
- ZipList 压缩链表结构,集合长度小于512或长度小于64k时采用压缩表结构
- QuickList 快速链表结构,v3.2以后改进,由linked+ziplist组成,linkedlist保证快速遍历,ziplist保证数据压缩
- hashtable 哈希表结构,redis全局也是hash表结构
- skiplist - 跳表结构-结构上结点之间有多个指针,能够根据key快速跳到对应的位置
3、Redis快速的原因
- 基于内存实现的KV结构,便于快速查找
- 高效的数据结构和数据编码
- 单线程模型,避免线程上下文切换
- 高效的网路传输协议,使用epoll实现IO多路复用机制
- 高效的内存淘汰机制,保证缓存命中率
4、Redis线程模型,IO模型,网络模型等
- 线程模型 - 单线程模型:即网络请求采用单线程,分为文件事件处理器-包括请求连接,命令请求,命令响应
- 多线程模型:连接,持久化,语法检查
 
- 网络Io模型 - 参考JavaIO模型
 
- 多路复用 - 多路是网络请求多路
- 复用是处理线程复用
 
- 内存模型 - 本身内存,数据内存,缓冲内存,碎片内存