浅析Redis集群数据倾斜问题及解决方法

news2024/12/26 12:00:46

概  述 

在服务端系统服务开发中,缓存是一种常用的技术,它可以提高系统对请求的处理效率,而redis又是缓存技术栈中的一个佼佼者,广泛的应用于各种服务系统中。在大型互联网服务中,每天需要处理的请求和存储的缓存数据都是海量的,在这些大型系统中,使用单实例的redis,很难满足系统超高的并发请求以及海量数据缓存需求。大型的互联网服务中对于redis的使用,往往采用集群架构,通过横向扩展redis实例规模的方式,以较低的成本,来提升缓存系统对数据请求的处理效率和数据存储容量。

redis集群架构虽然有众多优点,但是事物往往都是有双面性的,在解决某些场景下的问题后,又会在另外的场景下有带来问题。当然redis集群模式,也是符合这个规律的。redis集群模式下,会增加运维的复杂度,限制了redis中某些命令的使用(范围查询,事务操作的使用等),除了这些常见的问题外,数据倾斜问题,是redis集群模式下一个比较隐蔽的问题,只有在一些特殊的场景下才会出现,但是该问题带来的影响确实巨大的。

示  例

2019年春节抽奖服务,业务评估峰值qps是2w,转化到redis集群为10w qps和5GB内存存储,部署5个分片每个分片1GB+2W qps的redis集群(包含预留容量)。结果活动开始时,才发现服务存在”热点key",请求严重倾斜, 峰值时的6w qps都集中到其中一个分片,导致这分片过载,整个抽奖服务雪崩。

什么是数据倾斜

   在redis集群模式下,数据会按照一定的分布规则分散到不同的实例上。如果由于业务数据特殊性,按照指定的分布规则,可能导致不同的实例上数据分布不均匀,如以下场景:有些切片实例上数据分布量较大,有些实例上数据分布量较少;有些实例上保存了热点数据,数据访问量较大,有些实例上保存数据相对较"冷",几乎没有访问量。那么存储数据量大的实例,或者保存热点数据的实例,资源利用率会比较高,负载压力较大,导致其对数据请求响应变慢。此时就产生了数据倾斜。

 有哪几种数据倾斜

redis分布式集群倾斜问题,主要分为两类:

1、数据存储容量倾斜,数据存储总是落到集群中少数节点;

2、qps请求倾斜,qps总是落到少数节点。

redis集群出现倾斜的影响

倾斜问题对于redis这类纯内存和单线程服务影响较大,存在以下痛点:

  • qps集中到少数redis节点,引起少数节点过载,会拖垮整个服务,同时集群处理qps能力不具备可扩展性;

  • 数据容量倾斜,导致少数节点内存爆增,出现OOM Killer和集群存储容量不具备可扩展性;

  • 运维管理变复杂,类似监控告警内存使用量、QPS、连接数、redis cpu busy等值不便统一;

  • 因集群内其他节点资源不能被充分利用,导致redis服务器/容器资源利率低;

  • 增大自动化配置管理难度;单集群节点尽量统一参数配置;

分析完影响,那我们再看生产环境中,导致Redis集群严重“倾斜”的常见原因。

导致Redis集群倾斜的常见原因

一般是系统设计时,键空间(keyspace)设计不合理:

  • 系统设计时,redis键空间(keyspace)设计不合理,出现”热点key",导致这类key所在节点qps过载,集群出现qps倾斜;

  • 系统存在大的集合key(hash,set,list等),导致大key所在节点的容量和QPS过载,集群出现qps和容量倾斜;

  • DBA在规划集群或扩容不当,导致数据槽(slot)数分配不均匀,导致容量和请求qps倾斜;

  • 系统大量使用Keys hash tags, 可能导致某些数据槽位的key数量多,集群集群出现qps和容量倾斜;

  • 工程师执行monitor这类命令,导致当前节点client输出缓冲区增大;used_memory_rss被撑大;导致节点内存容量增大,出现容量倾斜;

接下来,当集群出现内存容量、键数量或QPS请求量严重倾斜时,我们应该排查定位问题呢?

Redis集群倾斜问题的排查方式

