如何处理Redis 集群中的big key和hot key_hotkey 和 bigkey 的解决方案-程序员宅基地

如何处理Redis 集群中的big key和hot key

hot key出现造成集群访问量倾斜

Hot key,即热点 key,指的是在一段时间内,该 key 的访问量远远高于其他的 redis key, 导致大部分的访问流量在经过 proxy 分片之后,都集中访问到某一个 redis 实例上。hot key 通常在不同业务中,存储着不同的热点信息。比如

新闻应用中的热点新闻内容;
活动系统中某个用户疯狂参与的活动的活动配置;
商城秒杀系统中,最吸引用户眼球,性价比最高的商品信息

redis 集群部署方式大部分采用类 Twemproxy 的方式进行部署。即通过 Twemproxy 对 redis key 进行分片计算,将 redis key 进行分片计算,分配到多个 redis 实例中的其中一个,由于 Twemproxy 背后的多个 redis 实例在内存配置和 cpu 配置上都是一致的,所以一旦出现访问量倾斜或者数据量倾斜,则可能会导致某个 redis 实例达到性能瓶颈,从而使整个集群达到性能瓶颈。

解决方案:

  1. 使用本地缓存

在 client 端使用本地缓存,从而降低了redis集群对hot key的访问量,但是同时带来两个问题:
1、如果对可能成为 hot key 的 key 都进行本地缓存,那么本地缓存是否会过大,从而影响应用程序本身所需的缓存开销。2、如何保证本地缓存和redis集群数据的有效期的一致性。

  1. 利用分片算法的特性,对key进行打散处理

我们知道 hot key 之所以是 hot key,是因为它只有一个key,落地到一个实例上。所以我们可以给hot key加上前缀或者后缀,把一个hotkey 的数量变成 redis 实例个数N的倍数M,从而由访问一个 redis key 变成访问 N * M 个redis key。

N*M 个 redis key 经过分片分布到不同的实例上,将访问量均摊到所有实例。

代码如下:

在这个代码中,通过一个大于等于 1 小于 M * N 的随机数,得到一个 tmp key,
程序会优先访问tmp key,在得不到数据的情况下,再访问原来的 hot key,并将 hot key的内容写回 tmp key。
值得注意的是,tmp key的过期时间是 hot key 的过期时间加上一个较小的随机正整数,保证在 hot key 过期时,所有 tmp key 不会同时过期而造成缓存雪崩。这是一种通过坡度过期的方式来避免雪崩的思路,同时也可以利用原子锁来写入数据就更加的完美,减小db的压力

另外还有一件事值得一提,默认情况下,我们在生成 tmp key的时候,会把随机数作为 hot key 的后缀,这样符合redis的命名空间,方便 key 的收归和管理。但是存在一种极端的情况,就是hot key的长度很长,这个时候随机数不能作为后缀添加,原因是 Twemproxy 的分片算法在计算过程中,越靠前的字符权重越大,考后的字符权重则越小。也就是说对于key名,前面的字符差异越大,算出来的分片值差异也越大,更有可能分配到不同的实例(具体算法这里不展开讲)。所以,对于很长 key 名的 hot key,要对随机数的放入做谨慎处理,比如放在在最后一个命令空间的最前面(eg:由原来的 space1:space2:space3_rand 改成 space1:space2:rand_space3)。

big key 造成集群数据量倾斜
big key ,即数据量大的 key ,由于其数据大小远大于其他key,导致经过分片之后,某个具体存储这个 big key 的实例内存使用量远大于其他实例,造成,内存不足,拖累整个集群的使用。big key 在不同业务上,通常体现为不同的数据,比如:

论坛中的大型持久盖楼活动;
聊天室系统中热门聊天室的消息列表;

解决方案

对 big key 进行拆分
对 big key 存储的数据 (big value)进行拆分,变成value1,value2… valueN,
如果big value 是个大json 通过 mset 的方式,将这个 key 的内容打散到各个实例中,减小big key 对数据量倾斜造成的影响。
如果big value 是个大list,可以拆成将list拆成。= list_1, list_2, list3, listN
其他数据类型同理。

既是big key 也是 hot key
在开发过程中,有些 key 不只是访问量大,数据量也很大,这个时候就要考虑这个 key 使用的场景,存储在redis集群中是否是合理的,是否使用其他组件来存储更合适;如果坚持要用 redis 来存储,可能考虑迁移出集群,采用一主一备(或1主多备)的架构来存储。

如何发现 hot key,big key

  1. 事前-预判
    在业务开发阶段,就要对可能变成 hot key ,big key 的数据进行判断,提前处理,这需要的是对产品业务的理解,对运营节奏的把握,对数据设计的经验。

2.事中-监控和自动处理

监控
在应用程序端,对每次请求 redis 的操作进行收集上报;不推荐,但是在运维资源缺少的场景下可以考虑。开发可以绕过运维搞定);
在proxy层,对每一个 redis 请求进行收集上报;(推荐,简单直接影响小)
对 redis 实例使用monitor命令统计热点key(不推荐,高并发条件下会有造成redis 内存爆掉的隐患);
机器层面,Redis客户端使用TCP协议与服务端进行交互,通信协议采用的是RESP。如果站在机器的角度,可以通过对机器上所有Redis端口的TCP数据包进行抓取完成热点key的统计(不推荐,公司每台机器上的基本组件已经很多了,别再添乱了);

