热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

浅析Redis分布式集群倾斜问题

来源:快看技术产品团队对于分布式系统而言,整个集群处理请求的效率和存储容量,往往取决于集群中响应最慢或存储增长最快的节点。所以在系统设计和容量规划时,我们尽量保

来源:快看技术产品团队


对于分布式系统而言,整个集群处理请求的效率和存储容量,往往取决于集群中响应最慢或存储增长最快的节点。所以在系统设计和容量规划时,我们尽量保障集群中各节点的“数据和请求分布均衡“。但在实际生产系统中,出现数据容量和请求倾斜(类似Data Skew)问题是比较常见的。


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

redis分布式集群倾斜问题,主要分为两类:1 数据存储容量倾斜,数据存储总是落到集群中少数节点; 2 qps请求倾斜,qps总是落到少数节点。


本文主要从以下几点分析redis分布式集群倾斜:


  • redis集群出现倾斜的影响;

  • 导致redis集群倾斜的常见原因;

  • redis集群倾斜问题的排查方式;

  • 如何有效避免redis集群倾斜问题。

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](http://redis.io/topics/cluster-spec), 可能导致某些数据槽位的key数量多,集群集群出现qps和容量倾斜;

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

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


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


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


当集群因热点key导致集群qps倾斜,需快速定位热点key和top commands。可使用开源工具[redis-faina](https://github.com/facebookarchive/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.01of keysavg 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](https://www.vividcortex.com/resources/network-analyzer-for-redis)工具分析倾斜节点,是否大理包含有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按需要临时调整(警示:和业务确认调整再修改,避免业务出错)

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





          推荐阅读
          • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
          • flowable工作流 流程变量_信也科技工作流平台的技术实践
            1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
          • 浏览器中的异常检测算法及其在深度学习中的应用
            本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
          • Oracle优化新常态的五大禁止及其性能隐患
            本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
          • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
          • 云原生应用最佳开发实践之十二原则(12factor)
            目录简介一、基准代码二、依赖三、配置四、后端配置五、构建、发布、运行六、进程七、端口绑定八、并发九、易处理十、开发与线上环境等价十一、日志十二、进程管理当 ... [详细]
          • ejava,刘聪dejava
            本文目录一览:1、什么是Java?2、java ... [详细]
          • 旁路|发生_Day749.旁路缓存:Redis是如何工作的Redis 核心技术与实战
            篇首语:本文由编程笔记#小编为大家整理,主要介绍了Day749.旁路缓存:Redis是如何工作的-Redis核心技术与实战相关的知识,希望对你有一定的参考价值。 ... [详细]
          • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
          • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
          • 企业数据应用挑战及元数据管理的重要性
            本文主要介绍了企业在日常经营管理过程中面临的数据应用挑战,包括数据找不到、数据读不懂、数据不可信等问题。针对这些挑战,通过元数据管理可以实现数据的可见、可懂、可用,帮助业务快速获取所需数据。文章提出了“灵魂”三问——元数据是什么、有什么用、又该怎么管,强调了元数据管理在企业数据治理中的基础和前提作用。 ... [详细]
          • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
            在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
          • 本文讨论了在使用Git进行版本控制时,如何提供类似CVS中自动增加版本号的功能。作者介绍了Git中的其他版本表示方式,如git describe命令,并提供了使用这些表示方式来确定文件更新情况的示例。此外,文章还介绍了启用$Id:$功能的方法,并讨论了一些开发者在使用Git时的需求和使用场景。 ... [详细]
          • {moduleinfo:{card_count:[{count_phone:1,count:1}],search_count:[{count_phone:4 ... [详细]
          • Harmony 与 Game Space 达成合作,在 Shard1 上扩展 Web3 游戏
            旧金山20 ... [详细]
          author-avatar
          Fate丶灬小庆_926
          这个家伙很懒,什么也没留下!
          PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
          Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有