通例性hotkey:可以提前评估出hotkey的场景,比如:告急节沐日、促销运动等
突发性hotkey:没法提前评估,突发性举动,比如:忽然消息、爆炸信息(微博)、爆款商品等
办理方案
① 多副本方案:将这些热门key分散处理处罚
② 本地缓存方案:提前举行本地缓存预热,预加载,尽量优先掷中本地缓存
产生的标题
① 怎么提前预热:定时任务
② 数据同等性标题:本地缓存、分布式缓存、数据库
③ 针对突发性hotkey,关键点在于怎么快速定位热门key?
流式盘算:fink
高并发的hotkey盘算中央件:基于时间窗口原理(京东的hotkey组件)
1.2 bigkey
(1)商品详情缓存(String范例):将包罗多字段(如图文形貌、评价列表等)的完备商品信息序列化为大JSON字符串存储
单个String范例Key体积凌驾1MB(极度场景达10MB),导致查询延伸激增
(2)交际关系图谱(Hash范例):使用Hash存储用户交际关系(如挚友列表、关注列表),单个Key包罗数千成员且value体积总和超100MB
HGETALL等操纵耗时凌驾10ms,导致单线程壅闭和网络拥塞
(3)全站排行榜(ZSet范例):全局积分/热度排行榜使用单个ZSet存储全部效户数据,成员数量超1万
ZRANGE等范围查询操纵耗时过长,引发内存不均衡和节点负载倾斜
办理方案(依照“监控先行、分而治之、防备为主”原则)
(1)BigKey发现与定位,并举行监控
① 使用【redis-cli --bigkeys】命令举行全库扫描,辨认各数据范例中体积最大的Key(如String超1MB、聚集元素超5000个)
② 结合【MEMORY USAGE】命令精确盘算指定Key的内存占用,定位非常值
③ 通过Redis监控平台(如RedisInsight、Prometheus)及时跟踪内存增长、操纵耗时等指标,设置阈值告警(如操纵延伸>10ms)
(2)数据拆分与重构
① String范例:将大JSON拆分为多个子Key(如商品详情按字段拆分为product:1001:info、product:1001:reviews),或改用Hash布局分片存储
② 聚集范例(Hash/List/Set/ZSet):
按哈希分片(如user:1001:logs_0至user:1001:logs_4
按时间维度拆分(如日记队列拆分为logs:202404、logs:202405)
(3)计划规范,布局优化
① 限制单Key体积(如String≤100KB、聚集元素≤1000个)
② 克制存储完备业务对象,优先采取关联查询或二级缓存
③ 高频访问的热门数据(如排行榜)改用分片ZSet(如rank:shard_1至rank:shard_10)
2 本地缓存
缓存的核心:提升数据掷中率
2.1 本地缓存主要技能
Nginx本地缓存:share dict
Java技能栈
① Map(HashMap,ConcurrentHashMap)
优点:简朴,不须要引入第三方jar,得当一些比较简朴的场景
缺点:没有太好的缓存镌汰计谋
② Guava cache
Google开源的基于LRU镌汰算法的缓存技能
优点:支持最大容量限制;两种逾期删除计谋(插入时间、访问时间);支持简朴的统计功能
缺点:主流技能框架放弃了对Guava cache的支持
③ Encache
Hibernate默认的缓存组件
优点
支持多种缓存镌汰计谋
支持堆内缓存、堆外缓存、磁盘缓存
支持多种集群方案,办理数据共享
缺点:相较于Caffeine性能较差
④ Caffeine
采取W-TinyLFU(LFU和LRU优点结合)开源缓存技能
缓存性能接近理论最优,Guava cache加强版
2.2 本地缓存优缺点
镌汰最少次使用的,实用于局部周期性场景
增长元素访问次数统计,而且按照访问次数排序
优点:实用于局部周期性热门场景,比LRU有更好的缓存掷中率,以访问次数为基准
缺点:① 须要记载数据的访问次数,就要占用额外的空间
② 须要维护访问次数数据,每次访问更新偶然间开销
③ 局部突发流量场景,大概率缓存掷中率不高