Hive知识归纳——详解 hive 各个知识点

有点标题党了,但是大部分常用知识点也算是涉及到了,希望对你有帮助

Hive是什么?

概念

  •    从概念上讲:由Facebook开源的一款基于hadoop的用于统计海量结构化数据的一个数据仓库。
  •   从本质上讲:将HQL语句转换成MapReduce程序的一个工具。

产生:

  • 让了方便非java开发人员对hdfs上的数据做 MapReduce 操作

架构

  1. 从客户端编辑 sql 语句提交到服务端,通过解释器,编译器,优化器生成执行计划,然后提交到 Hadoop 集群运行

其中计划执行的最小单元是一个个 operator,每个operator代表一个操作或者一个MR作业

  1. Hive的元数据依赖于关系型数据库,其真实数据是存在于Hadoop之上的

  2. 下图为 Hive 架构简图,其中 Hadoop 展示的是 1.x 版本的,2.x 以后是提交到 yarn上运行。


    image.png

支持的数据类型

  1. 复杂类型
    | array_type
    | map_type
    | struct_type
  2. 简单类型
    |TINYINT
    | SMALLINT
    | INT
    | BIGINT
    | BOOLEAN
    | FLOAT
    | DOUBLE
    | STRING

表的类型

  1. 外部表:删除表时,只会删除元数据信息,而不对真实数据进行修改
  2. 内部表:也叫管理表,删除表时,会对元数据和真实数据一起删除。

HIve分区

  • 意义
  1. 其意义主要在于优化查询,对于分区表,我们一般都要求使用分区字段进行过滤,以加快查询速度
  • 静态分区使用
  1. 建表是指定分区(其中分区在hdfs上表现为文件夹分类管理形式)

create table day_hour_table (id int, content string) partitioned by (dt string, hour string);

  1. 在已有的表上添加分区

ALTER TABLE table_name ADD PARTITION (dt='2018-06-02', hour='18')

  1. 在已有表上删除某分区

ALTER TABLE table_name DROP PARTITION (dt='2018-06-02', hour='18')

  1. 向分区表中添加数据:

LOAD DATA INPATH "/testFile" INTO TABLE table_name PARTITION(dt='2018-06-02', hour='18')

  • 动态分区
  1. 开启支持动态分区

set hive.exec.dynamic.partition=true;
默认:false

set hive.exec.dynamic.partition.mode=nostrict;
默认:strict(至少有一个分区列是静态分区)

  1. 相关参数

set hive.exec.max.dynamic.partitions.pernode;
每一个执行mr节点上,允许创建的动态分区的最大数量(100)
set hive.exec.max.dynamic.partitions;
所有执行mr节点上,允许创建的所有动态分区的最大数量(1000)
set hive.exec.max.created.files;
所有的mr job允许创建的文件的最大数量(100000)

  1. 加载数据

from table_name1
insert overwrite table table_name2 partition(age, sex)
select id, name, age, sex, address distribute by age, sex;

hive 分桶

  • 分桶表是对列值取哈希值的方式,将不同数据放到不同文件中存储。
    对于hive中每一个表、分区都可以进一步进行分桶。
    由列的哈希值除以桶的个数来决定每条数据划分在哪个桶中。

  • 适用场景:
    数据抽样( sampling )
    SMB Join(sort meger bucket join)

  1. 开启支持分桶

set hive.enforce.bucketing=true;
默认:false;设置为true之后,mr运行时会根据bucket的个数自动分配reduce task个数。(用户也可以通过mapred.reduce.tasks自己设置reduce任务个数,但分桶时不推荐使用)
注意:一次作业产生的桶(文件数量)和reduce task个数一致。

  1. 创建分桶表

CREATE TABLE tb_name( id INT, name STRING, age INT)
CLUSTERED BY (age) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

  1. 加载数据:

insert into table tb_name select id, name, age from source_tb_name;

  1. 抽样

