Redis 数据分布优化:如何应对数据倾斜?

这篇具有很好参考价值的文章主要介绍了Redis 数据分布优化:如何应对数据倾斜?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Redis 核心技术与实战 笔记
作者: 蒋德钧

在切片集群中,数据会按照一定的分布规则分散到不同的实例上保存。比如,在使用 Redis Cluster 或 Codis 时,数据都会先按照 CRC 算法的计算值对 Slot(逻辑槽)取模,同时,所有的 Slot 又会由运维管理员分配到不同的实例上。这样,数据就被保存到相应的实例上了。

虽然这种方法实现起来比较简单,但是很容易导致一个问题:数据倾斜。

数据倾斜有两类。

  • 数据量倾斜:在某些情况下,实例上的数据分布不均衡,某个实例上的数据特别多。
  • 数据访问倾斜:虽然每个集群实例上的数据量相差不大,但是某个实例上的数据是热点数据,被访问得非常频繁。

如果发生了数据倾斜,那么保存了大量数据,或者是保存了热点数据的实例的处理压力就会增大,速度变慢,甚至还可能会引起这个实例的内存资源耗尽,从而崩溃。这是我们在应用切片集群时要避免的。

今天这节课,我就来和你聊聊,这两种数据倾斜是怎么发生的,我们又该怎么应对。

数据量倾斜的成因和应对方法

首先,我们来看数据量倾斜的成因和应对方案。

当数据量倾斜发生时,数据在切片集群的多个实例上分布不均衡,大量数据集中到了一个或几个实例上,如下图所示:

Redis 数据分布优化:如何应对数据倾斜?

那么,数据量倾斜是怎么产生的呢?这主要有三个原因,分别是某个实例上保存了 bigkey、Slot 分配不均衡以及 Hash Tag。接下来,我们就一个一个来分析,同时我还会给你讲解相应的解决方案。

bigkey 导致倾斜

第一个原因是,某个实例上正好保存了 bigkey。bigkey 的 value 值很大(String 类型),或者是 bigkey 保存了大量集合元素(集合类型),会导致这个实例的数据量增加,内存资源消耗也相应增加。

而且,bigkey 的操作一般都会造成实例 IO 线程阻塞,如果 bigkey 的访问量比较大,就会影响到这个实例上的其它请求被处理的速度。

其实,bigkey 已经是我们课程中反复提到的一个关键点了。为了避免 bigkey 造成的数据倾斜,一个根本的应对方法是,我们在业务层生成数据时,要尽量避免把过多的数据保存在同一个键值对中。

此外,如果 bigkey 正好是集合类型,我们还有一个方法,就是把 bigkey 拆分成很多个小的集合类型数据,分散保存在不同的实例上。

我给你举个例子。假设 Hash 类型集合 user:info 保存了 100 万个用户的信息,是一个 bigkey。那么,我们就可以按照用户 ID 的范围,把这个集合拆分成 10 个小集合,每个小集合只保存 10 万个用户的信息(例如小集合 1 保存的是 ID 从 1 到 10 万的用户信息,小集合 2 保存的是 ID 从 10 万零 1 到 20 万的用户)。这样一来,我们就可以把一个 bigkey 化整为零、分散保存了,避免了 bigkey 给单个切片实例带来的访问压力。

需要注意的是,当 bigkey 访问量较大时,也会造成数据访问倾斜,我一会儿再给你讲具体怎么应对。

接下来,我们再来看导致数据量倾斜的第二个原因:Slot 分配不均衡。

Slot 分配不均衡导致倾斜

如果集群运维人员没有均衡地分配 Slot,就会有大量的数据被分配到同一个 Slot 中,而同一个 Slot 只会在一个实例上分布,这就会导致,大量数据被集中到一个实例上,造成数据倾斜。

我以 Redis Cluster 为例,来介绍下 Slot 分配不均衡的情况。

Redis Cluster 一共有 16384 个 Slot,假设集群一共有 5 个实例,其中,实例 1 的硬件配置较高,运维人员在给实例分配 Slot 时,就可能会给实例 1 多分配些 Slot,把实例 1 的资源充分利用起来。

但是,我们其实并不知道数据和 Slot 的对应关系,这种做法就可能会导致大量数据正好被映射到实例 1 上的 Slot,造成数据倾斜,给实例 1 带来访问压力。

为了应对这个问题,我们可以通过运维规范,在分配之前,我们就要避免把过多的 Slot 分配到同一个实例。如果是已经分配好 Slot 的集群,我们可以先查看 Slot 和实例的具体分配关系,从而判断是否有过多的 Slot 集中到了同一个实例。如果有的话,就将部分 Slot 迁移到其它实例,从而避免数据倾斜。

