面试经典-Redis数据库的数据倾斜

一、定义

对于集群系统,一般缓存是分布式的,即不同节点负责一定范围的缓存数据。我们把缓存数据分散度不够,导致大量的缓存数据集中到了一台或者几台服务节点上,称为数据倾斜。一般来说数据倾斜是由于负载均衡实施的效果不好引起的。

二、危害

如果发生了数据倾斜,那么就会有某一台机器或几台保存了大量数据。轻则造成性能下降,处理请求速度骤降。重则造成Redis服务器崩溃,缓存服务不可用,将性能影响范围扩散到DB层,对后端服务造成不可估量的后果。

三、写入倾斜

1、bigkey导致倾斜

bigkey指的是某个 Redis 实例上保存了一个很大的 value (String 类型)或者是大量的集合元素(集合类型)的 key ,这个 key 就被称之为 bigkey ,而bigkey这种情况会导致集群中的某个实例的数据量很大,内存资源消耗也相应增加。

应对方案

在业务层生成数据时,要尽量避免把过多的数据保存在同一个键值对中。如果 bigkey 正好是集合类型,还有一个方法,就是把 bigkey 拆分成很多个小的集合类型数据,分散保存在不同的实例上。

2、Slot分配不均导致倾斜

介绍一下slot,slot全称HashSlot(哈希槽),类似于数据分区,每个key都会根据Hash算法计算出它应该属于哪个哈希槽,最终落到那个哈希槽中。而 Redis Cluster 就是采用哈希槽的方式来处理数据和实例间的映射关系。事实上,在 Redis Cluster 分片集群中一共有16384 个 Slot。 这里的Hash算法市面上的方式一般是先计算hash值,然后将计算结果对slot个数取模,最终确定落到哪个slot上。而计算hash值的算法有很多,常用的像CRC16、CRC64、sha1等等 运维在构建切片集群时候,需要手动分配哈希槽,并且把16384 个槽都分配完,否则 Redis 集群无法正常工作。由于是手动分配,则可能会导致部分实例所分配的slot过多,导致数据倾斜。

应对方案

使用CLUSTER SLOTS 命令来查看slot分配情况,使用CLUSTER SETSLOT,CLUSTER GETKEYSINSLOT,MIGRATE这三个命令来进行slot数据的迁移,具体内容不再这里细说,感兴趣的同学可以自行学习一下。

3、Hash Tag导致倾斜

Hash Tag 定义 :指当一个key包含 {} 的时候,就不对整个key做hash,而仅对 {} 包括的字符串做hash。假设hash算法为sha1。

对user:{user1}:ids和user:{user1}:tweets,其hash值都等同于sha1(user1)。

也就是说,如果不同 key 的 Hash Tag 内容都是一样的,那么,这些 key 对应的数据会被映射到同一个 Slot 中,同时会被分配到同一个实例上。

所以,如果不合理使用Hash Tag,会导致大量的数据可能被集中到一个实例上发生数据倾斜,集群中的负载不均衡。

应对方案

按照需求合理使用Hash Tag,甚至可以考量是否需要用到Hash Tag。

四、读取倾斜(热key)

一般来说,读取倾斜大多数都是热key问题导致的。如图所示,虽然每个集群实例上的数据量相差并没有很大,但是如果其中某个实例上的数据是热点数据,那台实例就会被访问得非常频繁。

原因:用户消费的数据远大于生产的数据(热卖商品、热点新闻、热点评论、明星直播)。

在日常工作中一些突发的事件,例如:双十一期间某些热门商品在进行降价促销或秒杀时,这时某一件商品会被数万次点击浏览或者购买,会形成一个较大的需求量,这种情况下就很容易造成热点问题。

同理,被大量浏览的热点数据、明星直播等,这些典型的读多写少的场景也会产生热点问题。

危害:请求分片集中,超过单 Server 的性能极限。

在服务端读数据访问Redis时,往往会对请求key进行分片计算,此时中会将请求打到某一台 Server 上,如果热点过于集中,热点 Key 的缓存过多,访问量超过 Server 极限时,就会出现缓存分片服务被打垮现象的产生。当缓存服务崩溃后,此时再有请求产生,就会打到DB 上,这也就是我们常说的缓存穿透,如果没有合理的解决,数据库又没有扛住大量的穿透请求,则会进一步导致数据库雪崩现象。造成所有连接此数据库的系统服务不可用,上下游调用链中断,产生不可估量的后果。

五、热key解决方案

1、拆分热key

拆分热key,指的是把热点数据拆分成多份,在每份数据副本的 key 中增加一个随机后缀,让它和其它副本数据不会被映射到同一个 Slot 中。这里相当于把一份数据复制到多个实例上,通过Hash算法实现一个简陋的负载均衡。同样的,在读取的时候也要增加随机后缀,将对一个实例的读取压力,均摊到多个实例上。