自动处理
通过监控之后,程序可以获取 big key 和 hot key,再报警的同时,程序对 big key 和 hot key 进行自动处理。或者通知程序猿利用一定的工具进行定制化处理(在程序中对特定的key 执行前面提到的解决方案)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010122604/article/details/115305650

智能推荐

前端开发之vue-grid-layout的使用和实例-程序员宅基地

文章浏览阅读1.1w次,点赞7次,收藏34次。vue-grid-layout的使用、实例、遇到的问题和解决方案_vue-grid-layout

Power Apps-上传附件控件_powerapps点击按钮上传附件-程序员宅基地

文章浏览阅读218次。然后连接一个数据源,就会在下面自动产生一个添加附件的组件。把这个控件复制粘贴到页面里,就可以单独使用来上传了。插入一个“编辑”窗体。_powerapps点击按钮上传附件

C++ 面向对象(Object-Oriented)的特征 & 构造函数& 析构函数_"object(cnofd[\"ofdrender\"])十条"-程序员宅基地

文章浏览阅读264次。(1) Abstraction (抽象)(2) Polymorphism (多态)(3) Inheritance (继承)(4) Encapsulation (封装)_"object(cnofd[\"ofdrender\"])十条"

修改node_modules源码,并保存,使用patch-package打补丁,git提交代码后,所有人可以用到修改后的_修改 node_modules-程序员宅基地

文章浏览阅读133次。删除node_modules,重新npm install看是否成功。在 package.json 文件中的 scripts 中加入。修改你的第三方库的bug等。然后目录会多出一个目录文件。_修改 node_modules

【】kali--password:su的 Authentication failure问题,&sudo passwd root输入密码时Sorry, try again._password: su: authentication failure-程序员宅基地

文章浏览阅读883次。【代码】【】kali--password:su的 Authentication failure问题,&sudo passwd root输入密码时Sorry, try again._password: su: authentication failure

整理5个优秀的微信小程序开源项目_微信小程序开源模板-程序员宅基地

文章浏览阅读1w次,点赞13次,收藏97次。整理5个优秀的微信小程序开源项目。收集了微信小程序开发过程中会使用到的资料、问题以及第三方组件库。_微信小程序开源模板

随便推点

Centos7最简搭建NFS服务器_centos7 搭建nfs server-程序员宅基地

文章浏览阅读128次。Centos7最简搭建NFS服务器_centos7 搭建nfs server

Springboot整合Mybatis-Plus使用总结(mybatis 坑补充)_mybaitis-plus ruledataobjectattributemapper' and '-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏3次。前言mybatis在持久层框架中还是比较火的,一般项目都是基于ssm。虽然mybatis可以直接在xml中通过SQL语句操作数据库,很是灵活。但正其操作都要通过SQL语句进行,就必须写大量的xml文件,很是麻烦。mybatis-plus就很好的解决了这个问题。..._mybaitis-plus ruledataobjectattributemapper' and 'com.picc.rule.management.d

EECE 1080C / Programming for ECESummer 2022 Laboratory 4: Global Functions Practice_eece1080c-程序员宅基地

文章浏览阅读325次。EECE 1080C / Programming for ECESummer 2022Laboratory 4: Global Functions PracticePlagiarism will not be tolerated:Topics covered:function creation and call statements (emphasis on global functions)Objective:To practice program development b_eece1080c

洛谷p4777 【模板】扩展中国剩余定理-程序员宅基地

文章浏览阅读53次。被同机房早就1年前就学过的东西我现在才学,wtcl。设要求的数为\(x\)。设当前处理到第\(k\)个同余式,设\(M = LCM ^ {k - 1} _ {i - 1}\) ,前\(k - 1\)个的通解就是\(x + i * M\)。那么其实第\(k\)个来说,其实就是求一个\(y\)使得\(x + y * M ≡ a_k(mod b_k)\)转化一下就是\(y * M ...

android 退出应用没有走ondestory方法,[Android基础论]为何Activity退出之后,系统没有调用onDestroy方法?...-程序员宅基地

文章浏览阅读1.3k次。首先,问题是如何出现的?晚上复查代码,发现一个activity没有调用自己的ondestroy方法我表示非常的费解,于是我检查了下代码。发现再finish代码之后接了如下代码finish();System.exit(0);//这就是罪魁祸首为什么这样写会出现问题System.exit(0);////看一下函数的原型public static void exit (int code)//Added ..._android 手动杀死app,activity不执行ondestroy

SylixOS快问快答_select函数 导致堆栈溢出 sylixos-程序员宅基地

文章浏览阅读894次。Q: SylixOS 版权是什么形式, 是否分为<开发版税>和<运行时版税>.A: SylixOS 是开源并免费的操作系统, 支持 BSD/GPL 协议(GPL 版本暂未确定). 没有任何的运行时版税. 您可以用她来做任何 您喜欢做的项目. 也可以修改 SylixOS 的源代码, 不需要支付任何费用. 当然笔者希望您可以将使用 SylixOS 开发的项目 (不需要开源)或对 SylixOS 源码的修改及时告知笔者.需要指出: SylixOS 本身仅是笔者用来提升自己水平而开发的_select函数 导致堆栈溢出 sylixos

推荐文章

热门文章

相关标签