乐趣区

关于数据库:看SparkSQL如何支撑企业级数仓

企业级数仓架构设计与选型的时候须要从开发的便利性、生态、解耦水平、性能、平安这几个纬度思考。本文作者:惊帆 来自于数据平台 EMR 团队

前言

Apache Hive 通过多年的倒退,目前根本曾经成了业界构建超大规模数据仓库的事实标准和数据处理工具,Hive 曾经不单单是一个技术组件,而是一种设计理念。Hive 有 JDBC 客户端,反对规范 JDBC 接口拜访的 HiveServer2 服务器,治理元数据服务的 Hive Metastore,以及工作以 MapReduce 分布式工作运行在 YARN 上。

规范的 JDBC 接口,规范的 SQL 服务器,分布式工作执行,以及元数据中心,这一系列组合让 Hive 残缺的具备了构建一个企业级数据仓库的所有个性,并且 Hive 的 SQL 服务器是目前应用最宽泛的规范服务器。

尽管 Hive 有非常明显的长处,能够找出齐全代替 Hive 的组件寥寥无几,然而并不等于 Hive 在目前阶段是一个齐全满足企业业务要求的组件,很多时候抉择 Hive 出发点并不是因为 Hive 很好的反对了企业需要,单单是因为临时找不到一个能撑持企业诉求的代替服务。

企业级数仓构建需要

数仓架构通常是一个企业数据分析的终点,在数仓之下会再有一层数据湖,用来做异构数据的存储以及数据的冷备份。然而也有很多企业,特地是简直齐全以结构化数据为主的企业在施行上会把数据湖和企业数仓库合并,基于某个数仓平台合二为一。

企业在思考构建本身数仓体系的时候,尽管须要参考现有的行业技术体系,以及能够抉择的组件服务,然而不能太过于局限于组件自身,寻找 100% 开箱即用的产品。太过于局限于寻找齐全符合的组件服务必然受限于服务自身的实现,给将来扩大留下微小的束缚。企业数据仓库架构必然不等于一个组件,大部分企业在数仓架构施行的都是都是基于现有的局部计划,进行基于本人业务适合的方向进行局部开发与定制,从而达到一个半自研的稳态,既能跟上业务变动的速度,又不过于依赖和受限于组件本身的倒退。

一般来说企业级数仓架构设计与选型的时候须要从以下几个纬度思考:

  • 开发的便利性:所抉择的数仓架构是否具备很好的开发生态,能够提供不同类型的开发态接口,不限于 SQL 编辑器,代码提交,以及第三方工具整合。
  • 生态:所抉择实现引擎本身是否有很好的生态性能,或者是否能够很好的与其余服务集成,例如数据湖引擎 delta lake,icebeg,hudi 等优良组件呈现,然而 Hive 集成的节奏却十分慢。
  • 解耦水平:分布式工作必然须要多个组件的协调,例如分布式存储,资源管理,调度等,像 Hive 就重度依赖于 YARN 体系,计算引擎也与 MR 强绑定,在解耦方面较弱,如果企业思考在 K8S 上构建本人的计算引擎,Hive 面临的局限会更加显著。
  • 性能:整体架构是否领有更好的性能。
  • 平安:是否反对不同级别,不同力度的用户拜访和数据安全鉴权体系。

对于企业数仓架构来说,最重要的是如何基于企业业务流程来设计架构,而不是基于某个组件来扩大架构。

一个企业数仓的整体逻辑如上图所示,数仓在构建的时候通常须要 ETL 解决和分层设计,基于业务零碎采集的结构化和非结构化数据进行各种 ETL 解决成为 DWD 层,再基于 DWD 层设计下层的数据模型层,造成 DM,两头会有 DWB/DWS 作为局部两头过程数据。

从技术选型来说,从数据源的 ETL 到数据模型的构建通常须要长时工作,也就是整个工作的运行工夫通常是小时及以上级别。而 DM 层次要是反对业务的需要,对实效性要求比拟高,通常运行在 DM 层上的工作工夫在分钟作为单位。

基于如上的分层设计的架构图能够发现,尽管目前有十分多的组件,像 Presto,Doris,ClickHouse,Hive 等等,然而这些组件各自工作在不同的场景下,像数仓构建和交互式剖析就是两个典型的场景。

