这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天
为什么需要Redis
数据增加、读写数据压力的增加,单表演进出了分表分库,MySQL单机演进出了集群。但是在高QPS场景下,依旧支撑不住。在此基础上,产生了数据分冷热,热数据存储到内存中,也就是说Redis是作为MySQL的缓存使用。
Redis的工作原理
-
Redis持久化原理 AOF/RDB(Redis DataBase/Append Only File)
RDB:Redis 默认的持久化方案,全量数据保存在RDB文件。在指定的时间间隔内,执行指定次数的写操作,则会将内存中的数据写入到磁盘中。即在指定目录下生成一个dump.rdb文件。通过加载dump.rdb文件恢复数据。
AOF:Redis 默认不开启,增量数据保存在AOF文件。它的出现是为了弥补RDB的数据不一致性,所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
重启Redis后,先加RDB文件,再加载AOF文件
-
单线程处理命令的概念
Redis的应用案例和数据结构
- 掘金连续签到,需要了解GET/SET,Key过期
利用 Redis 中的 expire - 实现超时过期,配合 string 使用
Redis 中 string 的数据结构 [len|alloc|flags|buf] 使用场景:存储计数、Session
sds指针指向 flags 和 buf 之间,左移得到元信息,右移得到 value
- 消息通知 - List
用 list 作为消息队列,使用 lpush 逐条向队列传入消息,rpop 逐条消费队列中的信息,数据从队列中移除
Redis 中 list 数据结构 Quicklist 由双向链表和 listpack 实现
listpack - entry: Redis 为了节省内存,将多个元素放在一个节点上
[tot-bytes|num-elements|element-1|element-2|...|listpack-end-byte]
tot-bytes: 整个长度;num-elements: 有多少元素; 每个元素的长度相等;
element: [type|data|len]
- 掘金用户计数,使用到 HASH
对多项计数需求,通过 hash 结构存储,hget 实现值的获取,hincr 根据字段名为字段进行单独的变更
pipelining: 一次性批量设置多个Key,减少网络传输
rehash: hash扩容,当数据量大时,会阻塞用户请求;渐进式rehash:当用户访问时,迁移少量数据,平摊到每次用户访问
- 排行榜ZSET 积分变化和排名的变更
zset数据结构,使集合中的元素能够按 score 进行有序排列
ZRevRank得到排名,ZScore获得分值
zskiplist 跳跃表(双向链表),快速获得有序数据
-
限流
-
使用SETNX实现分布式锁
Redis使用的注意事项
- 大Key:Value大于10KB就是大Key,使用大Key将导致Redis系统不稳定
- 热Key:一个Key的QPS特别高,将导致Redis实例出现负载突增,负责均衡流量不均的情况。导致单实例故障
- 慢查询:大Key、热Kye的读写;一次操作过多的Key(mset/hmset/sadd/zadd)
- 导致缓存穿透、缓存雪崩的场景