Hive架构原理
a.用户接口:Client
- CLI(Hive shell)、JDBC/ODBC(java访问hive)、Hive WEBUI(浏览器访问hive)和Thrift服务器
b.驱动器:Driver - 解析器(SQL Parser):将SQL字符串转换成抽象语法树AST,这一步一般都用第三方工具库完成,比如antlr;对AST进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
- 编译器(Physical Plan):将AST编译生成逻辑执行计划
- 优化器(Query Optimizer):对逻辑执行计划进行优化。
- 执行器(Execution):把逻辑执行计划转换成可以运行的物理计划对于Hive来说,就是MR/Spark
c.元数据:MetaStore - 通俗来说,元数据就是“数据的数据”,例如一张表里有许多数据,而元数据则是在描述该表的相关信息,例如创建时间、列数、行数等。Hive的元数据默认储存在derby数据库里,但推荐储存在MySQL里。
d.存储和计算 - 使用HDFS进行存储,使用MapReduce进行计算
- 一句话概括:Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的Driver,结合元数据(MetaStore),将这些指令翻译成MapReduce,提交到Hadoop中执行,最后,将执行返回的结果输出到用户交互接口
索引!
- Hive在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些Key建立索引。
- Hive要访问数据中满足条件的特定值时,需要暴力扫描整个数据,因此访问延迟较高。由于 MapReduce 的引入, Hive 可以并行访问数据,因此即使没有索引,对于大量数据的访问,Hive 仍然可以体现出优势但由于数据的访问延迟较高,决定了 Hive 不适合在线数据查询
- 延迟原因:扫描整个表、底层MR延迟也高
- 数据库的低延迟是有条件的,当数据库单独处理不了超大规模数据时,并行提供的优势就大于低延迟的单个个体了
- 而在数据库中,通常会针对一个或者几个列建立索引,提升访问特定条件下数据访问的效率,并拥有较低的延迟
建表
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [(col_name data_type [COMMENT col_comment], ...)] [COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], …)]
[CLUSTERED BY (col_name, col_name, ...)
[SORTED BY (col_name [ASC|DESC], …)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
`` [LOCATION hdfs_path];
- EXTERNAL关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive创建内部表时,会将数据移动到数据仓库指向的路径。
- 若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变
- 在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据
STORED AS ORC
:下次试一下以ORC文件存储一张表,养成这样的习惯,这个表只有优点
内部表和外部表
- **内部表:**默认创建的表都是内部表,或称管理表
managed table
。Hive会::或多或少地::控制着数据的生命周期。Hive默认情况下会将这些表的数据存储在由配置项hive.metastore.warehouse.dir
(例如/user/hive/warehouse
)所定义的目录的子目录下。 当我们删除一个管理表时,Hive也会删除这个表中数据。++管理表不适合和其他工具共享数据++ - 外部表:如果表是外部表,那么Hive并非认为其完全拥有这份数据删除该表并不会删除掉这份数据,不过描述表的元数据信息会被删除掉。::所以建一张外部表的实质是在元数据建立一个路径指向外部数据源::,删除外部表只是删除元数据里的信息而原始数据不会删除,当重建表时可直接读取原始数据
分区
究其实质,建一张表就是建一个文件夹,然后把数据放在该文件夹里;而分区则是指在这个文件夹(table)下又建立一个子文件夹,把归属这个分区的数据放在这个子文件夹中。最为常见的分区字段就是日期字段,如20200630的数据会放在该表下‘20200630’归属的文件夹里。::以后会出现分区删除等操作,所以掌握分区非常重要::
- 分区的好处在于提供数据查询效率,当需要某个分区数据时Hive只需要去扫描该表下所需子文件夹即可,而不用全表扫描一遍。++是有点像跳表的索引层,不过会不会允许像跳表一样重叠,这个需要进一步学习++
- 分区需要在建表时进行,语句为:
PARTITIONED BY (col_name data_type)
- 增加一个分区时:
alter table table_name add partition(dt='20200630');
- 增加多个分区时:
alter table table_name add partition(dt='20200630') partition(dt='20200701');
- 删除一个分区时:
alter table table_name drop partition(dt='20200630');
- 删除多个分区时(注意逗号!):
alter table table_name drop partition(dt='20200630'),partition(dt='20200701');
其他科普小知识
- 世界上最大的Hadoop 集群在 Yahoo!,2009年的规模在4000 台节点左右,美团近年来达到了6000台以上。而数据库由于** ACID 语义的严格限制,扩展性非常有限**目前最先进的并行数据库Oracle在理论上的扩展能力也只有100台左右
- 但好像Hadoop也没有万台那种,好像也不是很厉害……