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

大数据SQL优化:全面解析数据倾斜解决方案

本文深入探讨了大数据SQL优化中的数据倾斜问题,提供了多种解决策略和实际案例,旨在帮助读者理解和应对这一常见挑战。

前言:本文由编程笔记小编整理,旨在详细介绍大数据SQL优化中的数据倾斜问题及其解决方案,希望能为读者提供有价值的参考。


1. 数据倾斜概述


数据倾斜是指在大数据计算任务中,某个处理任务的进程(通常是一个JVM进程)被分配到过多的任务量,导致任务运行时间过长甚至失败,从而影响整个任务的执行效率。在HiveSQL任务中,可能会观察到map或reduce的进度长时间停留在99%;而在SparkSQL中,则可能表现为某个stage中的任务数量长时间保持在1或2个。如果任务进度信息长时间没有变化,通常意味着出现了数据倾斜。需要注意的是,有时SparkSQL任务显示有1到2个任务在运行,但进度信息不再刷新,这通常是在进行最后阶段的文件操作,并不是数据倾斜,但这可能表明存在小文件问题。


数据倾斜可以细分为以下四类:


1)读倾斜:某个map(HiveSQL)或task(SparkSQL)在读取数据阶段长时间无法完成,通常是因为文件分块过大或数据异常。这种场景相对较少见。


2)算倾斜:在需要排序(如开窗函数或非广播关联)或聚合操作时,同一key(字段或表达式组合)的处理耗时过长。这是最常见的倾斜类型,且情况较为复杂。


3)写倾斜:某个操作需要输出大量数据,例如关联后数据膨胀或某些操作(如limit)只能由一个task完成。


4)文件操作倾斜:数据生成在临时文件夹后,由于文件数量巨大,重命名和移动操作非常耗时。这通常发生在动态分区导致的小文件问题上。目前,国内和印度区域已通过小文件合并解决了这一问题,但在新加坡仍需关注。


2. 数据倾斜的原因


大数据计算依赖于分布式系统,需要将计算任务和数据分发到集群中的各个节点执行,并最终汇总到少数节点进行聚合操作,以及将数据写入HDFS/S3等分布式存储系统。这一过程虽然设计用于应对大多数情况,但仍存在以下几点不足:


1)业务数据分布规律难以预测,系统无法提前知道某个表的字段取值分布是否均匀。


2)计算结果数量难以预测,例如两表关联的结果或对字段值进行split等操作后的结果数量无法提前预知。


3)某些操作只能由单一节点执行,如排序、Limit、count distinct、全局聚合等,这些操作通常会安排到一个节点来执行。


上述特点导致单节点处理的数据量可能极大,从而引发数据倾斜。然而,随着技术的发展,越来越多的优化措施已被提出,未来业务人员可能会减少因数据倾斜带来的困扰。


3. 解决案例


以下案例主要基于SparkSQL,展示了如何解决不同类型的数据倾斜问题。


3.1 事实表关联事实表数据膨胀


业务中有时需要将事实表与事实表进行关联,导致某些key的输出数据量极大,造成数据膨胀和计算倾斜。例如,两个表通过option_id关联,部分key的关联结果可达数十亿行,严重倾斜。解决这一问题的关键在于减少单个task处理的数据量。通过使用collect_set/collect_list等聚合函数,可以将数据收拢,减少行数,再通过explode + lateral view的方式展开,最终恢复到用户期望的明细结果。具体代码示例如下:



代码中的关键点包括:


• repartition(1000):将上一阶段关联后的结果分成1000份,以减少单个任务处理的数据量。


• ceil(rand()*N):将一个key分成最多N行,限制最终按key关联后生成的行数。


• spark.sql.files.maxPartitionBytes:控制单个任务处理的数据量,进一步拆分任务。


通过上述优化,任务在20分钟内完成,生成了近800亿行的数据,其中包括19个超十亿行的key。


3.2 避免排序


排序操作在大数据处理中开销巨大,尤其是在数据量较大的情况下。以下是两个通过改写代码避免排序的案例:


1)用max函数替换排序:


业务需求是从1200亿行数据中抽取约1万条样本数据。原SQL通过排序获取每组数据中size最大的记录,但由于某些key的数据量极大,导致任务失败。优化后的思路是通过max函数获取每个key的最大值,再与原表关联,提取最大值对应的记录。具体代码如下:



代码中的关键点包括:


• semi join:左表匹配右表,一旦匹配成功即停止查找,提高效率。


• row_number:对结果进行开窗,取第一条记录。


2)用分位函数替换排序:


业务需求是对数据进行分档打标。原SQL通过全局排序获取每个记录的位置,但由于数据量过大,任务失败。优化后的思路是使用分位数函数,计算数据必须大于或等于某个值才能处于某个位置,从而避免全局排序。具体代码如下:



