redis #
热key问题和优化方案 #
热key引发的问题:
- 流量集中:可能导致redis节点网络异常、cpu异常,甚至崩溃。
- 资源倾斜:redis集群流量严重倾斜,其他节点利用率不足。
- 缓存击穿问题:缓存失效时,瞬间的大量请求可能导致数据库压力大增,引发雪崩。
优化方案:
- 本地缓存:对实时性要求不高的业务,可能将数据缓存在本地,减少redis节点压力。
- key拆分备份:对key添加后缀,如用户id哈希取模、随机数取模等,这样不同的key会被分散存储到不同的节点上,流量被均摊。
- 业务隔离:热key相关业务与核心业务使用的redis服务隔离开来,防止redis崩溃导致核心业务崩溃。
- 监控告警:收集key访问量,集成到监控面板和告警服务中。
大key问题和优化方案 #
如何找到大key:
- 输入命令
redis-cli --bigkeys
,建议在从节点上操作,不要在主节点上操作,因为该命令会阻塞节点。 - 指令
MEMORY USAGE key [SAMPLES count]
,返回使用内存的字节数。
大key是怎么产生的:
- 设计问题:直接存储大文件或大对象到redis中,或者使用了不合理的数据结构。
- 集合类型的key中项目过多,可能是因为没有考虑到业务增长,也可能是因为没有及时清理已失效数据。
大key引发的问题:
- redis集群内存分布不均,内存资源倾斜。
- 删除大key时,会阻塞工作线程。
- 大量请求可能导致redis节点网络阻塞,影响性能。
优化方案:
- 本地缓存。
- 数据分层:冷数据使用其他存储方式保存,如数据库、对象存储、文件系统。
- key拆分:将集合类型的大key拆分成多个小key,数据按哈希取模的方式存入不同的key中。
- 使用合适的数据结构,不要一成不变地使用字符串类型。
- 分批次处理:对于集合类型大key,不要一次性取出所有数据,分页获取数据并处理,完成后再获取下一页数据。
- 及时清理集合类型大key中失效的项目。
- 去重统计优化:对于使用set统计大量uv的场景,可以用 HyperLogLog(HLL) 代替。
redis实现mq的方法 #
发布订阅(PubSub) #
原理:
- 客户端订阅一个或多个频道,发布者将消息发布的指定频道,Redis服务器会将消息转发给所有订阅该频道的用户。
优点:
- 实现简单
- 适合一对多的消息广播场景
缺点:
- 不支持消息持久化
- 没有消息确认机制
- 消费者不在线则消息丢失
列表(List) #
原理:
- 使用 LPUSH 将消息添加到列表头部,使用 LPOP 从列表尾部弹出,或者使用 RPUSH/RPOP 指令。
- LPOP/RPOP 不会阻塞将导致 CPU 空耗,可以用 BLPOP/BRPOP 代替。
优点:
- 实现简单
- 高性能:redis是基于内存的,操作延迟低
- 支持持久化
- 支持消息有序性
缺点:
- 没有消息确认机制
- 不支持多个消费者同时消费