select id, name, age from tb_name tablesample(bucket 1 out of 2 on age);
一共4个桶,抽取2(4/2)个bucket的数据,抽取第1、第3(1+2)个bucket的数据

  1. SMB Join
    对于一些大表 join 大表 的场景,
    采用分桶表会有比较好的表现效果,
    当然这里两个表都要按照同一个规则进行分桶。

Beeline 和 HIveServer2

  • beeline 要与 HIveServer2 配合使用
  • 服务端启动 HIveServer2
  • 客户端可以通过beeline -u jdbc:hive2://hostname:10000/db_name -n username 进行hive的连接
  • HiveServer2的另外一个功能,就是提供给开发者一个jdbc的开发接口,
    可以通过hive驱动,像访问 mysql 一样访问 Hive
  • HiveServer2 相比 Hive MetaServer 是很好的隐藏了客户端,这一点亲手配置过 Hive 的同学可能比较能够理解,因为 beeline 其实是不需要任何配置的,连上 hiveserver2 就能用,但是 Hive MetaServer 是需要你自己配置 Hive客户端的。并且高可用的配置只能基于 HiveServer2

Hive 函数

  • UDTF:一进多出函数,对于某个数据经过函数会产生多条记录,eg: explode
  • UDF:一进一出函数,对于一个数据经过函数处理,还是一条数据 eg: to_date
  • UDAF:多进一出函数,多条数据经过函数处理会聚合成一条数据 eg: count
  • 这块内容其实挺多的,但是官网都有详细的文档,所以下面只是简单的给出官网链接,偷懒一把!!!嘿嘿
  • 自定义 UDF
    1. UDF
    2. UDTF
    3. UDAF
    4. 创建永久和临时函数
    CREATE FUNCTION [db_name.] function_name AS class_name 
    [USING JAR|FILE|ARCHIVE 'file_uri' [, JAR|FILE|ARCHIVE 'file_uri'] ];
    

Hive 索引

  • 目的:优化查询以及检索性能
  1. 创建索引:

create index t1_index on table tb_name1(name)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler' with deferred rebuild
in table t1_index_table;
as:指定索引器;
in table:指定索引表,若不指定默认生成在default__psn2_t1_index__表中

  1. 查询索引
    show index on tb_name1;

  2. 重建索引(建立索引之后必须重建索引才能生效)
    ALTER INDEX t1_index ON tb_name1 REBUILD;

  3. 删除索引
    DROP INDEX IF EXISTS t1_index ON tb_name1;

5.使用的时候根据索引条件查询能加快查询速度,但是由于索引表也是需要维护的,会带来额外开销。

  1. 实际上,hive作为数据仓库,其实索引的使用还是比较少的,反正我是没怎么使用过。。。

数据倾斜

  • 什么时数据倾斜?什么导致的数据倾斜?
  1. 一般来说,在分布式计算系统中,我们期望的每个节点完成任务的时间是一致的,
    但是实际生产环境中,因为种种原因会导致某些节点处理的数据较大,
    导致完成任务时间与其他节点相差很大,
    以至于整个任务完成时间过长,这就是我们常说的数据倾斜

  2. 一般来说,导致数据倾斜的原因都是因为数据分布的不均匀导致的,
    而 Hive 因为底层是通过 MR 实现的,
    所以数据倾斜一般都是发生在 Reduce 端,
    而 Reduce 端处理的数据是由我们的 Partition 决定的,
    这就为我们寻找数据倾斜的原因提供了一个最基本的思路。

