Hive、Spark、Impala原理阅读笔记
作者:互联网
前言-从 Hadoop 说起
什么是 Hadoop
Apache Hadoop 软件库是一个框架,它允许使用简单的编程模型,实现跨计算机集群的大型数据集的分布式处理。它最初的设计目的是为了检测和处理应用程序层的故障,从单个机器扩展到数千台机器(这些机器可以是廉价的),每个机器提供本地计算和存储,而不是依靠硬件提供高可用性。
Hadoop 中有3个核心组件:
- 分布式文件系统:HDFS —— 实现将文件分布式存储在很多的服务器上
- 分布式运算编程框架:MapReduce —— 实现在很多机器上分布式并行运算
- 分布式资源调度平台:YARN —— 帮用户调度大量的 MapReduce 程序,并合理分配运算资源
HDFS
HDFS,是 Hadoop Distributed File System 的简称,是 Hadoop 抽象文件系统的一种实现。Hadoop 抽象文件系统可以与本地系统、Amazon S3 等集成,甚至可以通过 Web 协议(webhsfs)来操作。HDFS 的文件分布在集群机器上,同时提供副本进行容错及可靠性保证。例如客户端写入读取文件的直接操作都是分布在集群各个机器上的,没有单点性能压力。传统的文件系统是单机的,不能横跨不同的机器,因此 HDFS 的设计本质上是为了大量的数据能横跨成百上千台机器。即便如此,用户看到的是一个文件系统而不是很多文件系统,比如说要获取 /hdfs/tmp/file1 的数据,引用的是一个文件路径,但是实际的数据存放在很多不同的机器上,作为用户,不需要知道这些,就好比在单机上我们不关心文件分散在什么磁道什么扇区一样,HDFS 为用户管理这些数据。
设计特点
- 大数据文件:非常适合上 T 级别的大文件或者一堆大数据文件的存储,如果文件只有几个 G 甚至更小就不太适用
- 文件分块存储:HDFS 会将一个完整的大文件平均分块存储到不同计算器上,它的意义在于读取文件时可以同时从多个主机取不同区块的文件,多主机读取比单主机读取效率要高得多
- 流式数据访问:一次写入多次读写,这种模式跟传统文件不同,它不支持动态改变文件内容,而是要求让文件一次写入就不做变化,要变化也只能在文件末添加内容
- 廉价硬件:HDFS 可以应用在普通 PC 机上,这种机制能够让一些公司用几十台廉价的计算机就可以撑起一个大数据集群
- 硬件故障:HDFS 认为所有计算机都可能会出问题,为了防止某个主机失效读取不到该主机的块文件,它将同一个文件块副本分配到其它某几个主机上,如果其中一台主机失效,可以迅速找另一块副本取文件
不适用的场景
- 低延时的数据访问:对延时要求在毫秒级别的应用,不适合采用 HDFS,HDFS 是为高吞吐数据传输设计的,因此可能牺牲延时 HBase 更适合低延时的数据访问
- 大量小文件:文件的元数据(如目录结构,文件 Block 的节点列表,Block-node Mapping)保存在 NameNode 的内存中, 整个文件系统的文件数量会受限于 NameNode 的内存大小; 经验而言,一个文件/目录/文件块一般占有150字节的元数据内存空间,如果有100万个文件,每个文件占用1个文件块,则需要大约300M的内存,因此上亿级别的文件数量在现有商用机器上难以支持
- 多方读写:需要任意的文件修改 HDFS 采用追加(append-only)的方式写入数据,不支持文件任意 offset 的修改,不支持多个写入器(writer)
关键元素
- Block:将一个文件进行分块,通常是64M,设置成这么大是为了最小化查找(seek)时间,控制定位文件与传输文件所用的时间比例。假设定位到 Block 所需的时间为10ms,磁盘传输速度为100M/s。如果要将定位到 Block 所用时间占传输时间的比例控制1%,则 Block 大小需要约100M;但是如果Block设置过大,在 MapReduce 任务中,Map 或者 Reduce 任务的个数如果小于集群机器数量,会使得作业运行效率很低;Block 的拆分使得单个文件大小可以大于整个磁盘的容量,构成文件的 Block 可以分布在整个集群, 理论上,单个文件可以占据集群中所有机器的磁盘
- NameNode:保存整个文件系统的目录信息、文件信息及分块信息,这是由唯一 一台主机专门保存的,当然这台主机如果出错,NameNode 就失效了。在 Hadoop2.* 开始支持 activity-standy 模式----如果主 NameNode 失效,启动备用主机运行 NameNode
- DataNode:分布在廉价的计算机上,用于存储 Block 块文件
基于 HDFS 的数据库
HBase
HBase 是 Hadoop Database 即Hadoop数据库,数据通常存储在 HDFS 上,HDFS 为 HBase 提供了高可靠性的底层存储支持。它是一个适合于非结构化数据存储的数据库,基于列的而不是基于行的模式,同样利用 Hadoop MapReduce 来处理其中的海量数据。
- HDFS 为 HBase 提供了高可靠性的底层存储支持
- Hadoop MapReduce 为 HBase 提供了高性能的计算能力
- Zookeeper 为 HBase 提供了稳定服务和 failover 机制
- Pig 和 Hive 为 HBase 提供了高层语言支持,使得在 HBase 上进行数据统计处理变的非常简单
- Sqoop 为 HBase 提供了方便的 RDBMS(关系型数据库)数据导入功能,使得传统数据库数据向 HBase 中迁移变的非常方便HBASE本身作为一个分布式数据库
此外,HBase 本身可以完全不考虑 HDFS 的,我们完全可以只把 HBase 当作是一个分布式高并发 k-v 存储系统,只不过它底层的文件系统是通过 HDFS 来支持。换做其他的分布式文件系统也是一样,不影响 HBase 的本质,甚至如果不考虑文件系统的分布式或稳定性等特性,完全可以用简单的本地文件系统,甚至内存文件系统来代替。
使用场景对比
- 对于经常需要修改原有的数据的场景,使用 Hbase 进行存储
- 对于需要经常进行全表扫描、进行大批量的查询的场景,选择 HDFS
- 对于性能要求不高且只需要支持单条数据查询或者小批量数据进行查询的场景,两者均可
MongoDB
MongoDB 是一种文档数据库,文档是处理信息的基本单位。一个文档可以很长、很复杂,可以无结构,与字处理文档类似。常用于日志的采集和存储,小文件的分布式存储,类似互联网微博应用的数据存储
使用场景
- 网站数据:非常适合实时的插入、更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
- 缓存:由于性能很高,也适合作为信息基础设施的缓存层;在系统重启之后,由 Mongo 搭建的持久化缓存可以避免下层的数据源过载
- 大尺寸、低价值的数据:使用传统的关系数据库存储一些数据时可能会比较贵,在此之前,很多程序员往往会选择传统的文件进行存储
- 高伸缩性的场景:非常适合由数十或者数百台服务器组成的数据库
- 用于对象及JSON数据的存储:Mongo 的 BSON 数据格式非常适合文档格式化的存储及查询
不适合的场景
- 高度事物性的系统:例如银行或会计系统,传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序
- 传统的商业智能应用:针对特定问题的 BI 数据库会对产生高度优化的查询方式,对于此类应用,数据仓库可能是更合适的选择
- 需要SQL的问题
MapReduce
HDFS 可以为用户整体管理不同机器上的数据,任务下达时使用很多台机器处理,这就面临了如何分配工作的问题:如果一台机器挂了如何重新启动相应的任务、机器之间如何互相通信交换数据以完成复杂的计算等。这就是 MapReduce 的功能。MapReduce 的设计,采用了很简化的计算模型,只有 Map 和 Reduce 两个计算过程(中间用 Shuffle 串联)。使用这个模型,已经可以处理大数据领域很大一部分问题了。
基本原理
将大的数据分析分成小块逐个分析,最后再将提取出来的数据汇总分析,最终获得我们想要的内容,举例说明:
考虑统计一个存储在 HDFS 上的巨大的文本文件,我们想要知道这个文本里各个词的出现频率。Map阶段,几百台机器同时读取这个文件的各个部分,分别把各自读到的部分分别统计出词频,产生类似(hello, 12100次),(world,15214次)等等这样的 Pair(这里把 Map 和 Combine 放在一起说以便简化);这几百台机器各自都产生了如上的集合,然后又有几百台机器启动 Reduce 处理。Reduce 阶段,Reducer 机器 A 将从 Mapper 机器收到所有以 A 开头的统计结果,机器 B 将收到 B 开头的词汇统计结果(实际上不会真的以字母开头做依据,而是用函数产生 Hash 值以避免数据串化。因为类似 X 开头的词比其他要少得多,会导致各个机器的工作量相差悬殊)。然后这些 Reducer 将再次汇总,(hello,12100)+(hello,12311)+(hello,345881)= (hello,370292)。每个 Reducer 都如上处理,就得到了整个文件的词频结果。
Map+Reduce 的简单模型虽然好用,但是很笨重。第二代的 Tez 和 Spark 除了引入内存 Cache 之类的新 Feature,本质上来说,是让 Map/Reduce 模型更通用,让 Map 和 Reduce 之间的界限更模糊,数据交换更灵活,磁盘的读写更少,以便更方便地描述复杂算法,取得更高的吞吐量。
框架
Hadoop 的集群主要由 NameNode,DataNode,Secondary NameNode,JobTracker,TaskTracker 组成:
- NameNode:记录了文件是如何被拆分成 Block 以及这些 Block 都存储到了那些 DateNode 节点
- NameNode:保存了文件系统运行的状态信息
- DataNode:存储被拆分的Blocks
- Secondary NameNode:帮助 NameNode 收集文件系统运行的状态信息
- JobTracker:当有任务提交到 Hadoop 集群的时候负责 Job 的运行,负责调度多个 TaskTracker
- TaskTracker:负责某一个 Map 或者 Reduce 任务
Hive,Impala 与 Spark
闲谈 Hadoop、Hive、Impala 与 Spark 的关系
”“”
有了 MapReduce,Tez 和 Spark 之后,程序员发现,MapReduce 的程序写起来真麻烦。他们希望简化这个过程。这就好比你有了汇编语言,虽然你几乎什么都能干了,但是你还是觉得繁琐。你希望有个更高层更抽象的语言层来描述算法和数据处理流程。于是就有了 Pig 和 Hive。Pig 是接近脚本方式去描述 MapReduce,Hive 则用的是 SQL。它们把脚本和 SQL语言翻译成 MapReduce 程序,丢给计算引擎去计算,而你就从繁琐的 MapReduce 程序中解脱出来,用更简单更直观的语言去写程序了。
有了 Hive 之后,人们发现 SQL 对比 Java 有巨大的优势。一个是它太容易写了。刚才词频的东西,用 SQL 描述就只有一两行,MapReduce 写起来大约要几十上百行。而更重要的是,非计算机背景的用户终于感受到了爱:我也会写 SQL!于是数据分析人员终于从乞求工程师帮忙的窘境解脱出来,工程师也从写奇怪的一次性的处理程序中解脱出来。大家都开心了。Hive 逐渐成长成了大数据仓库的核心组件。甚至很多公司的流水线作业集完全是用 SQL 描述,因为易写易改,一看就懂,容易维护。
自从数据分析人员开始用 Hive 分析数据之后,它们发现,Hive 在 MapReduce 上跑,真**慢!流水线作业集也许没啥关系,比如24小时更新的推荐,反正24小时内跑完就算了。但是数据分析,人们总是希望能跑更快一些。比如我希望看过去一个小时内多少人在****页面驻足,分别停留了多久,对于一个巨型网站海量数据下,这个处理过程也许要花几十分钟甚至很多小时。而这个分析也许只是你万里长征的第一步,你还要看多少人浏览了**多少人看了******的 CD,以便跟老板汇报,我们的用户是猥琐男闷骚女更多还是文艺青年/少女更多。你无法忍受等待的折磨,只能跟帅帅的工程师蝈蝈说,快,快,再快一点!
于是 Impala,Presto,Drill 诞生了(当然还有无数非著名的交互 SQL 引擎,就不一一列举了)。三个系统的核心理念是,MapReduce 引擎太慢,因为它太通用,太强壮,太保守,我们 SQL 需要更轻量,更激进地获取资源,更专门地对 SQL 做优化,而且不需要那么多容错性保证(因为系统出错了大不了重新启动任务,如果整个处理时间更短的话,比如几分钟之内)。这些系统让用户更快速地处理 SQL 任务,牺牲了通用性稳定性等特性。如果说 MapReduce 是大砍刀,砍啥都不怕,那上面三个就是剔骨刀,灵巧锋利,但是不能搞太大太硬的东西。
这些系统,说实话,一直没有达到人们期望的流行度。因为这时候又两个异类被造出来了。他们是 Hive on Tez / Spark 和 SparkSQL。它们的设计理念是,MapReduce 慢,但是如果我用新一代通用计算引擎 Tez 或者 Spark 来跑 SQL,那我就能跑的更快。而且用户不需要维护两套系统。这就好比如果你厨房小,人又懒,对吃的精细程度要求有限,那你可以买个电饭煲,能蒸能煲能烧,省了好多厨具。
上面的介绍,基本就是一个数据仓库的构架了。底层 HDFS,上面跑 MapReduce/Tez/Spark,再上面跑 Hive,Pig;或者 HDFS 上直接跑 Impala,Drill,Presto,这解决了中低速数据处理的要求。
“”“
------摘自知乎《如何用形象的比喻描述大数据的技术生态?Hadoop、Hive、Spark 之间是什么关系?》,Xiaoyu Ma,对敏感词做了屏蔽处理
Hive
Hive 是一个构建于 Hadoop 顶层的数据仓库工具,支持大规模数据存储、分析,具有良好的可扩展性。某种程度上可以看作是用户编程接口,本身不存储和处理数据。它依赖分布式文件系统 HDFS 存储数据,依赖分布式并行计算模型 MapReduce 处理数据。Hive 定义了简单的类似 SQL 的查询语言——HiveQL,用户可以通过编写的 HiveQL 语句运行 MapReduce 任务,可以很容易把原来构建在关系数据库上的数据仓库应用程序移植到 Hadoop 平台上。
注意,Hive 并不是一个关系数据库。Hive 中没有定义专门的数据格式,由用户指定,需要指定三个属性:列分隔符、行分隔符 、读取文件数据的方法(Hive 中默认有三个文件格式 TextFile,SequenceFile 以及 RCFile)。Hive 在查询数据的时候,由于没有索引,需要扫描整个表,因此延迟较高;另外一个导致 Hive 执行延迟高的因素是 MapReduce 框架,由于 MapReduce 本身具有较高的延迟,因此在利用 MapReduce 执行 Hive 查询时,也会有较高的延迟(相对的,数据库的执行延迟较低,当然,这个低是有条件的,即数据规模较小,当数据规模大到超过数据库的处理能力的时候,Hive 的并行计算显然能体现出优势)。
Hive 中包含以下数据模型:DB、Table,External Table,Partition,Bucket:
– db:在 hdfs 中表现为 ${hive.metastore.warehouse.dir} 目录下一个文件夹
– table:在 hdfs 中表现所属 db 目录下一个文件夹
– external table:与 table 类似,不过其数据存放位置可以在任意指定路径
– partition:在 hdfs 中表现为 table 目录下的子目录
– bucket:在 hdfs 中表现为同一个表目录下根据 hash 散列之后的多个文件
架构
Hive 的系统架构分为用户接口模块、驱动模块、元数据存储模块。
更一般的架构为:
用户接口模块
包括 CLI、HWI、JDBC、ODBC、Thrift Server,CLI 即Shell命令行;JDBC/ODBC 是 Hive 的 Java 接口,通过 Thrift Server 接入,然后发送给 Driver;WebGUI 是通过浏览器访问 Hive
驱动模块(Driver)
包括编译器、优化器、执行器等,负责把 HiveQL 语句转换成一系列 MapReduce 作业
元数据存储模块(Metastore)
是一个独立的关系型数据库(自带 derby 数据库,或 MySQL 数据库),由 Cloudera 公司开发的新型查询系统,它提供 SQL 语义,能查询存储在 Hadoop 的 HDFS 和 HBase 上的PB级大数据,在性能上比 Hive 高出3~30倍。元数据包括表的名字、表的列和分区及其属性、表的属性(是否为外部表等)、表的数据所在目录等
工作原理
下图描述了 Hive 和 Hadoop 之间的工作流程:
- Execute Query
Hive 接口,如命令行或 Web UI 发送查询驱动程序(任何数据库驱动程序,如 JDBC,ODBC 等)来执行 - Get Plan
在驱动程序帮助下查询编译器,分析查询检查语法和查询计划或查询的要求 - Get Metadata
编译器发送元数据请求到 Metastore(任何数据库) - Send Metadata
Metastore 发送元数据,以响应编译器 - Send Plan
编译器检查要求,并重新发送计划给驱动程序,到此为止,查询解析和编译完成 - Execute Plan
驱动程序发送执行计划到执行引擎 - Execute Job
在内部,执行作业的过程是一个 MapReduce,执行引擎发送作业给 JobTracker,再进一步分发
Metadata Ops
与此同时,在执行时,执行引擎可以通过 Metastore 执行元数据操作 - Fetch Result
执行引擎接收来自数据节点的结果 - Send Results
执行引擎发送这些结果值给驱动程序 - Send Results
驱动程序将结果发送给 Hive 接口
Impala
Impala 是一个运行在 Hadoop 之上的大规模并行处理(MPP)查询引擎,提供对 Hadoop 集群数据的高性能、低延迟的 SQL 查询,使用 HDFS 作为底层存储。它对查询的快速响应使交互式查询和对分析查询的调优成为可能,而这些在针对处理长时间批处理作业的 SQL-on-Hadoop 传统技术上是无法完成的。Impala 与 Hive 元数据存储数据库相结合,在这两个组件之间共享数据库表,并且Impala 与 HiveQL 的语法兼容。因此既可以使用 Impala 也可以使用 Hive 进行建立表、发布查询、装载数据等操作。Impala 可以在已经存在的 Hive 表上执行交互式实时查询。
为什么使用 Impala
- Impala 可以使用 SQL 访问存储在 Hadoop 上的数据,而传统的 MapReduce 则需要掌握 Java 技术
- Impala 提供 SQL 直接访问 HDFS 文件系统、HBase 数据库系统或 Amazon S3 的数据
- Impala 在 Hadoop 生态系统之上提供并行处理数据库技术,允许用户执行低延迟的交互式查询
- Impala 大都能在几秒或几分钟内返回查询结果,而相同的 Hive 查询通常需要几十分钟甚至几小时完成
- Impala 的实时查询引擎非常适合对 Hadoop 文件系统上的数据进行分析式查询
- 由于 Impala 能实时给出查询结果,它能够很好地与 Pentaho、Tableau 这类报表或可视化工具一起使用(这些工具已经配备了 Impala 连接器,可以从 GUI 直接执行可视化查询)
- Impala 与 Hadoop 生态圈相结合,内置对所有 Hadoop 文件格式(ORC、Parquet等等)的支持,这意味着可以使用 Hadoop 上的各种解决方案存储、共享和访问数据,同时避免了数据竖井,并且降低了数据迁移的成本
Impala 缺省使用 Parquet 文件格式,这种列式存储对于典型数据仓库场景下的大查询是最优的(Parquet 是一种列式存储,它不像普通数据仓库那样水平存储数据,而是垂直存储数据;当查询在数值列上应用聚合函数时,这种存储方式将带来巨大的性能提升,原因是只需要读取文件中该列的数据,而不是像 Hive 需要读取整个数据集;Parquet文件格式支持高效的压缩编码方式,例如 Hadoop 和 Hive 缺省使用的 snappy 压缩;Parquet 文件也可用 Hive 和 Pig 处理
适用场景
- 需要低延迟得到查询结果
- 快速分析型查询
- 实时查询
- 需要多次处理相同类型的查询
架构
Impala 由不同的守护进程组成,每种守护进程运行在 Hadoop 集群中的特定主机上,其中 Impalad、Statestored、Catalogd 三个守护进程在其架构中扮演主要角色。
Impala守护进程
Impala 的核心组件是一个运行在集群中每个数据节点上的守护进程,物理表现为 Impalad 进程。该进程读写数据文件,接收从 Impala-Shell 命令行、Hue、JDBC、ODBC (Java或其它语言的交互接口)提交的查询请求,将查询工作并行分布到集群的数据节点上,并将查询的中间结果返回给中心协调节点。可以将查询提交至任意一个数据节点上运行的 Impala 守护进程,此守护进程实例担任该查询的协调器,其它节点提交部分中间结果返给协调器,协调器构建查询的最终结果集。当在试验环境使用 Impala-Shell 命令行运行 SQL 时,出于方便性,通常总是连接同一个 Impala 守护进程。而在生产环境负载的集群中,可以采用循环的方式,通过 JDBC 或 ODBC 接口,将每个查询轮流提交至不同的 Impala 守护进程,以达到负载均衡。Impala守护进程持续与 Statestore 进行通信,以确认每个节点健康状况以及是否可以接收新的任务。当集群中的任何 Impala 节点建立、修改、删除任何类型的对象,或者通过 Impala 处理一个 insert 或 load data 语句时,Catalogd 守护进程(Impala 1.2引入)都会发出广播消息。Impala 守护进程会接收这种从 Catalogd 守护进程发出的广播消息。这种后台通信减少了对 refresh 或 invalidate metadata 语句的需要,而在 Impala 1.2版本前,这些语句被用于在节点间协调元数据信息。
Impala Statestore
叫做 Statestore 的 Impala 组件检查集群中所有数据节点上 Impala 守护进程的健康状况,并将这些信息持续转发给每个 Impala 守护进程,其物理表现为一个名为 Statestored 的守护进程,该进程只需要在集群中的一台主机上启动。如果 Impala 守护进程由于硬件、软件、网络或其它原因失效,Statestore 会通知所有其它的 Impala 守护进程,这样以后的查询就不会再向不可到达的节点发出请求。 Statestore 的目的只是在发生某种错误时提供帮助,因此在正常操作一个 Impala 集群时,它并不是一个关键组件。即使 Statestore 没有运行或者不可用,Impala 守护进程依然会运行,并像通常一样在它们中分法任务。 这时如果一个 Impala 守护进程失效,仅仅是降低了集群的鲁棒性。当 Statestore 恢复可用后,它会重建与 Impala 守护进程之间的通信并恢复监控功能。在 Impala 中,所有负载均衡和高可用的考虑都是用于 Impala 守护进程的。Statestored 和 Catalogd 进程没有高可用的需求,因为这些进程即使出现问题也不会引起数据丢失。当这些进程由于所在的主机停机而变成不可用时,可以这样处理:先停止 Impala 服务,然后删除 Impala StateStore 和 Impala Catalog 服务器角色,再在另一台主机上添加这两个角色,最后重启 Impala 服务。
Impala Catalog 服务
称为 Catalog 服务的 Impala 组件将 Impala SQL 语句产生的元数据改变转发至集群中的所有数据节点,其物理表现为一个名为 Catalogd 的守护进程,该进程只需要在集群中的一台主机上启动,而且应该与 Statestored 进程在同一台主机上。由于 Catalog 服务的存在,当通过执行 Impala 语句而改变元数据时,不需要再发出 refresh 或 invalidate metadata 语句。然而,当通过 Hive 执行建立表、装载数据等操作后,在一个 Impala 节点上执行查询前,仍然需要先发出 refresh 或 invalidate metadata 语句。例如,通过 Impala 执行的 create table、insert 或其它改变表或改变数据的操作,无需执行 refresh and invalidate metadata 语句。而如果这些操作是用过 Hive 执行的,或者是直接操纵的 HDFS 数据文件,仍需执行 refresh and invalidate metadata 语句(只需在一个 Impala 节点执行,而不是全部节点)。缺省情况下,元数据在 Impala 启动时异步装载并缓存,这样 Impala 可以立即接收查询请求。如果想让 Impala 等所有元数据装载后再接收查询请求,需要设置 Catalogd 的配置选项 load_catalog_in_background=false
Impala的元数据和元数据存储
前面讨论 Impala 如何与 Hive一起使用时提到,Impala 使用一个叫做 Metastore 的数据库维护它的表定义信息。同时 Impala 还跟踪其它数据文件底层特性的元数据,如 HDFS 中数据块的物理位置信息。对于一个有很多分区或很多数据的大表,获取它的元数据可能很耗时,有时需要花上几分钟的时间。因此每个 Impala 节点都会缓存这些元数据,当后面再查询该表时,就可以复用缓存中的元数据。如果表定义或表中的数据更新了,集群中所有其它的 Impala 守护进程在查询该表前, 都必须能收到最新的元数据,并更新自己缓存的元数据。在 Impala 1.2或更高版本中,这种元数据的更新是自动的,由 Catalogd 守护进程为所有通过 Impala 发出的 DDL 和 DML 语句进行协调。对于通过 Hive 发出的 DDL 和 DML,或者手工改变了 HDFS 文件的情况,还是需要在 Impala 中使用 refresh 语句(当新的数据文件被加到已有的表上)或 invalidate metadata 语句(新建表、删除表、执行了 HDFS 的 rebalance 操作,或者删除了数据文件)。Invalidate metadata 语句获取 Metastore 中存储的所有表的元数据。如果能够确定在 Impala 外部只有特定的表被改变,可以为每一个受影响的表使用 refresh 表名,该语句只获取特定表的最新元数据。
Spark
Apache Spark 是一个围绕速度、易用性和复杂分析构建的大数据处理框架,最初在2009年由加州大学伯克利分校的 AMPLab 开发,并于2010年成为 Apache 的开源项目之一,与 Hadoop 和 Storm 等其他大数据和 MapReduce 技术相比,Spark 有如下优势:
- 运行速度快:Spark 拥有 DAG 执行引擎,支持在内存中对数据进行迭代计算;官方提供的数据表明,如果数据由磁盘读取,速度是 Hadoop MapReduce 的10倍以上,如果数据从内存中读取,速度可以高达100多倍。
- 适用场景广泛:大数据分析统计、实时数据处理、图计算及机器学习
- 易用性:编写简单,支持80种以上的高级算子,支持多种语言,数据源丰富,可部署在多种集群中
- 容错性高:Spark 引进了弹性分布式数据集 RDD (Resilient Distributed Dataset) 的抽象,它是分布在一组节点中的只读对象集合,这些集合是弹性的,如果数据集一部分丢失,则可以根据“血统”(即充许基于数据衍生过程)对它们进行重建。另外在 RDD 计算时可以通过 CheckPoint 来实现容错,而 CheckPoint 有两种方式:CheckPoint Data,和Logging The Updates,用户可以控制采用哪种方式来实现容错
适用场景
- 复杂的批量处理(Batch Data Processing),偏重点在于处理海量数据的能力,至于处理速度可忍受,通常的时间可能是在数十分钟到数小时;
- 基于历史数据的交互式查询(Interactive Query),通常的时间在数十秒到数十分钟之间
- 基于实时数据流的数据处理(Streaming Data Processing),通常在数百毫秒到数秒之间
架构
Hadoop 存在缺陷:基于磁盘,无论是 MapReduce 还是 YARN 都是将数据从磁盘中加载出来,经过 DAG,然后重新写回到磁盘中,计算过程的中间数据又需要写入到 HDFS 的临时文件,这些都使得 Hadoop 在大数据运算上表现太“慢”,因此 Spark 应运而生。通常当需要处理的数据量超过了单机尺度(比如我们的计算机有4GB的内存,而我们需要处理100GB以上的数据),这时我们可以选择Spark 集群进行计算;有时我们可能需要处理的数据量并不大,但是计算很复杂,需要大量的时间,这时我们也可以选择利用 Spark 集群强大的计算资源,并行化地计算,其架构示意图如下:
Spark Core:包含 Spark 的基本功能,尤其是定义 RDD 的 API、操作以及在这两者上的动作;其他 Spark 的库都是构建在 RDD 和 Spark Core 之上的
Spark SQL:提供通过 Apache Hive 的 SQL 变体 Hive 查询语言(HiveQL)与 Spark 进行交互的API,每个数据库表被当做一个 RDD,Spark SQL 查询被转换为 Spark 操作;Spark 提供的 SQL 形式的对接 Hive、JDBC、HBase 等各种数据渠道的 API,用 Java 开发人员的思想来讲就是面向接口、解耦合,ORMapping、Spring Cloud Stream 等类似的思想
Spark Streaming:基于 SparkCore 实现的可扩展、高吞吐、高可靠性的实时数据流处理,支持从 Kafka、Flume 等数据源处理后存储到 HDFS、DataBase、Dashboard 中,对实时数据流进行处理和控制;Spark Streaming 允许程序能够像普通 RDD 一样处理实时数据
MLlib:一个常用机器学习算法库,算法被实现为对 RDD 的Spark操作,这个库包含可扩展的学习算法,比如分类、回归等需要对大量数据集进行迭代的操作。
GraphX:控制图、并行图操作和计算的一组算法和工具的集合,GraphX 扩展了 RDD API,包含控制图、创建子图、访问路径上所有顶点的操作
工作原理
Cluster Manager 在 Standalone 模式中即为 Master 主节点,控制整个集群,监控 Worker;在 YARN 模式中为资源管理器负责分配资源,有点像 YARN 中 ResourceManager 那个角色,大管家握有所有的干活的资源,属于乙方的总包
WorkerNode 是可以干活的节点,听大管家 ClusterManager 差遣,是真正有资源干活的主,负责控制计算节点,启动 Executor 或者 Driver
Executor 是在 WorkerNode 上起的一个进程,相当于一个包工头,负责准备 Task 环境和执行
Task 负责内存和磁盘的使用,是施工项目里的每一个具体的任务
Driver 是统管 Task 的产生与发送给 Executor 的,运行 Application 的 main() 函数,是甲方的司令员
SparkContext 是与 ClusterManager 打交道的,负责给钱申请资源的,是甲方的接口人
整个互动流程是这样的:
- 甲方来了个项目,创建了 SparkContext,SparkContext 去找 ClusterManager(可以是Standalone,Mesos,Yarn)申请 Executor 资源同时给出报价,需要多少 CPU 和内存等资源,并启动 StandaloneExecutorbackend
- ClusterManager 去找 WorkerNode 并启动 Excutor,并介绍 Excutor 给 Driver 认识
- Driver 根据施工图拆分一批批的 Task,将 Task 送给 Executor 去执行(SparkContext 构建成 DAG 图,将 DAG 图分解成 Stage、将 Taskset 发送给 Task Scheduler,最后由 Task Scheduler 将 Task 发送给 Executor 运行)
- Executor 接收到 Task 后准备 Task 运行时依赖并执行,并将执行结果返回给 Driver
- Driver 会根据返回回来的 Task 状态不断的指挥下一步工作,直到所有 Task 执行结束,运行完释放所有资源
特点:多线程运行、运行过程与资源管理器无关、Task 采用了数据本地性和推测执行来优化
附:RDD 的依赖关--窄依赖和宽依赖
窄依赖(narrow dependency):是指每个父 RDD 的一个 Partition 最多被子 RDD 的一个 Partition 所使用,例如 map、filter、union 等操作都会产生窄依赖;(独生子女)即 rdd 中的每个 partition 仅仅对应父 rdd 中的一个 partition;父 rdd 里面的 partition 只去向子 rdd 里的某一个 partition,这叫窄依赖;如果父 rdd 里面的某个 partition 会去子 rdd 里面的多个 partition,那它就一定是宽依赖
宽依赖(shuffle dependency):是指一个父 RDD 的 Partition 会被多个子 RDD 的 Partition 所使用,例如 groupByKey、reduceByKey、sortByKey 等操作都会产生宽依赖;(超生)每一个父 rdd 的 partition 数据都有可能传输一部分数据到子 rdd 的每一个 partition 中,即子 rdd 的多个 partition 依赖于父 rdd;宽依赖划分成一个 Stage
对比
由于 Spark 是一种计算框架,因此后续的对比侧重于用 SparkSQL 进行对比
Hive 与 Impala
相同点
- 使用相同的存储数据池,都支持把数据存储于 HDFS 和 HBase 中
- 使用相同的元数据
- 对 SQL 的解释处理比较相似,都是通过词法分析生成执行计划
- 用户可以定义自己的标量函数(UDF)、聚合函数(UDAF)和表函数(UDTF)
不同点
- Hive 适合于长时间的批处理查询分析,而 Impala 适合于实时交互式 SQL 查询
- Hive 依赖于 MapReduce 计算框架,Impala 把执行计划表现为一棵完整的执行计划树,直接分发执行计划到各个 Impalad 执行查询
- Hive 在执行过程中,如果内存放不下所有数据,则会使用外存,以保证查询能顺序执行完成;而 Impala 在遇到内存放不下数据时,不会利用外存,所以 Impala 目前处理查询时会受到一定的限制
Hive 与 SparkSQL
相同点
- 都支持 ThriftServer 服务,为 JDBC 提供解决方案
不同点
- Hive 是一个构建于 Hadoop 顶层的数据仓库工具,底层采用 MapReduce 进行计算
- SparkSQL 基于 Spark 框架
SparkSQL 与 Impala
相同点
- 支持 Parquet、Avro、Text、JSON、ORC 等多种文件格式
- 支持存储在 HDFS、HBase、Amazon S3 上的数据操作
- 支持把数据缓存在内存中
- 支持 UDF
不同点
- SparkSQL 底层使用 Spark 计算框架,提供有向无环图,比 MapReduce 更灵活;Spark SQL 以 Schema RDD 为核心,模糊了 RDD 与关系表之间的界线;不适合商业智能和交互式查询
- Impala 底层采用 MPP 技术,支持快速交互式 SQL 查询
标签:HDFS,Impala,Hadoop,Hive,查询,Spark,数据 来源: https://blog.csdn.net/weixin_41559709/article/details/118934929