引言
本文主要梳理在使用和设计缓存的一些问题点以及应对思路,以及缓存设计的一些架构和治理点。本文主要内容有:
一、缓存常见问题点梳理
缓存穿透,大量请求访问缓存在不存在的数据,请求压力落到数据库,数据库压力瞬时增大甚至被打垮。
只要缓存有数据就不会打到数据库,可通过短时间的缓存占位符避免。
缓存击穿,缓存中的热点数据过期,大量请求被落入数据库,数据库压力瞬时增大甚至被打垮。
同一时间避免大量请求入库,可通过分布式锁限制请求通过。
缓存雪崩, 缓存中的大量数据设置相同的过期时间,当同一时间过期时,大量请求被落入数据库,数据库压力瞬时增大甚至被打垮。
大量key避免设置相同的过期时间即可避免雪崩,可通过在设置过期时间上增加一定的随机时间。
大key限制 ,大量大key会对集群造成冲击和抖动,客户端表现为超时,尽可能规范和避免。
在写入前(SDK、代理或集群)可以对字符串的key大小进行限制,非字符串key可以限制个数。
在写入大key后,定时对集群中key进行巡检,捞出大key针对性告警与治理。
热key识别 ,热点key容易造成集群流量不均衡,个别节点流量过大,甚至击垮集群,导致大量请求落入数据库,造成雪崩。
客户端计数埋点/代理端计数埋点/服务端统计热点key。
热key拆分打散/热key迁移到集群其他节点/增加本地缓存形成两级缓存优先读取本地缓存。
缓存和数据库的一致性,先删缓存再更新数据库,避免读到缓存旧数据。
本地缓存与分布式缓存一致性, 当缓存变化时,通过广播机制通知到各个节点更新本地缓存,实现分布式缓存和本地缓存的一致性。
二、缓存常见架构设计点
代理模式, Proxy+CacheDB 不同语言连接Proxy即可,实现轻量,监控治理方便在代理层切入。
增加Proxy的部署成本增加,两级跳转RT增加。
直连模式, 客户端直接连接缓存集群,RT响应以及性能较好,分布式全局故障系数更低。
每种语言都需要开发对应的客户端。
一主多从, 由主节点负责读写,从节点负责灾备,当主节点挂掉由从节点接管,压力在主节点。
多主多从, 集群中每个节点都可负责读写,集群读写压力充分分散。
多份数据高可靠, 通过2~3份数据备份保证数据的高可靠。
高可用协议, 常用一致性协议Paxos、Raft、Gossip或基于其裁剪。
三、缓存常见监控治理点
缓存命中率, 当访问的数据缓存中有即命中,否则未命中。
命中率=命中数/(命中数+没有命中数)。
缓存命中率衡量缓存的使用收益,命中率越高,应用性能加速越好,RT越短、吞吐越高。
大key拦截与巡检 ,针对大key比如超过512KB或者1M进行拦截,以及大key监控。
关键指标, 连接数、内存使用率、集群副本数量、节点数量、响应RT耗时分布、可用性等监控。
命令分布/慢查询统计, 访问集群执行redis命令统计分布情况,统计耗时过长命令的统计。
运维白屏化, 集群部署、升级以及扩缩容、数据迁移、监控告警等白屏化。
数据迁移与同步, 将数据从一个集群迁移到另一个集群,以及特殊场景集群之间的双向同步。