当我们使用一些类似于 group by , join 等会产生 shuffle 语法的时候,
默认的 partition 方式都是通过 key 来决定的,
所以一般导致数据倾斜的原因都是 key 的分布不均匀。

  • 数据倾斜解决方案

    1. Hive自带的数据倾斜解决方案,主要是针对 group by ;

    a. 设置参数 :set hive.map.aggr=true ,开启 map 端的聚合功能,也就是 MR 程序中写的 combiner

    1. hive.groupby.mapaggr.checkinterval:
      map端group by执行聚合时处理的多少行数据(默认:100000),
    2. hive.map.aggr.hash.min.reduction:
      进行聚合的最小比例(预先对100000条数据做聚合,若 (聚合之后的数据量)/100000 的值大于该配置设 置值0.5,则不会聚合)
    3. hive.map.aggr.hash.percentmemory:
      map端聚合使用的内存的最大值
    4. hive.map.aggr.hash.force.flush.memory.threshold:
      map端做聚合操作是hash表的最大可用内容,大于该值则会触发flush

    b. 设置 set hive.groupby.skewindata=true ,开启Group By 产生数据倾斜优化

    该处理方式是将一次group 操作进行了两次处理,
    首先会对map端输入的数据进行随机分发给reduce端,
    因为是随机的,所以数据会均匀分发给reduce 进行 group ,
    然后对第一次group处理的数据再进行一次正常的 group操作,
    因为有了第一次的处理,第二次处理的数据将会大大减少
    从而使得数据倾斜问题不再明显。
    严格来说,这并没有解决数据倾斜问题,
    但是却大大减少了数据倾斜带来的影响

    1. Join 产生的数据倾斜
      a. Map端进行join:适合小表 join 大表的情况
    1. 通过修改以下配置启用自动的mapjoin:
      set hive.auto.convert.join = true;
      (该参数为true时,Hive自动对左边的表统计量,如果是小表就加入内存,即对小表使用Map join)
    2. hive.mapjoin.smalltable.filesize;
      (大表小表判断的阈值,如果表的大小小于该值则会被加载到内存中运行)
    3. hive.ignore.mapjoin.hint;
      (默认值:true;是否忽略mapjoin hint 即HQL 语句中的 mapjoin 标记)
    4. hive.auto.convert.join.noconditionaltask;
      (默认值:true;将普通的join转化为普通的mapjoin时,是否将多个mapjoin转化为一个mapjoin)
    5. hive.auto.convert.join.noconditionaltask.size;
      (将多个mapjoin转化为一个mapjoin时,其表的最大值)

    b. 对于两张都是大表的情况,
    我们可以想办法将一个大表转化为小表,然后采用 a 方案;
    另外我们也可以使用分桶的思想,来加快join;
    我们还可以根据业务,来避免这类问题,
    比如:找到导致数据倾斜的 key 过滤出来额外处理。
    很多时候,这个导致倾斜的 key 可能是一个脏数据,那么直接过滤就好了
    其中 数据倾斜解决方案 这上面的一些方案也可以参考,

HIve 优化

谈起优化,上面很大一部分内容都有涉及,这里我们主要谈谈 HQL 优化

  1. 某些容易导致数据倾斜的函数
  • count(distinct *)
    该用法在MR 的 reduce 阶段只有一个 reduce 来处理,当数据量较大会导致严重的数据倾斜。
    可以通过
    select count(1) from (select distinct(uid) d_uid from t)
    来优化

  • order by key
    对于全局排序也有上面类似的问题
    为了解决上面的问题,我们需要先了解下hive的几种排序

    • order by:全局排序,一般不用,因为其为了全局有序,
      将数据放到一个reduce里面处理,效率比较低
    • cluster by:全局排序,建议使用,但是只能是降序,不能指定asc和desc
    • sort by:局部排序,这个局部就是每个 reduce 内部,
      所以不能保证全局有序,
      单个使用意义不大,需要结合 distribute by一起使用
    • distribute by:分区排序,
      在分发数据给 reduce 的时候保证 reduce 是有序的,
      结合 sort by
      可以做到全局有序

    所以上面这个问题可以通过
    select a,b,c from t distribute by a sort by a asc, b desc
    来解决

  1. Union All insert
//union all
insert overwrite table t
select a,b,c   
from t1      
union all   
select a,b,c from t2

