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


推荐阅读
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • 精选30本C# ASP.NET SQL中文PDF电子书合集
    欢迎订阅我们的技术博客,获取更多关于C#、ASP.NET和SQL的最新资讯和资源。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 本文由瀚高PG实验室撰写,详细介绍了如何在PostgreSQL中创建、管理和删除模式。文章涵盖了创建模式的基本命令、public模式的特性、权限设置以及通过角色对象简化操作的方法。 ... [详细]
  • 本文详细介绍了 MySQL 中 LAST_INSERT_ID() 函数的使用方法及其工作原理,包括如何获取最后一个插入记录的自增 ID、多行插入时的行为以及在不同客户端环境下的表现。 ... [详细]
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
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社区 版权所有