不同集群上查看 Slot 分配情况的方式不同:如果是 Redis Cluster,就用 CLUSTER SLOTS 命令;如果是 Codis,就可以在 codis dashboard 上查看。

比如说,我们执行 CLUSTER SLOTS 命令查看 Slot 分配情况。命令返回结果显示,Slot 0 到 Slot 4095 被分配到了实例 192.168.10.3 上,而 Slot 12288 到 Slot 16383 被分配到了实例 192.168.10.5 上。

127.0.0.1:6379> cluster slots
1) 1) (integer) 0
   2) (integer) 4095
   3) 1) "192.168.10.3"
      2) (integer) 6379
2) 1) (integer) 12288
   2) (integer) 16383
   3) 1) "192.168.10.5"
      2) (integer) 6379

如果某一个实例上有太多的 Slot,我们就可以使用迁移命令把这些 Slot 迁移到其它实例上。在 Redis Cluster 中,我们可以使用 3 个命令完成 Slot 迁移。

  1. CLUSTER SETSLOT:使用不同的选项进行三种设置,分别是设置 Slot 要迁入的目标实例,Slot 要迁出的源实例,以及 Slot 所属的实例。
  2. CLUSTER GETKEYSINSLOT:获取某个 Slot 中一定数量的 key。
  3. MIGRATE:把一个 key 从源实例实际迁移到目标实例。我来借助一个例子,带你了解下这三个命令怎么用。

我来借助一个例子,带你了解下这三个命令怎么用。假设我们要把 Slot 300 从源实例(ID 为 3)迁移到目标实例(ID 为 5),那要怎么做呢?

实际上,我们可以分成 5 步。

第 1 步,我们先在目标实例 5 上执行下面的命令,将 Slot 300 的源实例设置为实例 3,表示要从实例 3 上迁入 Slot 300。

CLUSTER SETSLOT 300 IMPORTING 3

第 2 步,在源实例 3 上,我们把 Slot 300 的目标实例设置为 5,这表示,Slot 300 要迁出到实例 5 上,如下所示:

CLUSTER SETSLOT 300 MIGRATING 5

第 3 步,从 Slot 300 中获取 100 个 key。因为 Slot 中的 key 数量可能很多,所以我们需要在客户端上多次执行下面的这条命令,分批次获得并迁移 key。

CLUSTER GETKEYSINSLOT 300 100

第 4 步,我们把刚才获取的 100 个 key 中的 key1 迁移到目标实例 5 上(IP 为 192.168.10.5),同时把要迁入的数据库设置为 0 号数据库,把迁移的超时时间设置为 timeout。我们重复执行 MIGRATE 命令,把 100 个 key 都迁移完。

MIGRATE 192.168.10.5 6379 key1 0 timeout

最后,我们重复执行第 3 和第 4 步,直到 Slot 中的所有 key 都迁移完成。

从 Redis 3.0.6 开始,你也可以使用 KEYS 选项,一次迁移多个 key(key1、2、3),这样可以提升迁移效率。

MIGRATE 192.168.10.5 6379 "" 0 timeout KEYS key1 key2 key3

对于 Codis 来说,我们可以执行下面的命令进行数据迁移。其中,我们把 dashboard 组件的连接地址设置为 ADDR,并且把 Slot 300 迁移到编号为 6 的 codis server group 上。

codis-admin --dashboard=ADDR -slot-action --create --sid=300 --gid=6

除了 bigkey 和 Slot 分配不均衡会导致数据量倾斜,还有一个导致倾斜的原因,就是使用了 Hash Tag 进行数据切片。

Hash Tag 导致倾斜

Hash Tag 是指加在键值对 key 中的一对花括号{}。这对括号会把 key 的一部分括起来,客户端在计算 key 的 CRC16 值时,只对 Hash Tag 花括号中的 key 内容进行计算。如果没用 Hash Tag 的话,客户端计算整个 key 的 CRC16 的值。

举个例子,假设 key 是 user:profile:3231,我们把其中的 3231 作为 Hash Tag,此时,key 就变成了 user:profile:{3231}。当客户端计算这个 key 的 CRC16 值时,就只会计算 3231 的 CRC16 值。

否则,客户端会计算整个“user:profile:3231”的 CRC16 值。使用 Hash Tag 的好处是,如果不同 key 的 Hash Tag 内容都是一样的,那么,这些 key 对应的数据会被映射到同一个 Slot 中,同时会被分配到同一个实例上。

下面这张表就显示了使用 Hash Tag 后,数据被映射到相同 Slot 的情况,你可以看下。