交互式剖析强调的是时效性,一个查问能够疾速出后果,像 Presto,Doris,ClickHouse 尽管也能够解决海量数据,甚至达到 PB 及以上,然而次要还是是用在交互式剖析上,也就是基于数据仓库的 DM 层,给用户提供基于业务的交互式剖析查问,不便用户疾速进行摸索。因为这类引擎更聚焦在交互式剖析上,因而对于长时工作的反对度并不敌对,为了达到疾速获取计算结果,这类引擎重度依赖内存资源,须要给这类服务配置很高的硬件资源,这类组件通常有着如下束缚:

  • 没有工作级的重试,失败了只能重跑 Query,代价较高。
  • 个别全内存计算,无 shuffle 或 shuffle 不落盘,无奈执行海量数据。
  • 架构为了查问速度快,执行前曾经调度好了 task 执行的节点,节点故障无奈从新调度。

一旦产生工作异样,例如网络抖动引起的工作失败,机器宕机引起的节点失落,再次重试所耗费的工夫简直等于全新从新提交一个工作,在分布式工作的背景下,工作运行的工夫越长,呈现谬误的概率越高,对于此类组件的应用业界最佳实际的倡议也是不超过 30 分钟左右的查问应用这类引擎是比拟适合的。

而在离线数仓场景下,简直所有工作都是长时工作,也就是工作运行时常在小时及以上,这时就要求执行 ETL 和构建数仓模型的组件服务须要具备较高的容错性和稳定性,当工作产生谬误的时候能够以低成本的形式疾速复原,尽可能防止因为局部节点状态异样导致整个工作齐全失败。

能够发现在这样的诉求下相似于 Presto,Doris,ClickHouse 就很难满足这样的要求,而像 Hive,Spark 这类计算引擎依靠于 Yarn 做资源管理,对于分布式工作的重试,调度,切换有着十分牢靠的保障。Hive,Spark 等组件本身基于可重算的数据落盘机制,确保某个节点呈现故障或者局部工作失败后能够疾速进行复原。数据保留于 HDFS 等分布式存储系统上,本身不治理数据,具备极高的稳定性和容错解决机制。

反过来,因为 Hive,Spark 更长于解决这类批处理的长时工作,因而这类组件不善于与下层的交互式剖析,对于这种对于时效性要求更高的场景,都不能很好的满足。所以在思考构建数仓的时候,通常会抉择 Hive,Spark 等组件来负责,而在下层提供交互式剖析查问的时候,通常会应用 Presto,Doris,ClickHouse 等组件。

演绎下来如下:

  • Presto,Doris,ClickHouse:更重视交互式剖析,对单机资源配置要求很高,重度依赖内存,不足容错复原,工作重试等机制,适宜于 30 分钟以内的工作,通常工作在企业的 DM 层间接面向业务,解决业务需要。
  • Hive,Spark:更重视工作的稳定性,对网络,IO 要求比拟高,有着欠缺的两头临时文件落盘,节点工作失败的重试复原,更加适合小时及以上的长时工作运行,工作在企业的的 ETL 和数据模型构建层,负责荡涤和加工下层业务所须要的数据,用来撑持整个企业的数仓构建。

一个企业在施行数据平台的时候,由多个不同组件各自工作在不同的架构层中,无奈互相取代,相互协作配合,承载整个企业的数据平台业务。

企业级数仓技术抉择

Google 发表的三篇论文从存储,计算,检索三个方向论述了海量数据下一种新的分布式数据加工解决技术,这三个方向被雅虎 Nutch 团队实现后奉献给 Apache,也就是目前大家看到的 HDFS,MapReduce 和 HBase,造成了晚期 Hadoop 的三大利器。

然而这三大利器更聚焦在异构数据的信息提取解决上,没有提供对结构化数据很敌对的相似 SQL 语法的剖析入口,同时在编程态的撑持也不够敌对,只有 Map 和 Reduce 两阶段,重大限度了业务解决的实现,雅虎团队也是爬虫相干业务孵化而出,能够看出 Hadoop 晚期的三大套件有着如下特点:

  • 门槛高,须要编程实现,并且编程态受限于 MapReduce 的两阶段束缚。
  • 以离散数据处理为主,对剖析能力,查问等罕用数据分析性能反对有余。
  • 没有交互式客户端,无奈实现交互式摸索。

