本文包含Hive的设计与架构的详细信息,具体内容如下:
- Hive架构
- Hive数据模型
- 元存储
- Motivation
- 元数据对象
Hive 架构
图中展示了Hive的主要组成部分,以及与Hadoop的交互,如图所述,Hive的主要组件有:
- UI – 提供给用户的接口,用于对系统提交查询和其他操作。从2011年起,在Hive开发了一个命令行接口和一个基于GUI的网页.
- Driver – 这个组件接收来自UI的查询。这个组件实现了会话句柄的概念,并提供执行,以及模仿JDBC/ODBC接口取得APIs。
- Compiler – 这个组件解析查询,对不同的查询块和查询表达式做语义分析,最后根据元数据的表和分区的元数据来产生一个执行计划。
- Metastore – 这个组件存储数据仓库中的表和分区的所有结构信息,包括列、列类型信息,需要读和写数据的序列化器和反序列化器,以及数据存储的HDFS文件位置。
- Execution Engine – 这个组件执行由compiler创建的执行计划。这个计划是一个DAG stages。这个执行引擎管理着这个计划的不同的stages的依赖,并且在合适的系统组件上执行这些stages。
图中也显示了,一个经典的查询流程是如何贯穿这个系统的。在图中的第一步,UI调用执行接口到Driver。第二步,Driver对查询创建一个会话句柄(session handle),并且发送查询给Compiler来产生执行计划。第三和第四步,compiler从metastore获取需要的元数据。这个元数据用于对查询树中的表达式做类型检查、和基于查询谓词做分区剪枝。这个由compiler产生的计划(第五步)是一个有向无环图(DAG)的stages,每个stage可以是一个map/reduce作业,一个元数据操作或者对HDFS的操作。对于map/reduce stages,这个计划包含map操作树(执行在mapper上的操作树)和一个reduce操作树(需要reduce的操作)。第六步(6,6.1,6.2,6.3),执行引擎提交这些stages到合适的组件。在每个task(mapper/reducer),与表或中间输出相关的反序列化器,用于从HDFS文件读取数据行,并且被传递到相关的操作树。一旦有输出产生,会通过序列化器把输出写到一个临时的HDFS文件(这会发生在mapper端,且没有reduce的情况下)。这个临时文件用于给计划的子stage的map/reduce提供数据。对于DML(数据操纵语言)操作,最终的临时文件被移到表(table)的位置。这个策略用于确保不会读到脏数据(在HDFS上,文件重命名是一个原子操作)。对于查询,通过执行引擎直接从HDFS读取这个临时文件的内容,然后作为从Driver调用获得的一部分返回给UI(第七,八,九步)。
Hive 数据模型
Hive中的数据组织成以下:
-
Tables – 这与关系型数据库的表类似。表可以被过滤,投影,连接和合并。此外,一个表的所有数据存储在HDFS的一个目录下。Hive也支持外部表概念,即在创建表的时候,可以在创建表语句中,通过提供正确的路径,然后创建外部表。与关系型数据库相似,一个表里的行被组织成有类型的列。
-
Partitions – 每个表都有一个或多个分区key,来决定数据如何存储,例如,表T有一个日期分区列ds,数据文件则存储在HDFS的
<table location>/ds=<date>
目录。在查询的情况下,分区会对数据进行剪枝,例如,在一个查询中有谓词T.ds = '2008-09-01'
,则查询只会针对HDFS上的<table location>/ds=2008-09-01/
这个目录进行数据查找。 -
Buckets – 在表中,每个分区的数据,还可能基于一个列的哈希划分成桶。每个桶作为一个文件存储在分区目录下。分桶使得系统更有效地进行数据的抽样查询。
除了原生列类型(integer, float, string, date, boolean),Hive还支持数组和map(key、value键值对)。另外,用户也可以使用原生类型来自定义自己的类型。类型系统依赖于SerDe(序列化和反序列化)和对象检查接口,用户通过实现他们自己的对象检查器来创建自己的类型,并且使用这些检查器,用户能够创建他们自己的SerDes来序列化和反序列化数据到HDFS文件,当需要理解其他数据格式和类型时,这两个接口为其提供了必要的钩子来继承Hive的这个能力。内置的对象检查器,如ListObjectInspector
,StructObjectInspector
和MapObjectInspector
以一个可扩展的方式,提供了必要的原型来组合富类型。例如map(关联数组)和数据组提供了有用的诸如size
和index
操作符的内置函数。.
用于索引嵌套类型,例如a.b.c=1
,表示比较a里面的b字段中的c字段是否为1。
元存储
Motivation
元存储提供了两个数据仓库中重要但通常会忽略的特征:数据抽象和数据发现。在Hive中,如果没有数据抽象,用户在查询时,必须提供数据格式、提取器和加载器信息。在Hive中,这些信息是在表创建的时候给予的,并且在每次引用表的时候会重复使用这些信息。这与传统的仓库系统非常相似。第二个特性:数据发现,允许用户在仓库中探索和发现有意义的数据。
元数据对象
- 数据库 - 表的命名空间,在未来,它可以被用来作为一个管理单元,如果没有指定数据库名,默认使用
default
库。 - 表 - 表的元数据包含:列的列表,拥有者,存储和序列化信息。也能包含任意用户指定的key-value数据。存储信息包括数据的位置,文件的输入和输出格式,以及桶信息。序列化和反序列化元数据包括序列化器和反序列化器的类实现,所有的这些信息在创建表的时候提供。
- 分区 -每个分区可以有自己的列和序列化和反序列化存储信息。这些信息的变更不会影响老的分区。
文章翻译自:Design