Redis 数据分布优化:如何应对数据倾斜?

其中,user:profile:{3231}和 user:order:{3231}的 Hash Tag 一样,都是 3231,它们的 CRC16 计算值对 16384 取模后的值也是一样的,所以就对应映射到了相同的 Slot 1024 中。user:profile:{5328}和 user:order:{5328}也是相同的映射结果。

那么,Hash Tag 一般用在什么场景呢?其实,它主要是用在 Redis Cluster 和 Codis 中,支持事务操作和范围查询。因为 Redis Cluster 和 Codis 本身并不支持跨实例的事务操作和范围查询,当业务应用有这些需求时,就只能先把这些数据读取到业务层进行事务处理,或者是逐个查询每个实例,得到范围查询的结果。

这样操作起来非常麻烦,所以,我们可以使用 Hash Tag 把要执行事务操作或是范围查询的数据映射到同一个实例上,这样就能很轻松地实现事务或范围查询了。

但是,使用 Hash Tag 的潜在问题,就是大量的数据可能被集中到一个实例上,导致数据倾斜,集群中的负载不均衡。那么,该怎么应对这种问题呢?我们就需要在范围查询、事务执行的需求和数据倾斜带来的访问压力之间,进行取舍了。

我的建议是,如果使用 Hash Tag 进行切片的数据会带来较大的访问压力,就优先考虑避免数据倾斜,最好不要使用 Hash Tag 进行数据切片。因为事务和范围查询都还可以放在客户端来执行,而数据倾斜会导致实例不稳定,造成服务不可用。

好了,到这里,我们完整地了解了数据量倾斜的原因以及应对方法。接下来,我们再来看数据访问倾斜的原因和应对方法。

数据访问倾斜的成因和应对方法

发生数据访问倾斜的根本原因,就是实例上存在热点数据(比如新闻应用中的热点新闻内容、电商促销活动中的热门商品信息,等等)。

一旦热点数据被存在了某个实例中,那么,这个实例的请求访问量就会远高于其它实例,面临巨大的访问压力,如下图所示:

Redis 数据分布优化:如何应对数据倾斜?

那么,我们该如何应对呢?

和数据量倾斜不同,热点数据通常是一个或几个数据,所以,直接重新分配 Slot 并不能解决热点数据的问题。

通常来说,热点数据以服务读操作为主,在这种情况下,我们可以采用热点数据多副本的方法来应对。

这个方法的具体做法是,我们把热点数据复制多份,在每一个数据副本的 key 中增加一个随机前缀,让它和其它副本数据不会被映射到同一个 Slot 中。这样一来,热点数据既有多个副本可以同时服务请求,同时,这些副本数据的 key 又不一样,会被映射到不同的 Slot 中。在给这些 Slot 分配实例时,我们也要注意把它们分配到不同的实例上,那么,热点数据的访问压力就被分散到不同的实例上了。

这里,有个地方需要注意下,**热点数据多副本方法只能针对只读的热点数据。**如果热点数据是有读有写的话,就不适合采用多副本方法了,因为要保证多副本间的数据一致性,会带来额外的开销。

对于有读有写的热点数据,我们就要给实例本身增加资源了,例如使用配置更高的机器,来应对大量的访问压力。

小结

这节课,我向你介绍了数据倾斜的两种情况:数据量倾斜和数据访问倾斜。

造成数据量倾斜的原因主要有三个:

  1. 数据中有 bigkey,导致某个实例的数据量增加;
  2. Slot 手工分配不均,导致某个或某些实例上有大量数据;
  3. 使用了 Hash Tag,导致数据集中到某些实例上。

而数据访问倾斜的主要原因就是有热点数据存在,导致大量访问请求集中到了热点数据所在的实例上。

为了应对数据倾斜问题,我给你介绍了四个方法,也分别对应了造成数据倾斜的四个原因。我把它们总结在下表中,你可以看下。
Redis 数据分布优化:如何应对数据倾斜?

当然,如果已经发生了数据倾斜,我们可以通过数据迁移来缓解数据倾斜的影响。Redis Cluster 和 Codis 集群都提供了查看 Slot 分配和手工迁移 Slot 的命令,你可以把它们应用起来。

最后,关于集群的实例资源配置,我再给你一个小建议:在构建切片集群时,尽量使用大小配置相同的实例(例如实例内存配置保持相同),这样可以避免因实例资源不均衡而在不同实例上分配不同数量的 Slot。文章来源地址https://www.toymoban.com/news/detail-502895.html

