YongSir

专业程序员伪装者

Hive初探

Hive 初探

在hadoop生态,最重要的无疑是HDFS 和 MapReduce/Spark等运算框架,但依托于HDFS的数据库存储层工具往往是平时用到的最多的,当前2大依托于HDFS的结构化数据存储有:HBaseHive

这篇文章就来说说Hive的方方面面。

虽然Hive是hadoop生态中的一个数据结构化管理层,但要注意的是,不同于mySQL等数据库,也根Hbase不同,hive本身被设计的目的就不在于其实时查询,因此它的查询是一个耗时的过程,但他可以支持类SQL语言,可以让job不再要求我们一行一行的写代码,会根据语句自动生成MapReduce代码,从而简化操作。总之,Hive提供给我们HQL,让我们方便的MapReduce,最终用以对hdfs上数据的提取/转化/加载(ETL),对映射到数据库表中的数据进行方便的操作,其提供了3种用户接口:

  • CLI: 根mySQL的命令基本相同
  • WebUI: 默认端口9999
  • Client:通过JDBC等来远程访问

构架

借用hive - facebook爸爸的构架图:
来自facebook爸爸的hive构架图

安装及错误处理

作为Hadoop组建,安装起来很简单,关键在于配置,通常都使用mySQL存储metaStore,所以在设置中:

在安装时注意版本对应,确保各个节点机器的ssh通信正常,会省去不少麻烦
启动时需注意保证集群启动正常,一个常见的错误:
留待图片
就是因为namenode为启动成功,在hadoop生态,几乎所有的组件都是依赖与hdfs,yarn的,然后配合zookeeper热备,一旦出现启动不了的问题,首先就要去检查依赖的运行环境是否启动正常

基本操作相关

1 表的创建相关

  • 创建表基本上根普通的SQL语句一致,只是我们常常需要指定分割符号,指定排序,存储类型等等,常见的通用模型如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name [LIKE] patternTable
    [(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]

关键字ROW FORMAT DELIMITED:

1
2
3
4
FIELDS TERMINATED BY ‘,’           //指定每行中字段分隔符为逗号
LINES TERMINATED BY ‘\n’ //指定行分隔符
COLLECTION ITEMS TERMINATED BY ‘,’ //指定集合中元素之间的分隔符
MAP KEYS TERMINATED BY ‘:’ //指定数据中Map类型的Key与Value之间的分隔符

关键字PARTITIONED BY: 就是对应于mapreduce中的分区

关键字CLUSTERED BY: 称之为分桶

关键字STORED AS:指定表在HDFS上的文件存储格式,可选的文件存储格式有:

1
2
3
4
5
TEXTFILE 		//文本,默认值
SEQUENCEFILE // 二进制序列文件
RCFILE //列式存储格式文件 Hive0.6以后开始支持
ORC //列式存储格式文件,比RCFILE有更高的压缩比和读写效率,Hive0.11以后开始支持
PARQUET //列出存储格式文件,Hive0.13以后开始支持

一个具体的🌰,eg:

1
2
3
4
5
CREATE TABLE IF NOT EXISTS tableDemo 
(sno INT,sname STRING,age INT,sex STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;

上述创建了一个行分割符号为tab的表tableDemo,使用show tables;可查看

  • 删除– DROP
  • 修改表结构用ALTER TABLE tableName [ADD COLUMNS][RENAME TO xxx]等

2 数据操作

  • 加载数据

    1
    2
    LOAD DATA LOCAL INPATH '$local_Dir/xxxx.txt' INTO TABLE tableName; -- 加载本地数据
    LOAD DATA INPATH '$hdfs_dataDir/xxxx.txt' INTO TABLE tableName; -- 加载hdfs数据

    说明:这里只是总结操作,具体概念后文详述

    • 加载数据到分区,eg:

      1
      2
      3
      4
      LOAD DATA LOCAL INPATH
      '$loacl_dir/data.txt`
      overwrite INTO TABLE tableName
      PARTITION (dt='part001')
    • 加载数据到桶表:
      首先要开启桶:set hive.enforce.bucketing = true,eg:

      1
      2
      3
      INSERT OVERWRITE TABLE tb_bucket_shop 
      SELECT shop_id, shop_name, shopkeeper FROM tb_part_shop
      CLUSTER BY shop_id;
  • 插入操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- 单表插入
    INSERT OVERRITE TABLE copied_table
    SELECT * FROM meta_table
    -- 多表插入
    FROM meta_table
    INSERT OVERRITE TABLE copied_table1
    SELECT *
    INSERT OVERRITE TABLE copied_table2
    SELECT *
  • 查询操作
    通用格式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT [DISTINCT] col_name 
    LIMIT num
    FROM table1 [table2 ...]
    [ORDER BY col_name]
    [GROUP BY col_name]
    [SORT BY col_name]
    [DISTRIBUTE BY func(col_name)]
    [CLUSTER BY col_name]
    [WHERE col_name OPERATOR [AND OPERATOR...] ]
    • GROUP BY: 分组
    • ORDER BY: 全局排序
      Hive优化常常要用到,不同于数据库的order,使 时需要指定hive.mapred.mode:

      1
      2
      hive.mapred.mode = nonstrict; // 默认
      hive.mapred.mode = strict; // 必须指 limit
    • SORT BY: 分区内排序并可以指定task数
      如task=1,那么效果等同于ORDER BY, 指定Reduc 个数:set mapred.reduce.tasks=num

    • DISTRIBUTE BY和CLUSTER BY
      distribute by:按照指定的字段或表达式对数据进行划分,输出到对应的Reduce或者文件中。
      cluster by:除了兼具distribute by的功能,还兼具sort by的排序功能。