美文网首页
离线处理之Hive入门基础

离线处理之Hive入门基础

作者: 机器不能学习 | 来源:发表于2018-11-07 16:47 被阅读0次

    改了一万个BUG,才开始HIVE之旅。且行且珍惜。

    HIVE是Facebook开发贡献给Hadoop开源社区的。
    他可以无基础帮助OLAP分析人员使用简单的sql语句进行数据分析。它的原理也很简单,hivesql先被sql解析其解析,生产个一个可执行的mr计划,最后交给hadoop处理。
    hadoop是批量处理,所以hive也是高延迟的。它不提供数据的排序和查询缓冲,以及在线事务和记录级跟新。

    hive主要构架:
    Driver组建:核心组件,有编译器 优化器 执行器,能将sql变为rm任务。
    MetaStore:元数据。hive的元数据都存储在这里面。一般元数据都存储在关系数据库中,最常用的是msql,还有Derby。但后者只适合简单的测试
    CLI:命令行接口,其负责类是hive-cli中的CliDriver
    Thrift Server:提供JDBC接口,可以进行可扩展且跨语言的服务
    HIVE WEB INTERFACE(HWI):简单说就是可操作的ui界面

    我觉得hwi是最方便好用的。
    配置hwi也简单介绍一下:
    1.下载src包,我们下载的hive都是bin包。最好下载对应版本的src包,还有一个需要注意的是,最好用1..版本的。2以上版本的的hive/lib里没有hwi.jar(个人测试结果)。
    将src中的web文件里所有文件打包为一个war包,并对hive-site.xml进行hwi配置。
    2.下载ant,并进行配置
    3.依赖包,依赖包有来自ant的,有来自tomacat的,有来自java的tools.

    DDL操作

    表的创建主要分为了内部表创建和外部表创建
    内部表是存储的具体数据,每次加载数据时,是将整个文件拉取,删除该表数据也会被删除。
    外部表存储的是一个外部引用,所以也就不存在删除源文件。

    创建表的注意点:
    1.参数的先后,比如创建外部表是,LOCATION是最后的参数,如果你放在中间肯定会报EOF miss的错误。顺序为,表(字段) 分区 分桶(排序) 规则 类型 Location
    2.path的范围,一般导入的文件path=hdfs:///localhost:9000/user/root+'path',就是说它的前缀是已经指定好的。这个参数也可以配置。而LOCATION的path则没有前缀的。如目录在hdfs:///localhost:9000/user/external需要写/user/external.
    3.文件格式和数据规则必写。因为你load进入的数据的格式如果不被识别,那么就将全部是null。FIELDS TERMINATED BY ' ' LINES TERMINATED BY '\n' 。意思是列与列的数据用' '隔开,每行数据用/n隔开。

    修改表
    改名
    ALTER TABLE old_name RENAME TO new_name
    增加列
    ALTER TABLE table_name ADD COLUMNS (new_col INT COMMENT '注意有引号')
    改变表属性
    ALTER TABLE table_name SET FILEFORMAT TEXTFILE(改变存储方式)
    ALTER TABLE table_name SET serdeproperties('field.delim'='\t')(改变了分割方式)
    alter table table_name set tblproperties('EXTERNAL'='TRUE')(内部表转外部表)

    分区操作
    增加分区
    ALTER TABLE table_name ADD PARTITION (name=value)
    如果这个表本来没有这个name字段的分区:会报错ValidationFailureSemanticException table is not partitioned but partition spec exists: {id=1}
    大意是这不是一个分区表,所以说在建表的时候就要确认这个分区表,才可以在后续进行增加分区的操作
    ALTER TABLE table_name DROP PARTITION (name=value)(删除一个分区)

    删除表
    DROP TABLE table_name
    TRUNCATE TABLE my_table(只删除表中数据,不改变表结构)
    truncate不能删除外部表,因为外部表的数据不是存放在Meta Store中

    DML操作

    想数据表导入数据
    LOAD DATA [LOCAL] INPATH ' ' [OVERWRITE] INTO table_name
    如果是在hdfs里的文件,则不需要local。 overwrite into是覆盖表分区,仅仅是这个分区的数据内容,如果是追加,则不需要overwrite。
    hive 会把该目录下的该文件移动到表中,如果文件名产生冲突会用新的文件代替久的文件。

    将查询结果插入
    INSERT OVERWRITE TABLE table_name [partition] SELECT ....
    可以将后续的查询结果插入表或者是表的分区里。overwrite会强制写入,其中的输出格式和序列化方式由表的元数据决定。同时我们也可以使用多表插入,可以减少扫描的次数。

    将查询结果写入文件系统
    INSERT OVERWRITE [LOCAL] DIRECTORY dir SELECT...
    dir可以是全路径,如果没有定义scheme或者authority那么hive会使用hadoop配置的fs.default.name来定义。比如我的默认dir前缀就是hdfs://localhost:9000/user/root

    sql操作
    SELECT WHERE 和sql语句没有大区别
    如select * from user where id=1

    重复项处理
    在默认的select name from user中,返回的name是all也就是包括所有(包含了重复的项)
    如果想过滤掉这些项,用select distinct name from user

    使用正则
    https://www.cnblogs.com/Allen-rg/p/9323506.html
    使用正则可以过滤数据。

    基于分区查询
    select * from table_name where table_name.partition<100
    这里的table_name表加入是按partition分区的,那么这里就不会进行全局扫描,而是找出满足条件的分区,再进行查询

    聚合
    Group by 该函数可以产生聚合操作,
    如select name from user group by name.
    这个操作会按name进行分组,但这个过程中,可能其他列的值会变为多值,如name=张三的有两个,那么name这一行对应的id列就有两个值了,对于关系数据库这是不可以的。这是必须对id进行操作,使之变为一个值才行。如max,count等操作。

    join操作
    一图以蔽之


    1367194228.jpg
    分区,分桶

    将表划分为分区,partition会根据分区字段进行分区。分区可以让数据的部分查询更快。表或者分区可以进一个进行分桶,捅通常在原始数据中加入额外的数据结构,使得高效查询。例如用户可以增加ID桶。

    分区可以是时间或者时间戳,在查询时带上这个时间查询,当然就不会全局扫描(是不是和mysql的索引很像呢)。分区也可以进行多维度分区,这样就可以建立一个目录级关系。如天时间和时刻进行分区。总目录下是天,天下面是时刻.
    动态分区开启:
    set hive.exec.dynamic.partition=true;
    set hive.exec.dynamic.partition.mode=nonstrict;
    默认值:strict
    描述:strict是避免全分区字段是动态的,必须有至少一个分区字段是指定有值的避免产生大量分区

    使用分桶的原因是为了高效查询和高效抽样。指定字段会根据hash后取余数,来决定进入哪个桶。在map-side关联中,两边桶不必相同,成倍数即可。系统也给了一个hive.enforce.bucketing=true的方式,将分桶交给hive.set hive.enforce.sorting=true;开启强制排序,插数据到表中会进行强制排序,默认false;

    我们发现其实桶的概念就是MapReduce的分区的概念,两者完全相同。物理上每个桶就是目录里的一个文件,一个作业产生的桶(输出文件)数量和reduce任务个数相同。
    而分区表的概念,则是新的概念。分区代表了数据的仓库,也就是文件夹目录。每个文件夹下面可以放不同的数据文件。通过文件夹可以查询里面存放的文件。但文件夹本身和数据的内容毫无关系。
    桶则是按照数据内容的某个值进行分桶,把一个大文件散列称为一个个小文件。
    这些小文件可以单独排序。如果另外一个表也按照同样的规则分成了一个个小文件。两个表join的时候,就不必要扫描整个表,只需要匹配相同分桶的数据即可。效率当然大大提升。
    同样,对数据抽样的时候,也不需要扫描整个文件。只需要对每个分区按照相同规则抽取一部分数据即可。

    相关文章

      网友评论

          本文标题:离线处理之Hive入门基础

          本文链接:https://www.haomeiwen.com/subject/ahyvxqtx.html