经验之谈:我为什么选择了这样一个激进的缓存大Key治理方案

news/发布时间2024/5/19 16:05:01

一、引言

本文将结合我的一次Redis大Key的治理经验,来浅谈一下缓存大Key的治理方案选择。文中主要包括缓存大Key基础知识大Key治理方案选择大Key治理案例等,适合有一定开发经验的开发者阅读,希望对大家有帮助。

二、缓存大Key基础知识

2.1 大Key的标准

集合类型元素数量>5000或者单个value大于1M。当然这个标准不是绝对的,而是需要根据具体的业务场景和Redis集群的实际情况来灵活调整

2.2 大Key带来的风险

  • 大key发生热点访问,响应积压在服务端后内存暴涨,最终导致服务端被杀造成数据丢失
  • 严重影响 QPS、TP99等指标,对大Key进行的慢操作会导致后续的命令被阻塞,从而导致一系列慢查询。
  • hgetall、smembers 等时间复杂度O(N)的命令使用不当,容易造成CPU使用率过高。
  • 集群各分片内存使用不均。某个分片占用内存较高或OOM,发送缓存区增大等,导致该分片其他Key被逐出,同时也会造成其他分片的资源浪费。
  • 集群各分片的带宽使用不均。某个分片被流控,其他分片则没有这种情况,且影响宿主机上的其它应用。
  • 数据迁移失败 过大的Key(如超过1G),在迁移、缩容、扩容,主从全量同步在序列化过程中,内存上涨,数据同步失败,且存在数据丢失风险。

三、缓存大Key治理方案

3.1事前预防

事前预防的基本思路是在缓存设计的时候,缓存中只存储必要的数据,且需要考虑将存储空间变小,具体的手段有:

  1. 对于JSON类型,可以删除不使用的Field;或者使用@JsonProperty 注解让 FiledName 字符集缩小;
  2. 采用Protobuf等压缩算法,利用时间换空间;
  3. 对于集合类型,设计上尽量避免整存整取;

3.2 事中监控

事中做好监控,对于缓存大Key,早发现,早治理;

3.3 事后

缓存大Key已经存在,那么应该怎么办?分2种情况进行考虑:

  1. 评估这些大Key是否还有存在的意义和价值,是否可以删除,对于可以删除的可以使用SCAN命令进行循序渐进式删除大Key;对于不可以直接删除的这种,是否可以将数据转移到其他的介质进行存储;
  2. 对于不能直接删除的大Key,进行“分而治之”,再通俗一点就是“拆”,将大Key进行拆分
  • String类型的大Key:可以尝试将对象分拆成几个Key-Value,使用MGET或者多个GET组成的pipeline获取值,分拆单次操作的压力,对于集群来说可以将操作压力平摊到多个分片上,降低对单个分片的影响。
  • 集合类型的大Key,每次只需操作部分元素:将集合类型中的元素分拆。以Hash类型为例,可以在客户端定义一个分拆Key的数量N,每次对HGET和HSET操作的field计算哈希值并取模N,确定该field落在哪个Key上。

四、缓存大Key治理案例

4.1 系统架构和业务场景说明

有这样一个电商活动管理系统,系统有2个应用:后台管理端、运营端;(后台管理端是管理人员进行操作;运营端可以创建营销活动)存储使用的是MySQL和Redis;

系统中有一个这样的场景,简单来说就是,后台管理端可以添加sku白名单,这个白名单是以“商家ID + skuId”为一条记录写入MySQL中的;运营端在创建营销活动,需要上传sku,上传的时候需要读取sku白名单进行校验。

系统现状是,在查询sku白名单的时候使用了Redis缓存。缓存模式采用的是旁路缓存,添加SKU白名单的流程是,写入数据库,并删除缓存;读取SKU白名单的流程是,先从缓存读取,缓存中没有则读取数据库,并将结果写入缓存。缓存的数据类型是String,value为数据库中的全量SKU白名单记录,是以JSON字符串存储的。

旁路缓存:读取缓存、读取数据、更新缓存和操作都是在应用程序中完成的。

但是随着业务的发展,添加的SKU白名单逐渐增多,发展成为了缓存大Key。截止治理之前,数据库的配置表中存在1w+条sku白名单记录,也就是说Redis的一个String结果存储了1w+条的白名单记录。

这里也许有人问,一张表中存储1w+条数据,也是没有压力的啊,其实这张配置表中不仅有商家SKU白名单配置,还包括系统中其他所有的配置信息存储,数据量还是可观的。

4.2 一种激进的治理方案

该业务场景中,缓存大Key是不可以直接进行删除处理的,处理思路是将其拆分为一些小的Key。

分析场景,商家可以登录运营端进行创建营销活动,在创建营销活动和上传SKU的过程中,只需要查询该商家的SKU白名单,那么存储和查询全部都是不必要的,那么可以将全量白名单数据按照商家维度进行拆分存储和查询。

关于缓存结构的选择,我使用的是Hash结构(新缓存),key与原缓存String结构 key 相同,field为商家ID,value为sku白名单列表。大概流程图如下:

新缓存Hash结构key与原缓存String结构 key 完全相同,意味着新的Hash结构缓存和旧的String缓存是无法共存的,只能选择其一,意味着不存在百分比切量的过程,一步到位切量,你就说是否激进?