//普通方式
insert overwrite table t
select a,b,c  from t1
insert overwrite table t
select a,b,c  from t2
  1. limit
    limit 限制,对于hive 很多时候都是需要进行全表统计,然后显示 limit 限制的条数的记录,对于执行速度并没有多大的提升,如果我们的需求是可以通过抽样来看整体情况的,那么全表扫描无疑是很浪费资源的,所以hive也是提供了相应的优化机制,来允许我们采用抽样使用 limit
    hive.limit.optimize.enable=true --- 开启对数据源进行采样的功能
    hive.limit.row.max.size --- 设置最小的采样容量
    hive.limit.optimize.limit.file --- 设置最大的采样样本数

  2. join
    上文说了不少join的优化,这里补充一点:
    多个join 相互关联,尽可能的使用相同的 key 进行关联,
    这样就 Hive 就只会使用一个 Maper 去操作

  1. 本地执行
    当我们觉得有些任务是杀鸡用牛到的时候,
    可以尝试运用本地运行,
    分布式计算只有再数据量足够大的时候才能体现其优势,
    否则单机是更快的。
    通过 mapred.job.tracker=true 参数开启本地模式
    当然,hive 也提供了自动开启本地模式的优化机制
    通过 hive.exec.mode.local.auto开启自动执行,自动开启的条件如下:
    1.job的输入数据量小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB)
    2.job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4)
    3.job的reduce数必须为0或者1
  2. stage 并行执行
    对于一些复杂的 hql 可能会需要多个 stage 一起执行来完成,默认情况下,hive 是根据其解析的计划串行执行一个个 stage 的,为了提高执行速度,我们可以开启 stage 并行执行。
    通过 hive.exec.parallel=true开启

stage 是什么? hive 将sql 解析后自动生成的一个抽象概念,比如我们要做饭,那么这个 stage 就可以理解为:1.买菜买米,2.煮饭,3.炒菜,4.上桌。如果开启了并行执行那么,煮饭 和 炒菜 就可以一起执行了,当然前提是你要忙的过来,所以集群资源要足够才行,如果没开启,那么就傻傻的 先煮饭,饭熟了,再炒菜

  1. JVM 重用
    这里JVM 重用是针对 hive 底层的执行引擎 MR 来说的,默认的一个 task 启动一个 jvm 进程来执行。
    通过mapred.job.reuse.jvm.num.tasks=1 可以设置每个JVM 执行的 task 数量

为什么默认值是1 ?
因为如果JVM设置的task数量超过1,那么这个JVM只有等待其执行完自己指定的任务,或者整个 job执行完成才会退出释放资源。
我们可以来假设一下,我们有 6 个task分别是 1,2,3,4,5,6。对应执行的JVM 是 1到6 号,其中 1 需要1min 执行完,其余的都是1s执行完,如果一个jvm执行完一个任务就退出,那么可能在 2s 到 3s 的时候,就只有 1号JVM 占用资源了,而如果不是,2到6号 在 2-3s 执行完毕,但是因为有重用功能,会导致这几个 JVM 继续等待其他任务的派发,直到 1号JVM 执行完毕才会释放 ,导致资源的浪费。
所以才资源不是很充足的情况下,该功能还是要慎用噢~!

  1. 控制 Map 和 Reduce 数量
    可以参考这篇文章

这里啰嗦一下,reduce的数量可能需要根据你自己的业务来设置一下,
没什么可说,但是 Map 一般都不会需要自己设置和优化,
因为默认一个 Map就是对应 hdfs 上的一个 block,
当hdfs block设置合理,并且小文件很少的情况,
那么 Map 一般也还算合理并不会有多大影响。

Hive Shell

hive shell 就和 mysql shell 差不多的使用方式,
支持 repl 的方式进行数据查询,
这里我们主要来说明两个特殊的使用

  • 支持 Hadoop 命令:
    hive shell 是支持 hadoop 的相关操作的,比如:hive> dfs -ls /
  • 支持 Linux 命令:
    hive shell 是支持 Linux 的相关操作的,前面加上!就 ok 了,比如:hive> !ls /

远程调试

通过 hive --debug port=9999 来开启远程调,关于java 远程调试可以参考其他文章

小文件合并

可以参考:https://blog.csdn.net/yycdaizi/article/details/43341239

数据仓库建模

其他小知识点

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容