例如:我们在放入缓存时就将对应业务的缓存key拆分成多个不同的key。如下图所示,在写入缓存的过程中,我们首先将key拆成N份,比如某个请求进来的key名字叫做"hot_key",那我们就可以把它拆成“hot_key_001”、“hot_key_002”、“hot_key_003”、“hot_key_004”…,当然了,每次更新和新增时都要记得去改动这N个key,这就是拆key。
对于Service端来讲,我们要尽可能的将访问流量分流的足够的均匀。 如何给即将访问的热key上合理的加入后缀?说一下市面上常用的方案,根据本机的ip或mac地址做hash,之后的值与拆key的数量做取余,最终决定拼接成什么样的key后缀,从而打到哪台机器上。当然也有其他的解决方案,比如在服务启动时的一个随机数对拆key的数量做取余。

public boolean getRandomHotKey(String hotKey,int count) {
        int random = new Random().nextInt(count);
        randomKey = hotKey + "_" + random;
        Object data = redis.get(randomKey);
        if (data == null){
            data = getFromDB(); 
            redis.set(randomKey,expireTime + random);
        }
    }

2、多级缓存+动态计算自动发现热点缓存

该方案主要是通过主动发现热点并对其进行本地缓存来解决热点 Key 的问题。对,你没有听错,就是在缓存上再架设一层缓存。具体来说,就是在 Proxy上增加本地缓存,本地缓存采用LRU算法来缓存热点数据,后端节点增加热点数据计算模块来返回热点数据。当然了,Client会访问SLB,并且通过SLB将各种请求分发至Proxy中,Proxy会按照基于路由的方式将请求转发至Redis中。

Proxy 架构的主要有以下优点:

  • Proxy 本地缓存热点,读能力可水平扩展
  • DB 节点定时计算热点数据集合
  • DB 反馈 Proxy 热点数据
  • 对客户端完全透明,不需做任何兼容

六、热点数据的发现与存储

对于热点数据的发现,首先会在一个周期内对 Key 进行请求统计,在达到请求量级后会对热点 Key 进行热点定位,并将所有的热点 Key 放入一个小的 LRU 链表内,在通过 Proxy 请求进行访问时,若 Redis 发现待访点是一个热点,就会进入一个反馈阶段,同时对该数据进行标记。

可以使用一个etcd或者zk集群来存储反馈的热点数据,然后本地所有节点监听该热点数据,进而加载到本地JVM缓存中。

在热点 Key 的处理上主要分为写入跟读取两种形式,在数据写入过程当 SLB 收到数据 Key1 并将其通过某一个 Proxy 写入一个 Redis,完成数据的写入。

假若经过后端热点模块计算发现 Key1 成为热点 key 后, Proxy 会将该热点进行本地缓存,当下次客户端再进行访问 Key1 时,则可以不读取 Redis,直接从 Proxy 返回数据。

注意:由于 Proxy 是可以水平扩充的,因此可以任意增强热点数据的访问能力。

七、JD开源hotKey

上述的缓存倾斜解决思路,目前较为成熟解决方案是京东开源的项目HotKey,它拥有自动探测热Key、分布式一致性缓存的设计。原理就是在Client端做洞察;然后上报对应Hotkey,Server端检测到后,将对应Hotkey下发到对应服务端做本地缓存,并且能保证本地缓存和远程缓存的一致性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SPN的相关利用(下)

Kerberoasting kerberos通信过程: 在TGS-REQ中会发出ST服务票据获取servicePrincipalName(SPN),该SPN是用户或者机器用户注册的。TGS-REP中TGS会返回给user一个ST,而ST是由user请求的server的密码进行加密的,我们可以从TGS-REP中…

RT-Thread时钟管理

操作系统需要通过时间来规范其任务,主要介绍时钟节拍和基于时钟节拍的定时器。 时钟节拍 任何操作系统都需要提供一个时钟节拍,以供系统处理所有和时间有关的事件,如线程的延时、线程的时间片轮转调度以及定时器超时等。 RT-Thread 中,时钟节拍的长度可以根据 RT_TICK_P…

Module外贸主题开心版下载-v5.7.0版本WordPress企业模板

主题下载地址:Module外贸主题开心版下载-v5.7.0版本 Module主题介绍:采用全新模块化开发,首页模块可视化拖拽自由组合,可自定义搭建出不同行业适用的企业网站。同时主题全面支持WPML多语言切换,可轻松搭建外贸网站。W…

JetBrains Rider 2024.1.1 .NET集成开发环境 mac/win

JetBrains Rider是一个新的跨平台的基于Inte lliJ平台和ReSharper的. NET集成技术开发工作环境。 Rider提供了大量人工智能系统代码进行编辑管理功能,如不同类型的代码可以完成、自动设备名称发展空间设计导入、自动通过插入大括号和突出研究显示信息匹配作为分隔符…

torchEEG工具箱

文章信息: 题目:TorchEEGEMO:基于脑电图的情绪识别深度学习工具箱 期刊:Expert Systems with Applications 环境:pytorch 1.11.0 CUDA 11.3 摘要: ​ 一个python工具箱TorchEEG,将工作流程分为五个模块…

软考 - 系统架构设计师 - 架构风格例题