这样激进的方案是基于什么的考量呢?

  1. 夜间流量几乎为0,且缓存切换操作秒级完成,风险可控。运营端系统,商家创建促销活动基本都是工作时间,晚上和凌晨几乎没有流量;而且,新旧缓存切换可以秒级完成:①运营端添加测试SKU白名单,删除缓存;②将开关切到新缓存;风险可控。
  2. 方案支持秒级回滚.①运营端添加测试SKU白名单,删除缓存;②将开关切到旧缓存。
  3. 代码改动和上线部署工作量小。这个方案可以保持管理后端删除缓存的逻辑不变,也就是在添加SKU白名单的时候还是删除所有的白名单缓存;只需要改动运营后端代码,且上线部署只需要部署运营端。
  4. 虽然管理后端删除缓存为全量删除,存在管理端添加商家A的SKU白名单,导致缓存中的商家B、商家C等的白名单数据也被删除(其实是无需删除的),综合评估可以暂时保持现状,后续优化

4.3 更加通用的治理方案

4.3.1 三个阶段

更加通用的缓存大key治理方案,包括双写、双读对比和读写新key等阶段:

  1. 双写阶段

在不影响现有业务的情况下,将新数据同时写入旧key和新key;

  1. 双读对比阶段

验证新key的数据与旧key的数据是否一致,并准备切换读操作到新key;

  1. 读写新key阶段

将所有读写操作都切换到新key,并废弃旧key;需要注意删除大key时要避免阻塞Redis服务。

4.3.2 注意事项

  • 数据一致性:在整个治理过程中,需要确保数据的一致性。特别是在双写和双读对比阶段,要仔细验证数据是否一致。
  • 性能影响:在双写和双读对比阶段,由于需要同时操作旧key和新key,可能会对性能产生一定影响。因此,需要在业务低峰期进行这些操作,并监控系统的性能指标。
  • 错误处理:在治理过程中,可能会遇到各种错误情况(如数据不一致、网络问题等)。需要制定完善的错误处理机制来确保系统的稳定性和可用性。
  • 备份和恢复:在执行治理操作之前,建议对Redis数据进行备份。以便在出现问题时可以快速恢复数据。

五、小结

本文是一个真实的线上缓存大Key治理案例,区别于通用的治理方案,我选择了一种激进和简单的治理策略。对于缓存大Key进行简单总结一下,对于使用缓存,需要考虑缓存大Key问题,设计和开发过程中尽量避免;如果已经出现,考虑删除,如果不可以删除,考虑拆分。可以在权衡之下,选择最适合自己的方案。

一起学习

欢迎各位在评论区或者私信我一起交流讨论,或者加我主页weixin,备注技术渠道(如博客园),进入技术交流群,我们一起讨论和交流,共同进步!

也欢迎大家关注我的博客园、公众号(码上暴富),点赞、留言、转发。你的支持,是我更文的最大动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.jwkm.cn/p/44422122.html

如若内容造成侵权/违法违规/事实不符,请联系宁远站长网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

[转帖]长连接黑洞重现和分析

https://plantegg.github.io/2024/05/05/%E9%95%BF%E8%BF%9E%E6%8E%A5%E9%BB%91%E6%B4%9E%E9%87%8D%E7%8E%B0%E5%92%8C%E5%88%86%E6%9E%90/ 长连接黑洞重现和分析 这是一个存在多年,遍及各个不同的业务又反反复复地在集团内部出现的一个问题,本文先通过重现展示这个问题,然后…

Blazor/Hybird 触屏下单程序调优笔记

环境 Blazor Net8.0 + FreeSql + Bootstrap Blazor 组件 以下都是自己瞎琢磨的和官网资料搬运,肯定有不少错漏和不合理的地方,非常希望各位大佬评论区给我建议和意见. 1. 组件化需要提升渲染性能的组件,例如触摸屏显示每个商品下单数量的商品列表 避免不必要地呈现组件子树, 执…

WDS+MDT网络启动自动部署windows(十五)使用it天空万能驱动

简介: 虽然我们可以使用dism这样的工具来备份驱动,并通过适当的厂家、型号来区分并自动注入驱动,它没万能驱动用着方便呀,还得去备份。 本文目标:在MDT部署时使用it天空的万能驱动。 下载 或许是我脑子坏掉了,印象中不是这个域名。 IT天空 - 新的十年,新的天空 (itsk.co…

阿里面试:事务ACID,底层是如何实现的?

文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 实现技术自由,…

DevOps,CI,CD,自动化简单介绍

原创 追逐时光者前言随着企业应用的不断迭代和发展,应用的版本发布可能涉及了多个技术团队(如PC端,移动端,小程序端等)。随之而来的问题是应用发布也成为了一项高风险,高压力的操作过程。并且应用的开发迭代的沟通,测试成本也大大的变得不可控。这时候就出现了DevOps管…

图文并茂手把手教你安装windows搭建sqlserver(SqlServer数据库安装保姆级教程)

sqlserver是什么 SQL Server 是由美国微软公司(Microsoft)开发的一款关系型数据库管理系统(RDBMS)。作为全球主流的数据库平台之一,SQL Server 设计用于高效管理和处理大量结构化数据,支持各种规模的应用场景,从个人电脑到企业级数据中心,乃至云端部署。 SQL Server 数…