排查节点热点key,确定top commands.

当集群因热点key导致集群qps倾斜,需快速定位热点key和top commands。可使用开源工具redis-faina,或有实时redis分析平台更好。

以下是使用redis-faina工具分析,可见两个前缀key的QPS占比基本各为50%, 明显热点key;也能看到auth命令的异常(top commands)。

Overall Stats
========================================
Lines Processed         100000
Commands/Sec            7276.82

Top Prefixes
========================================
ar_xxx         49849   (49.85%)

Top Keys
========================================
c8a87fxxxxx        49943   (49.94%)
a_r:xxxx           49849   (49.85%)

Top Commands
========================================
GET             49964   (49.96%)
AUTH            49943   (49.94%)
SELECT          88      (0.09%)

系统是否使用较大的集合键

系统使用大key导致集群节点容量或qps倾斜,比如一个5kw字段的hash key, 内存占用在近10GB,这个key所在slot的节点的内存容量或qps都很有可能倾斜。

这类集合key每次操作几个字段,很难从proxy或sdk发现key的大小。

可使用redis-cli --bigkeys 分析节点存在的大键。如果需全量分析,可使用redis-rdb-tools(https://github.com/sripathikrishnan/redis-rdb-tools) 对节点的RDB文件全量分析,通过结果size_in_bytes列得到大key的占用内存字节数。

示例使用redis-cli 进行抽样分析:

redis-cli  --bigkeys -p 7000                                 

# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).
[00.00%] Biggest string found so far 'key:000000019996' with 1024 bytes
[48.57%] Biggest list   found so far 'mylist' with 534196 items
-------- summary -------
Sampled 8265 keys in the keyspace!
Total key length in bytes is 132234 (avg len 16.00)

Biggest string found 'key:000000019996' has 1024 bytes
Biggest   list found 'mylist' has 534196 items

8264 strings with 8460296 bytes (99.99% of keys, avg size 1023.75)
1 lists with 534196 items (00.01% of keys, avg size 534196.00)

检查集群每个分片的数据槽分配是否均匀

下面以Redis Cluster集群为例确认集群中,每个节点负责的数据槽位(slots)和key个数。下面demo的部分实例存在不轻度“倾斜”但不严重,可考虑进行reblance.

redis-trib.rb info redis_ip:port
nodeip:port (5e59101a...) -> 44357924 keys | 617 slots | 1 slaves.
nodeip:port (72f686aa...) -> 52257829 keys | 726 slots | 1 slaves.
nodeip:port (d1e4ac02...) -> 45137046 keys | 627 slots | 1 slaves.
---------------------省略------------------------
nodeip:port (f87076c1...) -> 44433892 keys | 617 slots | 1 slaves.
nodeip:port (a7801b06...) -> 44418216 keys | 619 slots | 1 slaves.
nodeip:port (400bbd47...) -> 45318509 keys | 614 slots | 1 slaves.
nodeip:port (c90a36c9...) -> 44417794 keys | 617 slots | 1 slaves.
[OK] 1186817927 keys in 25 masters.
72437.62 keys per slot on average.

系统是否大量使用keys hash tags

在redis集群中,有些业务为达到多键的操作,会使用hash tags把某类key分配同一个分片,可能导致数据、qps都不均匀的问题。可使用scan扫描keyspace是否有使用hash tags的,或使用monitor,vc-redis-sniffer工具分析倾斜节点,是否大理包含有hash tag的key。

是否因为client output buffer异常,导致内存容量倾斜

确认是否有client出现output buffer使用量异常,引起内存过大的问题;比如执行monitor、keys命令或slave同步full sync时出现客户端输入缓冲区占用过大。

这类情况基本redis实例内存会快速增长,很快会出现回落。通过监测client输出缓冲区使用情况;分析见下面示例:

# 通过监控client_longest_output_list输出列表的长度,是否有client使用大量的输出缓冲区.
redis-cli  -p 7000 info clients
# Clients
connected_clients:52
client_longest_output_list:9179
client_biggest_input_buf:0
blocked_clients:0

# 查看输出缓冲区列表长度不为0的client。 可见monitor占用输出缓冲区370MB
redis-cli  -p 7000 client list | grep -v "oll=0"
id=1840 addr=xx64598  age=75 idle=0 flags=O obl=0 oll=15234 omem=374930608 cmd=monitor

如何有效避免Redis集群倾斜问题

  • 系统设计redis集群键空间和query pattern时,应避免出现热点key, 如果有热点key逻辑,尽量打散分布不同的节点或添加程序本地缓存;

  • 系统设计redis集群键空间时,应避免使用大key,把key设计拆分打散;大key除了倾斜问题,对集群稳定性有严重影响;

  • redis集群部署和扩缩容处理,保证数据槽位分配平均;

  • 系统设计角度应避免使用keys hash tag;

  • 日常运维和系统中应避免直接使用keys,monitor等命令,导致输出缓冲区堆积;这类命令建议作rename处理;

  • 合量配置normal的client output buffer, 建议设置10mb,slave限制为1GB按需要临时调整(警示:和业务确认调整再修改,避免业务出错)

在实际生产业务场景中,大规模集群很难做到集群的完全均衡,只是尽量保证不出现严重倾斜问题。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java系列】Mybatis-Plus 使用方式介绍

1 Mybatis-Plus简介 Mybatis-Plus 提供了多种方式来执行 SQL,包括使用注解、XML 映射文件和 Lambda 表达式等。其中,使用 Lambda 表达式是 Mybatis-Plus 推荐的方式,因为它更加直观和类型安全。 2 使用方法 1 Lambda 表达式执行 SQL 以下是…

pix2pixHD---loss---损失函数

在Pix2PixHDModel代码中首先定义损失: 首先看第一个:输入的两个参数use_gan_feat_loss, use_vgg_loss默认为false,则前缀有not,所以两个参数都是True。 def init_loss_filter(self, use_gan_feat_loss, use_vgg_loss):flags (Tr…

PCIE知识点-022:PCIe 参考时钟结构

图1:参考时钟结构示意图[4] 1. Common Refclk Architecture Common Refclk Architecture,即同源参考时钟架构,PCIe收发设备共用一个时钟源,是目前是使用最为广泛的方案。 缺点: 对于适用同一 Common Clock 作为参考时…

第四章 运行时数据区

文章目录 前言一、🚗 双亲委派机制1、 问题的引出:是否会被外来程序对系统进行破坏2、总结3、双亲委派的优势4、沙箱安全机制5、其他 二、🚒 运行时数据区线程 三、🛺 PC 寄存器概述(记录下一条程序指令的地址&#xf…

Vulnhub: dpwwn: 1靶机

kali:192.168.111.111 靶机:192.168.111.131 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.131 爆破出mysql的root用户为空密码 hydra -l root -P /usr/share/wordlists/rockyou.txt 192.168.111.131 -s 3306 mysq…

UI自动化 Xpath定位必知必会

目录 javascript xpath定位 定位单个元素: 定位多个元素: 验证xpath定位语法是否OK 尽量使用模糊匹配定位元素 模糊匹配contains 使用关联文本值定位 text() 在UI自动化测试中用的最频繁的就是xpath定位了,所以用好xpath定位至关重要&…

关于中断的几个小问题

1. intel 8259芯片中的IRQ2和int2的区别是什么? 答曰:IRQ2是芯片上的引脚,而int2是中断向量表的第2项,两者有很大区别。 Intel8259A芯片的中断引脚分别为: 主片: 0:8254时钟 1:键盘 …

【python代码】Kittle数据集的ground truth生成深度图攻略|彩色深度图|代码无恼运行

目录 1.明确KITTLE数据集特性 2.选择groundtruth 3.转换深度图 4.转换彩色深度图 1.明确KITTLE数据集特性 KITTI数据集包含了来自车载传感器的多模态数据,包括激光雷达、摄像头和GPS/惯性测量单元(IMU)等。该数据集主要采集于城市环境中…

B3645 数列前缀和 20

题目描述 给定一个长度为 n 的数列 a,请回答 q 次询问,每次给定 l,r,请求出 ()​mod p 的值,其中 p1,145,141。 输入格式 第一行是两个整数,依次表示数列长度 n 和询问次数 q。 第二行有 n 个整数,第 …

Qt下QTcpServer服务端识别多个QTcpSocket客户端

文章目录 Qt官方文档编写QTcpServerDemo和QTcpSocketDemo实现QTcpServerDemo实现QTcpSocketDemo 使用windeployqt生成程序运行所需依赖文件 Qt官方文档 QTcpSocket Class :https://doc.qt.io/qt-5/qtcpsocket.html QAbstractSocket Class:https://doc.q…

分布式RPC框架Dubbo详解

目录 1.架构演进 1.1 单体架构 1.2 垂直架构 1.3 分布式架构 1.4 SOA架构 1.5 微服务架构 2.RPC框架 2.1 RPC基本概念介绍 2.1.1 RPC协议 2.1.2 RPC框架 2.1.3 RPC与HTTP、TCP/ UDP、Socket的区别 2.1.4 RPC的运行流程 2.1.5 为什么需要RPC 2.2 Dubbo 2.2.1 Dub…

Redis的网络模型(未完成)

Redis是单线程还是多线程? 1)如果只是针对于Redis的核心业务部分(命令处理),答案是单线程 2)如果是说整个redis,那么就是多线程 在Redis的版本迭代过程中,在两个非常重要的时间节点上引入了对多线程的支持: 1)在Redis4.0版本中&am…