问题一: 什么是软件架构风格? 软件架构风格指特定软件系统组织方式的惯用模式。组织方式描述了系统的组成构件和这些构件的组织方式。惯用模式反映了众多系统所共有的结构和语义。 集成开发环境与用户的交互方式 (实际上询问在交互方面&am…

干货-PMP常考知识点,都给你们汇总到这里了

PMP认证考试考来考去,其实就是那些知识点。把这些知识点吃透了,你会发现做题稳准狠。不仅速度快,正确率也有很大的提升。 我们结合了10几年PMP备考辅导经验,给大家梳理了这些PMP常考的知识点集锦,希望能帮到大家&#…

css中all 的使用记录

all 在 CSS 中是一个特殊的属性值,它允许我们重置元素或元素父级的所有属性到其初始值、继承的值或取消设置的值。这一属性非常有用,特别是在需要快速重置多个属性的情况下,它避免了逐一设置每个属性的繁琐过程。 先看一下浏览器兼容性&#…

【SAP HANA 15】SQL锁表 (查询,解锁)

锁表查看 --锁表检查语句 SELECT C.CONNECTION_ID,PS.STATEMENT_STRINGFROM M_CONNECTIONS C JOIN M_PREPARED_STATEMENTS PSON C.CONNECTION_ID PS.CONNECTION_ID AND C.CURRENT_STATEMENT_ID PS.STATEMENT_IDWHERE C.CONNECTION_STATUS RUNNINGAND C.CONNECTION_TYPE Re…

第二届数据安全大赛暨首届“数信杯”数据安全大赛数据安全积分争夺赛-东区预赛部分WP

这里写目录标题 检材下载:1.理论题2.数据安全:pb:Sepack: 3.数据分析:数据分析(1)数据分析1-1:数据分析1-2:数据分析1-3: 数据分析(3)数据分析3-1:数据分析3-2&#xff1…

2024年04月18日优雅草便民tools开源-git以及dcloud同步-长期更新

优雅草小工具-数据来自优雅草api赋能 优雅草小工具-数据来自优雅草api赋能-优雅草便民工具是一款由成都市一颗优雅草科技有限公司打造的便民查询公益工具,2024年1月17日正式发布v1.0.0版本,本工具为了方便大众免费使用,本生活小工具会陆续加入…

Oracle——领先的企业级数据库解决方案

一、WHAT IS ORACLWE: ORACLE 数据库系统是美国 ORACLE 公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S 体系结构的数据库之一,ORACLE 通常应用于大型系统的数…

C#基于SSE传递消息给Vue前端实现即时单向通讯

一、简述 通常前端调用后端的API,调用到了,等待执行完,拿到返回的数据,进行渲染,流程就完事了。如果想要即时怎么办?如果你想问什么场景非要即时通讯,那可就很多了,比如在线聊天、实…

gpt能生成ppt吗

gpt能生成ppt吗 GPT是一个高度通用的工具,适用于多种场景和领域,制作ppt只是它强大功能的冰山一角,具体包括: 信息查询与解释: 提供科学、技术、历史、文化等领域的详细解释和背景信息。 解答疑问,帮助…

前端css中transition的使用

前端css中transition的使用 一、前言二、transition的4个属性三、例子1.源码12.源码1运行效果 四、结语五、定位日期 一、前言 CSS中的transition(过渡),根据字面意思就可以理解成一种变化状态的过程。当我们有一个方形,我们想让…

Java在MySQL数据报错Data truncation: Data too long for column ‘**‘ at row 1 处理

问题 在Java SpringBoot MyBatis 框架的项目中,一切正常,不过在一个接口的参数字段传入过大的数据就会报此错误: 请求常:org.springframework.dao.DataIntegrityViolationException: Error updating database.Cause:com.mysql.cj.jdbc.excep…

漫画项目管理 | 遇到强势甲方的不合理项目需求,我该怎么办?

🤷‍♂️ 遇到甲方强烈要求不合理需求怎么办? 🤸‍♂️看似离谱的功能客户却一定要加? 🤹‍♂️时间紧任务重,甲方却“什么都想要“? 🤾‍♂️明明初稿很完美,却被要求改来改去?** 👨‍…

学习STM32第十六天

RTC实时时钟 一、简介 RTC是一个独立的BCD格式定时器,提供一个时钟日历,两个可编程报警中断,一个具有中断功能周期性可编程唤醒标志,RTC和时钟配置系统处于后备区域。 通过两个32位寄存器以BCD格式实现秒、分钟、小时&#xff08…

Qt日志使用

QsLog使用 这篇讲qt的日志还是比较好的,可以在自己的函数里面配置这个日志框架实现自己所需的功能。 我接触的项目里面,假如有个函数功能执行错误了,我希望可以快速定位到这个错误,这个时候就需要到了日志,我咨询了有经…

使用Python脚本检测服务器信息并定时发送至管理员邮箱

在日常的系统管理工作中,监测服务器的资源占用情况至关重要,我们需要及时获得通知以便采取相应措施。我新装了一台UbuntuServer服务器,写了一个可以定期收集服务器的CPU、内存、网络和磁盘信息,并通过邮件将这些信息发送给管理员的…
最新文章