这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
为什么需要redis
- 数据量的增长
- 数据从单表,演进到分库分表
- 数据量增长,数据读写压力变大
- 数据分冷热
- 热数据是经常访问到的数据
- 需要把热数据存到内存中
redis的基本工作原理
- 数据从内存中读取
- 数据保存到硬盘防止丢失
- 增量数据存到AOF
- 全量数据存到RDB
- 单线程处理
redis的应用案例
根据redis内部数据结构特性的不同,按照不同的使用场景介绍
String
数据结构是SDS
- 存储字符串,数字,二进制
- 配合expire使用
- 可用于存储计数和session
QuickList
由双向链表和listpack实现
- 用作消息队列
Dict
Dict是一个hash的数据结构
- 当槽位不够的时候会发生rehash
- 渐进式rehash避免阻塞操作 可用作多项的计数
Zset
使用zskiplist (跳表)实现 可用作积分排名
除此之外,还有
限流
- 使用Lua脚本:可以使用Redis的脚本功能在服务端执行一段限流脚本,控制对特定资源的访问频率。。
- 使用Redis的Bitmap:可以将每一秒的请求数都存储在一个bitmap中,然后根据bitmap的值来判断当前是否允许请求。
- 使用Redis的原子计数器:可以对每一秒的请求数进行计数,如果超过限制的请求数,则拒绝请求。
分布式锁
并发场景,一次只能由一个执行器执行,执行完成后,其他等待中的执行器才能执行
可以使用redis的setnx实现
- 单线程执行命令
- setnx只有未设置过才能执行
使用注意事项
大Key
- 大Key的定义
- String 类型 Value的字节数大于10KB
- 复杂数据类型 (Hash,Set,Zset,List) 元素数量大于5000或者数据量总和大于10MB
- 大Key的危害、
- 读取成本高
- 容易导致慢查询
- 主从复制容易阻塞
- 消除大Key的方法
- 拆大Key为小Key
例如将一篇比较长的文章分段存放
- 压缩 需要考虑到压缩算法的耗时和压缩率的平衡
- 区分冷热,冷数据走db
热key
-
热Key的定义 一个Key的QPS特别高,将导致Redis实例出现负载突增,负责均衡流量不均的情况。导致单实例故障 热Key没有明确标准,QPS超500有可能就算热Key
-
解决热Key的方法
- 设置Localcache
- 将热Key拆分为更多的Key
- 使用代理访问(结合了热Key发现和Localcache功能)
慢查询的场景
- 批量一次性传入过多的Key/Value,建议单次不要超过100
- zset大小超过5k以上
- 操作的单个value过大,即操作大key
- 对大Key的delete/expire操作也有可能导致
缓存穿透,缓存雪崩
- 缓解缓存穿透
- 缓存空值
- 布隆过滤器
- 避免缓存雪崩
-
给Key的过期时间设置随机量,避免同时大量过期
-
使用缓存集群