前言
Apache Hive 经过多年的开展,目前基本曾经成为业界构建超大规模数据仓库的理想规范和数据处置工具,Hive曾经不单单是一个技术组件,而是一种设计理念。Hive 有 JDBC 客户端、允许规范 JDBC 接口访问的 HiveServer2 主机、控制元数据服务的Hive Metastore,以及义务以 MapReduce 散布式义务运转在 YARN 上。
规范的 JDBC 接口、规范的 SQL 主机、散布式义务口头以及元数据中心,这一系列组合让 Hive 完整地具有了构建一个企业级数据仓库的一切特性,并且Hive 的 SQL 主机是目前经常使用最宽泛的规范主机。
虽然 Hive 有十分显著的好处,可以找出齐全代替 Hive 的组件寥寥无几,但是并不等于 Hive在目前阶段是一个齐全满足企业业务要求的组件,很多时刻选用 Hive 登程点并不是由于 Hive很好地允许了企业需求,单单是由于暂时找不到一个能撑持企业诉求的代替服务。
企业级数仓构建需求
数仓架构通常是一个企业数据剖析的终点,在数仓之下会再有一层数据湖,用来做异构数据的存储以及数据的冷备份。但是也有很多企业,特意是简直齐全以结构化数据为主的企业在实施上会把数据湖和企业数仓库兼并,基于某个数仓平台合二为一。
企业在思索构建自身数仓体系的时刻,虽然须要参考现有的行业技术体系,以及可以选用的组件服务,但是不能太过于局限于组件自身,寻觅100%开箱即用的产品。太过局限于寻觅齐全符合的组件服务肯定受限于服务自身的成功,给未来裁减留下渺小的解放。企业数据仓库架构肯定不等于一个组件,大局部企业在数仓架构实施的都是基于现有的局部方案,启动基于自己业务适宜的方向启动局部开发与定制,从而到达一个半自研的稳态,既能跟上业务变动的速度,又不过于依赖和受限于组件自身的开展。
普通来说企业级数仓架构设计与选型的时刻须要从以下几个维度思索:
关于企业数仓架构来说,最关键的是如何基于企业业务流程来设计架构,而不是基于某个组件来裁减架构。
一个企业数仓的全体逻辑如上图所示,数仓在构建的时刻通常须要 ETL 处置和分层设计,基于业务系统采集的结构化和非结构化数据启动各种 ETL 处置成为DWD 层,再基于 DWD 层设计下层的数据模型层,构成 DM,两边会有 DWB/DWS 作为局部两边环节数据。
从技术选型来说,从数据源的 ETL 到数据模型的构建通常须要长时义务,也就是整个义务的运转期间通常是小时及以下级别。而 DM层关键是允许业务的需求,对时效性要求比拟高,通常运转在 DM 层上的义务期间以分钟作为单位。
基于如上的分层设计的架构图可以发现,虽然目前有十分多的组件,像 Presto、Doris、ClickHouse、Hive等等,但是这些组件各自上班在不同的场景下,像数仓构建和交互式剖析就是两个典型的场景。
交互式剖析强调的是时效性,一个查问可以极速出结果,像 Presto、Doris、ClickHouse 虽然也可以处置海量数据,甚至到达 PB及以上,但关键还是用在交互式剖析上,也就是基于数据仓库的 DM层,给用户提供基于业务的交互式剖析查问,繁难用户极速启动探求。由于这类引擎更聚焦在交互式剖析上,因此关于长时义务的允许度并不友好,为了到达极速失掉计算结果,这类引擎重度依赖内存资源,须要给这类服务性能很高的配件资源,这类组件通常有着如下解放:
一旦出现义务意外,例如网络颤抖惹起的义务失败、机器宕机惹起的节点失落,再次重试所消耗的期间简直等于从新提交一个义务。在散布式义务的背景下,义务运转的期间越长,出现失误的概率越高。关于此类组件的经常使用,业界最佳通常的倡导也是不超越30 分钟左右查问经常使用这类引擎是比拟适宜的。
而在离线数仓场景下,简直一切义务都是长时义务,也就是义务运转时长在小时级以上,这时就要求口头 ETL和构建数仓模型的组件服务须要具有较高的容错性和稳固性,当义务出现失误时可以以低老本的方式极速复原,尽或许防止由于局部节点形态意外造成整个义务齐全失败。
可以发如今这样的诉求下相似于 Presto、Doris、ClickHouse 就很难满足这样的要求,而像 Hive、Spark 这类计算引擎附丽于Yarn 做资源控制,关于散布式义务的重试、调度、切换有着十分牢靠的保证。Hive、Spark等组件自身基于可重算的数据落盘机制,确保某个节点出现缺点或许局部义务失败后可以极速启动复原。数据保留于 HDFS等散布式存储系统上,自身不控制数据,具有极高的稳固性和容错处置机制。
反过去,由于 Hive、Spark更擅短处置这类批处置的长时义务,因此这类组件不擅长与下层的交互式剖析,关于这种对时效性要求更高的场景,都不能很好地满足。所以在思索构建数仓的时刻,通常会选用Hive、Spark 等组件来担任,而在下层提供交互式剖析查问的时刻,通常会经常使用 Presto、Doris、ClickHouse 等组件。
演绎如下:
一个企业在实施数据平台的时刻,由多个不同组件各自上班在不同的架构层中,无法相互取代,相互单干配合,承载整个企业的数据平台业务。
企业级数仓技术选用
Google 宣布的三篇论文从存储、计算、检索三个方向论述了海量数据下一种新的散布式数据加工处置技术,这三个方向被雅虎 Nutch团队成功后奉献给 Apache,也就是目前大家看到的 HDFS、MapReduce 和 HBase,构成了早期 Hadoop 的三大利器。
但是这三大利器更聚焦在异构数据的消息提取处置上,没有提供对结构化数据很友好的相似 SQL 语法的剖析入口,同时在编程态的撑持也不够友好,只要 Map 和Reduce 两阶段,重大限度了业务处置的成功,雅虎团队也是爬虫相关业务孵化而出,可以看出 Hadoop 早期的三大套件有着如下特点:
Hive 就是降生在这样的较大的行业背景下,Hive 的出现刚好补偿了 Hadoop只能用来做离线数据处置这个缺点,提供了一种罕用的剖析接口,并且提供了十分好的用户交互方式。
Hive 全体架构如上图所示,Hive 提供 JDBC 接口成功允许以编程方式启动交互,同时业内简直一切 SQL Client、开源或商业 BI工具都允许经过规范 JDBC 的方式衔接 Hive,可以允许数据探求的举措,极大地丰盛了大数据生态圈下的组件多样性,同时也降落了经常使用门槛,可以让相熟 SQL的人员低老本迁徙。
基于这些设计十分好的特效,加上 Hive 经过多年的逐渐完善,开展到当天曾经是一个十分稳固成熟的消费环境可用的数据仓库组件,甚至代替品都很难找到,因此经常使用Hive 作为数据仓库的构建基础是一个十分好的选用。
如上图所示,其中有很多好处:
所以,虽然 Hive 出现曾经有很长期间了,但照旧是数仓构建的首选,在整个数仓构建中随处可见 Hive 的身影。虽然 Hive有种种好处,让人难以割舍,但是并不等于能很好地撑持企业业务需求。很多时刻选用 Hive仅仅是由于暂时没有其余可选的组件,假设自己从头开发一个,或许基于某个组件变革,老本又会远超企业预期,因此不得不继续选用经常使用 Hive。
基于通常来看,Hive 在构建企业数仓环节中存在的关键局限围绕在以下几个方面:
虽然 Hive 在以上局限层面也做了很多尝试(Hive On Spark),但是受限于 Hive 的架构,HiveServer2 自身有自己的 SQL解析引擎,为了兼容架构将解析后的结果间接翻译成 Spark 最底层的接口,全体性能反而优化不大。
除了 Hive 之外,还有十分多其余的低劣组件。但是,从企业数仓技术选型的视角来看,适宜用来构建数据仓库的,目前只要 Hive 和 Spark SQL相对愈加适宜,在这两个组件中,Spark SQL 相对 Hive 的好处又愈加显著。
SparkSQL 如何撑持企业级数仓
Spark 引擎由于自身弱小的生态和繁难的编程接口被宽泛运行在数据处置场景下,Spark 提供的 Spark SQL模块更是为经常使用 Spark 撑持企业数据仓库提供了一个良好的基础设备。
如上图所示,一个典型的数据仓库架构须要蕴含不同档次的模型构建。由于数据量大、数据结构异构等多种要素,大数据架构下的企业数仓构建放弃了基于相关型数据库下的Cube 设计,间接驳回基于散布式义务启动处置来构建多层数据模型。因此关于构建企业数仓的服务来说,有着如下要求:
基于以上特性可以发现,在目前可选用的组件范围内,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 SQL 来撑持企业级的数仓是齐全可行的,并且在目前也被泛滥企业通常验证。
如上图所示,一个基于 Spark SQL 构建的企业数仓架构逻辑架构设计上蕴含以上几个局部,每一个 Spark SQL 引擎都是一个主机,SparkSQL 引擎将自己的消息注册到 Zookeeper 中,SQL 主机基于 Zookeeper 中的 Spark SQL 引擎来口头客户端过去的恳求,SQL主机是一个兼容 Hive JDBC 接口的主机,在经常使用 Spark SQL 来撑持数仓构建的时须要重点思索的实施点是:
经常使用 Spark SQL 撑持企业级数仓的**之处还是在于如何提供一个好用的义务主机,用来撑持义务的控制。义务控制主机在逻辑上与HiveServer2 相似,但是愈加的轻量,没有 HiveServe2 中复杂而惨重的 SQL 解析,同时又没有 Spark Thrift Server这种自身就是一个 YARN 作业的解放。企业可以基于自身的业务流程,开发一个轻量的主机,在这方面字节有十分深的通常阅历,同时也有自己的 Spark SQL引擎主机,可关注后续的灵活。同时业界也有其余企业做了相似的上班,例如网易开源的 Kyuubi。
Kyuubi 整个架构图如上所示,Kyuubi 基于 Spark SQL 之上,较好地补偿了 Spark Thrift Server在多租户、资源隔离和高可用等方面的无余,是一个真正可以满足大少数消费环境场景的开源名目。但是 Kyuubi 在设计时思索的是如何补偿 Spark ThriftServer 的无余,目标在于增强 Spark SQL 的才干,而不是平等设计一个可以交流 Hive 组件的服务。因此关于遗留名目来说迁徙老本较高,SparkSQL 与 Hive 有着两套不兼容的 SQL,在经常使用 Kyuubi 的时刻如何降落遗留系统的迁徙老本将是一个十分大的上班量。
而行业也有开源的 Spark Thrift Server,该思绪是十分低劣的,但是由于开发环节中有点太过于局限,造成照旧存在很多疑问,关键体如今:
因此虽然 Spark 提供了 Spark thrift server 服务用来提供相似 JDBC这样的接口交互方式,但是目前照旧缺乏很多生成性能,造成在消费环境经常使用的状况十分少,Spark thrift server更像是一个小众的半成品,小修小补地尝试着处置局部疑问,但是没有给予一个彻底的方案,造成如今有点缺乏实践的消费运行。
字节跳动 EMR 产品在 Spark SQL 的优化通常
数据湖引擎集成
Hudi、Iceberg 等数据湖引擎目前经常使用的越来越宽泛,很多 B 端客户在经常使用 Spark SQL 的时刻也存在须要经常使用数据湖引擎的需求,因此字节EMR 产品须要将数据湖引擎集成到 Spark SQL 中,在这个环节中遇到了十分多的疑问。
首先在与 Iceberg 集成的时刻,对体验和易用的疑问启动了优化,用户在经常使用 Spark SQL 环节中,须要手动输入很多指令,并且须要找到对应的spark-iceberg 依赖包,这个也是目前集成 Iceberg 最罕用的方案。咱们的处置方式是在预先装置的环节中,提早把 iceberg 的相关 jar包放到 spark jars 目录下,这样用户只要要指定 catalog 即可,无需再手动输入很多指令。
其次在 Spark 与 Hive 跨引擎剖析场景下经常使用 Iceberg,Spark 反常创立表,Presto/Trono 可以反常读写,但 Hive无法反常读写,这个疑问官网的文档也没有明晰的形容,处置方案是须要修正 Spark 的性能文件或许修正 Hive 的 hive-site-sparkoverride 性能,确保初始化进去的 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 这样的工具,但是在某些 B端客户的业务背景下,这些工具并不能齐全满足要求,因此字节跳动 EMR 团队自己设计成功了 Spark SQL Server,关键聚焦处置的是如下场景:
如上图所示,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 访问链接:
非 HA 访问链接:
HA 形式下的消息被记载在 Zookeeper 中,保留的内容格局与 HiveServer2 的内容分歧,能确保经常使用 Hive 的客户端可以间接访问 HA形式下的主机。
Spark SQL 多租户
在 Hive 义务口头环节中,HiveServer2 服务承当了提供 SQL 主机启动用户身份认证、权限判别,以及解析 SQL 生成最终的口头方案,再由MR 引擎口头详细的散布式义务。
在这个环节中 HiveServer2承当了十分重的职责,因此须要消耗十分大的资源,因此会很大水平的影响用户的并发。关于散布式义务运转来说,它的资源解放来自于 Yarn作为资源控制器所调配的资源,但是在 Hive 架构下却受限于 HiveServer2 的影响,造成用户并发的数量无法随着 Yarn 资源的优化而优化。
而在 Spark SQL 引擎中,SQL 解析是下推到引擎外部,与详细的散布式义务口头合为一体,不须要独自的主机去做 SQL 解析。也正由于 SparkSQL 与 Hive 在解析模块的架构存在差异,Hive On Spark 的形式会变得十分难。
针对如上的场景,字节跳动 EMR 团队从新设计的 SQL 主机只担任义务的接纳,启动用户资源、权限和身份的判别,而后将义务发送给运转在 Yarn 中的Spark SQL 主机。冲破了 Hive 这种并发受制于 HiveServer2 和 Yarn 两层解放的局面,只由 Yarn的资源选择用户的并发水平,从而极大的降落了 Spark SQL 主机的资源需求,增强了其稳固性,在用户并发上有了十分大的优化。
其次经过引擎预热的性能缩小义务口头的期间,优化全体速度,引擎预热指的是在服务启动的时刻便向 Yarn 提交 Spark SQL引擎,处于期待的形态,当业务恳求抵达的时刻,基于业务类型从曾经处于就绪的引擎当选用一个引擎来口头义务。
并不是每一个预热提交的引擎都会被选用口头,在 SQL 主机中存在如下三种引擎隔离级别:
由此可见只要在 User、Open 的级别下引擎预热才会发生价值,预热省去了 Spark Submit的期间,当用户数量足够多,集体为统计单位所节俭的期间越多。
Spark SQL 事务允许
Hive 的事务力度是基于 HiveServer2 成功的,例如经过如下语法:
可开启事务,但是由于对事务的控制是在主机上,因此须要开启 ACID 的时刻受影响的是整个 HiveServer2 的一切恳求,而 Spark SQL很好地集成和允许了 Hudi,Iceberg 等数据湖格局,因此在 Spark SQL 主机中不须要成功相似 HiveServer2的事务机制,只要要在最终读取处置数据的时刻,驳回 Hudi、Iceberg 等特性便可到达允许事务的成果。
例如关于 Icdberg 数据格局的表已允许 update、delete 操作:
因此当 Spark SQL 集成了 Iceberg 后,便具有了事务才干,再配合 SQL 主机,便可在很低的老本上具有和 Hive事务才干等同的效益,同时也没有 Hive 下的一些解放,从这样的架构设计过去看,能够完整地交流Hive。另外一个方面当用户数质变多,同时数据会出现修正、更新等操作,很容易造少量的小广播传输,从而惹起 Driver 的 OOM。虽然大广播也会存在 OOM的疑问,但是大广播可以经过阈值控制,而小广播阈值对其不失效,一旦说数质变多,很容易惹起 Driver 的 OOM。字节 EMR团队经过对小广播启动兼并广播,处置少量小广播启动流传,造成打爆 Driver 的状况出现。
序幕
随着企业的业务开展越来越复杂,须要愈加灵敏、愈加高效的数仓架构,在这样的业务驱动背景下,Hive 的局限变得越来越显著,而基于 Spark SQL灵敏构建数仓的方案将会变得越来越干流。所以企业在思索数据仓库构建体系的时刻,可以思索如何基于 Spark SQL 构建自身数据体系,Spark完善和放开的生态在未来肯定会有更多低劣的服务围绕 Spark 构成弱小的好处。