Hive 就是诞生在这样的较大的行业背景下,Hive 的呈现刚好补救了 Hadoop 只能用来做离线数据处理这个缺点,提供了一种罕用的剖析接口,并且提供了十分好的用户交互方式。

Hive 整体架构如上图所示(本图来自于 Hive 官网),Hive 提供 JDBC 接口实现反对以编程模式进行交互,同时业内简直所有 SQL Client、开源或商业 BI 工具都反对通过规范 JDBC 的形式连贯 Hive,能够反对数据摸索的动作,极大的丰盛了大数据生态圈下的组件多样性,同时也升高了应用门槛,能够让相熟 SQL 的人员低成本迁徙。

基于这些设计十分好的特效,加上 Hive 通过这多年的逐步完善,倒退到明天曾经是一个十分稳固成熟的生产环境可用的数据仓库组件,甚至替代品都很难找到,因而应用 Hive 作为数据仓库的构建根底是一个十分好的抉择。

如上图所示,其中有很多长处:

  • 稳固:稳定性是 Hive 一个十分让人称道的个性,很多时候尽管 Hive 的性能,计算速度不迭其余引擎,然而 Hive 的稳定性却始终是十分好的。
  • 低门槛:只须要把握根本的 SQL 技能,便可应用 Hive 进行开发,相比其余分布式计算引擎引擎老本更低。
  • 生态丰盛:Hive 和 Hadoop 生态圈紧密结合,而 Hive 本身的 Metastore 也成了大数据生态圈内的规范元数据服务,大部分引擎都反对间接适配 MetaStore。
  • 扩大不便:Hive 本身的 UDF 机制能够疾速基于业务须要扩大性能。
  • 平安:Hive 反对 Kerberos/LDAP 多种认证形式,并且和 Ranger 联合能够做到更细粒度的行列权限级别,领有较好的数据安全。
  • 集成成本低:MapReduce 只反对编程态的接口,并且不反对迭代计算,Hive 封装了 MapReduce 提供 SQL 的接口,能够很低成本的和下层数据挖掘,数据分析工具进行集成。

所以尽管 Hive 呈现曾经十分有很长时间了,然而仍旧是数仓构建的首选,在整个数仓构建中随处可见 Hive 的身影。尽管 Hive 有种种长处,让人难以割舍,然而并不等于能很好的撑持企业业务需要。很多时候抉择 Hive 仅仅是因为临时没有其余可选的组件,如果本人从头开发一个,或者基于某个组件革新,老本又会远超企业预期,因而不得不持续抉择应用 Hive。

基于实际来看,Hive 在构建企业数仓过程中存在的次要局限围绕在以下几个方面:

  • 性能:Hive 基于 MapReduce 尽管带来了十分好的稳定性,同时也升高了它的性能,尽管有 TEZ 做肯定的优化,然而与同类的计算引擎 Spark 相比仍旧有十分大的差距。
  • 资源配置:因为 Hive 底层应用 MapReduce 作为计算引擎,而 MapReduce 对 SQL 不敌对,因而 Hive 在 HiveServer2 层面实现了 SQL 的转换解决,再生成基于 MapReduce 的物理打算,从而导致 HiveServer2 须要十分高的配置,能力维持足够好的稳定性。
  • 并发:Hive 的并发受限于 HiveServer2,企业须要保护多个高配的 HiveServer2 实例能力反对更好的并非,通常 Hive 的瓶颈都在 HiveServer2 而不是更底层的分布式计算。
  • 容错老本:Hive 基于 HiveServer2 进行 SQL 的剖析解决,多个 HiveServer2 之间互相独立不共享信息,因而当 HiveServer2 挂掉后,整个 HiveServer2 的工作都会完结,须要客户端自行重试,为整个作业级别的容错重启。
  • 事务反对:Hive 的事务设置在 HiveServer2 上,一旦 HiveServer2 实例开启事务后,整个通过该 HiveServer2 的申请都会开启事务,整个事务老本过高。
  • 部署:如果企业的计算引擎部署是基于 K8S 等容器架构,Hive on K8S 将会带来十分大的部署老本。

尽管 Hive 在以上局限层面也做了很多尝试,Hive On Spark,然而受限于 Hive 的架构,HiveServer2 本身有本人的 SQL 解析引擎,为了兼容架构将解析后的后果间接翻译成 Spark 最底层的接口,整体性能反而晋升不大。

