这是我参与「第五届青训营 」笔记创作活动的第13天
Redis,作为以性能著称的KV数据库,在实际业务中使用已经非常广泛。如果没有Redis做缓存,Mysql很难能够承载那么大的请求量。
为什么需要Redis
数据分冷热,将热数据放在内存当中。
Redis基本工作原理
- 数据从内存中读写
- 数据保存到硬盘上防止重启数据丢失
- 增量数据保存到AOF文件
- 全量数据RDB文件
- 单线程处理所有操作命令
Redis那么快,除了单线程、基于内存等,还有它特殊的数据结构。
Redis应用实例
连续签到
- 在Redis中设置一个值,后天的0点过期
- String数据结构,sds,使用在存储计数、Session
消息通知
用list作为消息队列
- 使用场景:消息通知
- List数据结构:Quicklist
- 由一个双向链表和listpack实现
计数
一个用户有多项计数需求,可通过hash结构存储
- Hash数据结构dict
- rehash:迁移某一个哈希节点下的值到另一个节点,数据量大时会阻塞用户请求
- 渐进式rehash:每次用户访问都迁移少量数据,平摊所有的迁移开销
排行榜
积分变化时,排名要实时变更
- zset数据结构,zskiplist跳表
- 结合dict后,可实现通过key操作跳表
限流
要求1秒内放行的请求为N,超过N禁止访问
利用当前时间戳构造一个key,对这个key调用incr,实现访问计数。
分布式锁
并发场景,要求一次只能有一个协程执行。执行完成后,其它等待中的协程才能执行。
可以使用redis的setnx实现,利用了两个特性
- Redis单线程执行命令
- setnx只有未设置过才能执行成功
但这并不是高可用的实现,因为可能会被超时的任务阻塞。
Redis使用注意事项
大Key,热Key
数据类型 | 大key标准 |
---|---|
String类型 | value的字节数大于10KB |
Hash/Set/Zset/list等复杂数据结构类型 | 元素个数大于5000个或总value字节数大于10MB |
- 读取成本高
- 容易导致慢查询
- 主从复制异常,服务阻塞无法正常响应请求
消除大Key的方法
- 拆分
- 压缩
- 集合类结构
- 拆分
- 区分冷热
热Key解决方法:
- 设置Localcache
- 拆分
- 使用Redis代理的热Key承载能力,实际上是结合了:
- 热Key发现
- LocalCache
慢查询场景
- 批量操作一次性传入过多key/value
- 大key
缓存穿透、缓存雪崩
缓存穿透:热点数据查询绕过缓存,直接查询数据库
- 查询一个一定不存在的数据
- 缓存过期时
减少方法:
- 缓存空值
- 布隆过滤器
缓存雪崩:大量缓存同时过期
- 分散缓存失效时间
- 使用缓存集群,避免单机宕机导致缓存雪崩