redis第二章-第一课-持久化rdb和aof以及混合模式

RDB快照 1.在默认情况下, Redis 将内存数据库快照保存在名字为 dump.rdb 的二进制文件中,默认存储在redis的当前目录下,也就是和redis.conf同级目录下,可以修改位置 2.你可以对 Redis 进行设置, 让它在“ N 秒内数据…

小白怎么入门CTF,看这个就够了(附学习笔记、靶场、工具包下载)

CTF靶场:CTF刷题,在校生备战CTF比赛,信安入门、提升自己、丰富简历之必备(一场比赛打出好成绩,可以让你轻松进大厂,如近期的各种CTF杯),在职人员可以工作意外提升信安全技能。 渗透…

00后太卷了,搞的我们这些老油条太难受了......

前几天我们公司一下子也来了几个新人,这些年前人是真能熬啊,本来我们几个老油子都是每天稍微加会班就打算走了,这几个新人一直不走,搞得我们也不好走。 2023年春招结束了,最近内卷严重,各种跳槽裁员&#x…

rk3568 点亮LCD(DP)

rk3568 rk3399 Android11/12 适配 DP DisplayPort(简称DP)是第一个依赖数据包化数据传输技术的显示通信端口。是一个由PC及芯片制造商联盟开发,视频电子标准协会标准化的数字式视频接口标准。主要用于视频源与显示器等设备的连接&#xff0c…