通过上述优化,任务执行时间减少了约87%。


3.3 写倾斜的避免


在动态分区场景下,很难预测每个分区将要输出的数据量。如果分配的task数量固定,可能导致某些分区的任务量过大,影响任务执行效率。解决方法是通过distribute by + case when表达式,让引擎根据不同的分区分配不同数量的任务。具体代码示例如下:



3.4 非法值过滤


在处理大数据任务时,有时会遇到非法值导致的倾斜问题。例如,在一个任务中,发现某个字段的空值数量巨大,导致任务运行时间不断增加,最终失败。通过与业务人员沟通,确认空值无意义,将其过滤掉后,任务在30分钟内完成,耗时下降约90%。如果倾斜值有意义,通常需要将其单独处理,再与其他非倾斜数据合并。


4. 结语


数据倾斜是大数据处理中的常见问题,本文通过多个实际案例,详细介绍了如何识别和解决不同类型的数据倾斜问题。未来,我们将开发更多的诊断和优化工具,帮助用户更有效地应对数据倾斜。


作者简介


Luckyfish,OPPO大数据服务质量负责人,主要负责大数据平台支持维护及服务质量保证工作,曾供职于京东科技,有丰富的任务开发和性能优化经验,同时对产品体验和成本优化有较多兴趣和经验。


推荐阅读
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • 本文详细探讨了 Java 中 Daemon 线程的特点及其应用场景,并深入分析了 Random 类的源代码,帮助开发者更好地理解和使用这些核心组件。 ... [详细]
  • 流处理中的计数挑战与解决方案
    本文探讨了在流处理中进行计数的各种技术和挑战,并基于作者在2016年圣何塞举行的Hadoop World大会上的演讲进行了深入分析。文章不仅介绍了传统批处理和Lambda架构的局限性,还详细探讨了流处理架构的优势及其在现代大数据应用中的重要作用。 ... [详细]
  • 本文档详细介绍了服务器与应用系统迁移的策略与实施步骤。迁移不仅涉及数据的转移,还包括环境配置、应用兼容性测试等多个方面,旨在确保迁移过程的顺利进行及迁移后的系统稳定运行。 ... [详细]
  • 设计模式笔记12:迭代器模式(Iterator Pattern) ... [详细]
  • MySQL 5.7 绿色版安装及 my.ini 配置详解
    本文主要针对最近因系统重装导致的MySQL配置问题,详细介绍了MySQL 5.7.24绿色解压版的安装步骤及my.ini配置文件的关键设置,帮助用户顺利完成数据库的安装与配置。 ... [详细]
  • 使用H5在前端生成Excel文件的方法
    本文介绍了一种利用HTML5和JavaScript库在浏览器端直接生成并下载Excel文件的技术方案。通过引入alasql.js和xlsx.core.min.js两个库,可以轻松实现数据导出功能。 ... [详细]
  • 本文详细介绍了 Spark 中的弹性分布式数据集(RDD)及其常见的操作方法,包括 union、intersection、cartesian、subtract、join、cogroup 等转换操作,以及 count、collect、reduce、take、foreach、first、saveAsTextFile 等行动操作。 ... [详细]
  • 本文深入探讨了企业级开发框架NHibernate和Spring.NET的关键特性之一——面向方面编程(AOP)。文章不仅介绍了AOP的基本概念及其如何增强面向对象编程(OOP),还详细说明了Spring.NET中AOP的具体应用,包括事务管理和自定义方面的实现。 ... [详细]
  • Navicat 使用指南与连接设置
    本文详细介绍了如何首次使用 Navicat 进行数据库连接设置,包括注册过程、输入正确的端口号及认证信息,确保用户能够顺利连接到 MySQL 数据库。 ... [详细]
  • 解决PHP与MySQL之间的编码不匹配问题
    探讨如何有效解决PHP与MySQL之间常见的编码问题,确保数据的正确传输与显示。 ... [详细]
  • 本文记录了在使用JMeter进行性能测试时,通过CSV Data Set Config读取外部数据过程中遇到的一个常见问题及其解决方案。该问题主要涉及文件配置的细节。 ... [详细]
  • 统一幻灯片标题:使用母版功能的技巧
    本文详细介绍了如何通过PowerPoint中的幻灯片母版功能,实现所有幻灯片标题的一致性设置。同时,提供了其他办公软件和编程相关的实用技巧。 ... [详细]
  • MyBatis入门指南
    本文详细介绍了MyBatis的基础知识,包括如何整合日志框架(如log4j和logback),使用外部JDBC文件,getMapper()方法的应用,以及别名设置等技巧。 ... [详细]
  • 本文探讨了SQL查询执行缓慢的多种可能因素,并提供了详细的解释和解决方案。 ... [详细]
author-avatar
gaoxing332844731
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有