除了 Hive 之外,还有十分多的其余优良的组件,然而从企业数仓技术选型的视角来看,适宜用来构建数据仓库的,目前只有 Hive 和 Spark SQL 绝对更加适合,在这两个组件中,Spark SQL 绝对 Hive 的劣势又更加显著。

SparkSQL 如何撑持企业级数仓

Spark 引擎因为本身弱小的生态和不便的编程接口被广泛应用在数据处理场景下,Spark 提供的 Spark SQL 模块更是将应用 Spark 撑持企业数据仓库提供了一个良好的基础设施。

如上图所示,一个典型的数据仓库架构须要蕴含不同档次的模型构建。因为数据量大,数据结构异构等多种起因,大数据架构下的企业数仓构建摈弃了基于关系型数据库下的 Cube 设计,间接采纳基于分布式工作进行解决来构建多层数据模型。因而对于构建企业数仓的服务来说,有着如下要求:

  • 反对长时工作,通常是小时以上,天级别居多。
  • 反对多任务,也就是高并发。
  • 稳定性必须被保障。
  • 速度快。
  • 反对 SQL 的交互式接口。
  • 易于集成。
  • 反对工作的重跑和容错以及疾速工作失败复原。

基于以上个性能够发现,在目前可抉择的组件范畴内,Spark SQL 相比其余组件,乃至 Hive 更加适合承当这类工作。然而很多企业在进行架构设计的时候割舍不掉 Spark SQL 带来的丰盛个性,又愁于 Spark SQL 不足相似 Hive 这样的 SQL 服务器,于是退而求其次变成 Hive 与 Spark SQL 两个组件共存的状态,Hive 进化为仅仅提供 MetaStore 服务,因而从很多实际的景象来看,Hive 构建企业数仓已是过来式,采纳 Spark SQL 进行数据仓库的构建是泛滥的抉择。

如上图所示,企业在构建数仓的时候,通过一个 Spark SQL Server 提供基于 SQL 接口的常驻服务,同时也能够采纳 Spark Submit 的形式间接提交 Jar 工作去运行,既能达到提供规范 SQL 交互式接口,又能提供更灵便的编程态接口。

从不同的企业级数仓构建视角来看,Hive 带来的束缚都越来越大,而 Spark SQL 的成熟度和发展趋势曾经齐全具备取代 Hive 来构建整个数仓,Spark SQL 的劣势集中体现在如下方面:

  • 丰盛的生态:Spark 不仅能够和很多组件集成,其本身领有生态曾经涵盖各个方面,从数据分析到机器学习和图计算。
  • 凋谢:Spark 架构设计上十分凋谢,能够疾速整合其余产品,例如相比 Hive,在集成 Iceberg,Hudi 等个性方面就会凋谢很多。
  • 部署:Spark 既能够部署在 ECS 虚拟机上,也可部署在 K8S 架构上,多种部署状态非常灵活。
  • 性能:Spark 的机制的流批处理性能十分适合用来构建企业数仓。
  • 易于开发:Spark SQL 既有 SQL 接口,也反对灵便的可迭代编程接口,十分不便不同场景下的数据开发。
  • 平安:Spark SQL 可和不同的平安服务集成,实现细粒度的鉴权。

因而,齐全基于应用 Spark SQL 来撑持企业级的数仓是齐全可行的,并且在目前也被泛滥企业实际验证。

如上图所示,一个基于 Spark SQL 构建的企业数仓架构逻辑架构设计上蕴含以上几个局部,每一个 Spark SQL 引擎都是一个服务器,Spark SQL 引擎将本人的信息注册到 Zookeeper 中,SQL 服务器基于 Zookeeper 中的 Spark SQL 引擎来执行客户端过去的申请,SQL 服务器是一个兼容 Hive JDBC 接口的服务器,在应用 Spark SQL 来撑持数仓构建的时须要重点思考的施行点是:

  • 如何提供一个交互服务用来撑持不同的客户端来连贯,包含交互式的 beeline,以及编程态的 JDBC 和工具接口。
  • 如何买通权限对接,如果是 Ranger 的话须要的是 Spark SQL Ranger Plugin。
  • 如何反对跨多个队列的工作提交。