进程管理(笔记)

如果对内存寻址熟悉的话, 或者认真看过上一节的内容: 内存管理之内存寻址: https://blog.csdn.net/qq_40482358/article/details/130868188. 那么对linux系统中的进程管理应该已经有一个初步的认识了: cr3作为一个控制寄存器, 描述当前进程的页目录的物理内存基地址, 当进程切换…

SpringCloud Ribbon 学习

SpringCloud Ribbon 学习 文章目录 SpringCloud Ribbon 学习1. Ribbon 是什么?2. LB(Load Balance)3 Ribbon 架构图&机制4 Ribbon 常见负载均衡算法5 测试 1. Ribbon 是什么? Spring Cloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端 负载均衡…

Docker容器与虚拟机(VM)大对比

Docker是一个开源应用容器引擎。Docker可以将应用程序与基本架构分开,从而快速交付软件。 传统虚拟机的运行需要占用较高的资源,包括磁盘空间、内存和处理器性能。每个虚拟机都需要完整的操作系统和应用程序副本,这在资源利用和启动时间上存…

好玩!AI文字RPG游戏;播客进入全AI时代?LangChain项目实践手册;OpenAI联创科普GPT | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 🤖 Microsoft Build 中国黑客松挑战赛,进入AI新纪元 近期,伴随着人工智能的新一轮浪潮,Hackathon (黑…