到了这里,关于Redis 数据分布优化:如何应对数据倾斜?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spark sql 数据倾斜--join 同时开窗去重的问题优化

    背景: 需求:在一张查询日志表中,有百亿数据,需要join上维表,再根据几个字段进行去重 开窗去重和join 一定要分步进行 ,按照需求先做join再开窗,或者去重完成后在进行join。 dwd_tmp1 中存在百亿用户查询日志数据 数据倾斜 数据量超百亿,资源给到200 * 2c * 20G,执行引擎

    2024年02月11日
    浏览(52)
  • Java接口压力测试—如何应对并优化Java接口的压力测试

    在如今的互联网时代,Java接口压力测试是评估系统性能和可靠性的关键一环。一旦接口不能承受高并发量,用户体验将受到严重影响,甚至可能导致系统崩溃。因此,了解如何进行有效的Java接口压力测试以及如何优化接口性能至关重要。 Java接口压力测试是通过模拟大量并发

    2024年02月12日
    浏览(36)
  • Redis缓存设计与性能优化【缓存和数据库不一致问题,解决方案:1.加过期时间这样可以一段时间后自动刷新 2.分布式的读写锁】

    在大并发下,同时操作数据库与缓存会存在数据不一致性问题 1、双写不一致情况 2、读写并发不一致 解决方案: 1、对于并发几率很小的数据(如个人维度的订单数据、用户数据等),这种几乎不用考虑这个问题,很少会发生缓存不一致, 可以给缓存数据加上过期时间,每隔一

    2024年04月13日
    浏览(51)
  • 如何保证分布式系统中服务的高可用性:应对 ZooKeeper Leader 节点故障的注册处理策略

    作者:zhaokk 在现代分布式系统中,高可用性是一个至关重要的。分布式系统中的各个组件需要保证在各种异常情况下仍然能够正常工作,确保系统的稳定性和可靠性。ZooKeeper(以下简称为zk)作为一种常用的分布式协调服务,为分布式系统中的各种任务提供了基础支持

    2024年02月11日
    浏览(63)
  • 如何解决Flink任务的数据倾斜

    如何解决flink任务的数据倾斜问题 Flink 任务的数据倾斜问题可以通过以下几种方法来解决: 使用滑动窗口:滑动窗口可以将窗口划分成多个子窗口,从而使数据更加均衡地分配到不同的计算节点中。同时,滑动窗口还可以使窗口内的数据更加连续,从而减少数据倾斜的情况。

    2024年02月14日
    浏览(41)
  • (四)库存超卖案例实战——优化redis分布式锁

    在上一节内容中,我们已经实现了使用redis分布式锁解决商品“超卖”的问题,本节内容是对redis分布式锁的优化。在上一节的redis分布式锁中,我们的锁有俩个可以优化的问题。第一,锁需要实现可重入,同一个线程不用重复去获取锁;第二,锁没有续期功能,导致业务没有

    2024年02月07日
    浏览(42)
  • 如何处理生产环境中的数据倾斜问题?

    1、flink数据倾斜的表现: 任务节点频繁出现反压,增加并行度也不能解决问题 部分节点出现OOM异常,是因为大量的数据集中在某个节点上,导致该节点内存被爆,任务失败重启 2、数据倾斜产生的原因: 业务上有严重的数据热点,比如滴滴打车的订单数据中北京、上海等几

    2024年02月10日
    浏览(74)
  • 探索大数据时代的决策利器:如何有效应对海量数据?

    随着信息技术的快速发展,大数据时代已经到来,海量数据成为了我们生活和工作中不可忽视的一部分。这些数据来自各个方面:社交媒体、传感器、网络交易、移动设备等,每天都在以惊人的速度增长。但是,面对如此庞大的数据量,我们该如何有效地应对呢?本文将探索

    2024年03月17日
    浏览(38)
  • 数据要素安全流通:如何应对日益严峻的数据安全问题?

    主页传送门:📀 传送     随着大数据、云计算、人工智能等新兴技术的迅猛发展,数据已经成为我国经济社会发展的五大生产要素之一,《网络安全法》《个人信息保护法》《数据安全法》的先后出台为维护国家安全、保护公民个人信息、规范网络行为以及促进数据经济

    2024年02月08日
    浏览(41)
  • MATLAB与大数据:如何应对海量数据的处理和分析

      在当今数字化时代,大数据已经成为了各行各业的核心资源之一。海量的数据源源不断地涌现,如何高效地处理和分析这些数据已经成为了许多企业和研究机构面临的重要挑战。作为一种功能强大的数学软件工具,MATLAB为我们提供了一种高效、灵活的方式来处理和分析大数

    2024年02月09日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包