应用 Spark SQL 撑持企业级数仓的外围的中央还是在于如何提供一个好用的工作服务器,用来撑持工作的治理。工作治理服务器在逻辑上与 HiveServer2 类似,然而更加的轻量,没有 HiveServe2 中简单而沉重的 SQL 解析,同时又没有 Spark Thrift Server 这种本身就是一个 YARN 作业的束缚。企业能够基于本身的业务流程,开发一个轻量的服务器,在这方面字节有十分深的实践经验,同时也有本人的 Spark SQL 引擎服务器,可关注后续的动静。同时业界也有其余企业做了相似的工作,例如网易开源的 Kyuubi。

Kyuubi 整个架构图如上所示(图片来自于 kyuubi 官网:https://github.com/apache/incubator-kyuubi)。

Kyuubi 基于 Spark SQL 之上,较好的补救了 Spark Thrift Server 在多租户、资源隔离和高可用等方面的有余,是一个真正能够满足大多数生产环境场景的开源我的项目。然而 Kyuubi 在设计的时候思考的是如何补救 Spark Thrift Server 的有余,目标在于加强 Spark SQL 的能力,而不是对等设计一个能够替换 Hive 组件的服务。因而对于遗留我的项目来说迁徙老本较高,Spark SQL 与 Hive 有着两套不兼容的 SQL,在应用 Kyuubi 的时候如何是遗留零碎迁徙老本将是一个十分大的工作量。

而行业也有开源的 Spark Thrift Server,该思路是十分优良的,然而因为开发过程中有点太过于局限,导致仍旧存在很多问题,次要体现在:

  • Driver 单点:整个 Spark thrift server 以一个 Spark 工作的模式运行在 YARN 上,所有的申请都运行在一个 Driver 中,一旦 Driver 挂掉后,所有工作都会同时失败。
  • 资源隔离:因为 Spark thrift server 是以 Spark 工作的模式运行在 YARN 上,因而提交的工作如果有跨队列提交需要的时候,Spark thrift server 很难撑持,其次多个工作运行在同一个 Driver 之中,资源应用会相互影响,很难更精细化的进行资源的治理。
  • 多租户:Spark thrift server 从申请层面是能够反对多用户的,然而从架构层面来看 Spark thrift server 是一个运行在 Yarn 上的工作,它也有本人的 Application Id 有本人的工作提交者,因而它实际上是以一个超级管理员的身份运行,再做二次租户隔离,必然存在肯定的资源平安问题。
  • 高可用:Spark thrift server 自身是没有高可用波及的,因而它的高可用须要自行独自设计,且还得思考客户端的兼容,例如 Hive JDBC 将 HA 信息存储在 ZK 中,而 Spark thrift server 没有这样的机制,因而高可用的施行老本较高。

因而尽管 Spark 提供了 Spark thrift server 服务用来提供相似 JDBC 这样的接口交互方式,然而目前仍旧不足很多生成性能,导致在生产环境应用的状况非常少,Spark thrift server 更像是一个小众的半成品,小修小补的尝试着解决局部问题,然而没有给予一个彻底的计划,导致当初有点不足理论的生产利用。

字节跳动在 Spark SQL 的优化实际

字节跳动的数仓在 2020 年全面从 Hive 迁徙至 Spark SQL,除了组件层面的源码批改外,在应用层面也对 Spark 做了十分多的优化。

数据湖引擎集成

Hudi,Iceberg 等数据湖引擎目前应用的越来越宽泛,字节外部在应用 Spark SQL 的时候也存在须要应用数据湖引擎的需要,因而须要将数据湖引擎集成到 Spark SQL 中,这个过程碰到十分多的问题。

首先在与 Iceberg 集成的时候,对体验和易用的问题进行了优化,用户在应用 Spark SQL 过程中,须要手动输出很多指令,并且须要找到对应的 spark-iceberg 依赖包,这个也是目前集成 Iceberg 最罕用的计划。咱们的解决形式是在事后装置的过程中,提前把 iceberg 的相干 jar 包放到 spark jars 目录下,这样用户只须要指定 catalog 即可,无需再手动输入很多指令。

其次在 Spark 与 Hive 跨引擎剖析场景下应用 Iceberg,Spark 失常创立表,Presto/Trono 能够失常读写,但 Hive 无奈失常读写,这个问题官网的文档也没有清晰的形容,解决方案是须要批改 Spark 的配置文件或者批改 Hive 的 hive-site-spark override 配置,确保初始化进去的 Spark Session 中的配置项 iceberg.engine.hive.enable 的值为 true,Hive 能力失常的读取 Spark 创立的表。

问题上实质上是因为 Iceberg 为了反对 Hive 引擎,在整体的设计上做了一些斗争,应用了 Storage Handler 的形式去实现 Hive 对 Iceberg 格局的表的读写,须要显式的指定 Hive 的 Input/Output Format 实现,而 Presto/Trono 则能够基于 Hive 的 format_type 自动识别表的格局进行辨认。

在兼容性上,因为 Iceberg 0.12 版本不反对 Spark 3.2,因为降级 Spark 的影响范畴十分大,于是更新了 Iceberg,应用了社区的一个 master 的 snapshot 版本进行编译,与 Spark 3.2 进行集成。

Spark SQL 服务器

尽管行业针对 Spark SQL 提供一个 SQL 服务器曾经有 Spark Thrift Server 或者 Kyuubi 这样的工具,然而在字节本身业务的背景下,这些工具并不能齐全满足要求,因而本人也设计实现了本人 Spark SQL Server,次要聚焦解决的是如下场景:

  • 兼容 Hive 语义:因为字节晚期也是基于 Hive 构建的数据仓库,后续逐渐全副替换为 Spark SQL,两头必然面临大量的零碎迁徙,而因为 Hive 与 Spark SQL 语义不尽相同,重写 SQL 实现的工作量十分大,因而在字节的 Spark SQL Server 中实现 Hive 语义和 Spark SQL 语义的兼容,在实现计划上采纳的时候讲 Hive SQL 解析注入到 Spark 引擎中,造成一个 SQL Parser Chain,最终会匹配到某一个解析器,实现对 SQL 的解析,从而达到对整个 SQL 语义的兼容。
  • 提前初始化 Spark SQL 引擎:在业务申请达到前提前在 YARN 上提交 Spark 工作,初始化资源信息,让整个引擎处于期待的状态,能够缩小工作提交耗费的工夫,在用户较多的状况下能够提醒整体的工作执行工夫。
  • 跨 Yarn 队列的工作提交:用户能够指定 Yarn 队列执行工作。


如上图所示,SQL 服务器是一个实现了 Thrift 接口的服务器,提供规范的 JDBC 拜访接口,Spark SQL 引擎同样实现了 Thrift 接口,Spark SQL 引擎在服务启动的时候便曾经被提交至 Yarn,处于期待状态。当业务工作达到的时候,由 SQL 服务器实现引擎的筛选,匹配一个曾经存在的引擎,或者从新提交一个全新的引擎用来执行工作。

SQL 服务器反对 OpenLDAP,Kerberos 等罕用的权限认证,同时反对多种不同的隔离级别,例如 Session 级别则每一个业务 SQL 都会初始化一个 Spark SQL 引擎用来接管工作,工作执行完结后,引擎从 Yarn 中销毁。而 User 级别则针对用户会初始性 0-N 个引擎,常驻于 Yarn 中,处于交替执行工作。

这样的服务器设计突破了 Spark Thrift Server 的单 Driver 所带来的局限,解耦了 SQL 服务和工作执行。也就反对更细粒度的资源管理和跨队列的工作提交。

同时也兼容了 Hive 的接口,用户能够通过如下形式拜访服务器:

HA 拜访链接:

./bin/beeline -u jdbc:hive2://emr-5fqkwudj144d2gc1k8hi-master-1/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=midas/ha;auth=LDAP -n emr_dev -pEMR123456emr

非 HA 拜访链接:

./bin/beeline -u jdbc:hive2://emr-master-2:10005/default;auth=LDAP”-n test_sub -pEMR123456emr

HA 模式下的信息被记录在 Zookeeper 中,保留的内容格局与 HiveServer2 的内容统一,能确保应用 Hive 的客户端能够间接拜访 HA 模式下的服务器。

Spark SQL 多租户


在 Hive 工作执行过程中,HiveServer2 服务承当了提供 SQL 服务器进行用户身份认证,权限判断,以及解析 SQL 生成最终的执行打算,再由 MR 引擎执行具体的分布式工作。

在这个过程中 HiveServer2 承当了十分重的职责,因而须要耗费十分大的资源,因而会很大水平的影响用户的并发。对于分布式工作运行来说,它的资源束缚来自于 Yarn 作为资源管理器所调配的资源,然而在 Hive 架构下却受限于 HiveServer2 的影响,导致用户并发的数量无奈随着 Yarn 资源的晋升进行晋升。

而在 Spark SQL 引擎中,SQL 解析是下推到引擎外部,与具体的分布式工作执行合为一体,不须要独自的服务器去做 SQL 解析。也正因为 Spark SQL 与 Hive 在解析模块的架构存在差别,Hive On Spark 的模式会变得十分难。

针对如上的场景,字节跳动从新设计的 SQL 服务器只负责工作的接管,进行用户资源,权限和身份的判断,而后将工作发送给运行在 Yarn 中的 Spark SQL 服务器。突破了 Hive 这种并发受制于 HiveServer2 和 Yarn 两层束缚的场面,只由 Yarn 的资源决定用户的并发水平,从而极大的升高了 Spark SQL 服务器的资源需要,加强了其稳定性,在用户并发上有了十分大的晋升。

其次通过引擎预热的性能缩小工作执行的工夫,晋升整体速度,引擎预热指的是在服务启动的时候便向 Yarn 提交 Spark SQL 引擎,处于期待的状态,当业务申请达到的时候,基于业务类型从曾经处于就绪的引擎中抉择一个引擎来执行工作。

并不是每一个预热提交的引擎都会被抉择执行,在 SQL 服务器中存在如下三种引擎隔离级别:

  • Session:基于每一个 connection 都会全新提交 Spark SQL 引擎,在链接断开后,引擎从 Yarn 上销毁。
  • User:同一个用户能够共享多个 Spark SQL 引擎,具体的 Spark SQL 引擎个数由该用户提交的工作资源需要决定,引擎在连贯断开后不会销毁,直到引擎闲暇时长达到下限。
  • Open:所有用户都可共享的 Spark SQL 引擎,通常是用来应答大账号,或者集群不须要做权限治理的场景。

由此可见只有在 User,Open 的级别下引擎预热才会产生价值,预热省去了 Spark Submit 的工夫,当用户数量足够多,群体为统计单位所节俭的工夫越多。

Spark SQL 事务反对

Hive 的事务力度是基于 HiveServer2 实现的,例如通过如下语法:

CREATE TABLE tm (a int, b int) stored as orc TBLPROPERTIES ('transactional'='true', 'transactional\_properties'='insert\_only')

可开启事务,然而因为对事务的治理是在服务器上,因而须要开启 ACID 的时候受影响的是整个 HiveServer2 的所有申请,而 Spark SQL 很好的集成和反对了 Hudi,Iceberg 等数据湖格局,因而在 Spark SQL 服务器中不须要实现相似 HiveServer2 的事务机制,只须要在最终读取解决数据的时候,采纳 Hudi,Iceberg 等个性便可达到反对事务的成果。

例如对于 Icdberg 数据格式的表已反对 update、delete 操作:

MERGE INTO prod.nyc.taxis ptUSING (SELECT * FROM staging.nyc.taxis) stON [pt.id](http://pt.id) = st.idWHEN NOT MATCHED THEN INSERT *;

因而当 Spark SQL 集成了 Iceberg 后,便具备了事务能力,再配合 SQL 服务器,便可在很低的老本上具备和 Hive 事务能力等同的效益,同时也没有 Hive 下的一些束缚,从这样的架构设计上来看,可能残缺的替换 Hive。另外一个方面当用户数量变多,同时数据会产生批改,更新等操作,很容易造大量的小广播传输,从而引起 Driver 的 OOM。尽管大播送也会存在 OOM 的问题,然而大播送能够通过阈值管制,而小广播阈值对其不失效,一旦说数量变多,很容易引起 Driver 的 OOM。字节通过对小广播进行合并播送,解决大量小广播进行流传,导致打爆 Driver 的状况呈现。

序幕

随着企业的业务倒退越来越简单,须要更加灵便,更加高效的数仓架构,在这样的业务驱动背景下,Hive 的局限变得越来越显著,而基于 Spark SQL 灵便构建数仓的计划将会变得越来越支流。所以企业在思考数据仓库构建体系的时候,能够思考如何基于 Spark SQL 构建本身数据体系,Spark 欠缺和凋谢的生态在将来必然会有更多优良的服务会围绕 Spark 造成弱小的劣势。

咱们基于企业级数仓建设的局部教训技术也曾经通过火山引擎 E -MapReduce 对外开放。

欢送关注字节跳动数据平台同名公众号

退出移动版