hive_hive sql - CSDN
hive 订阅
hive是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。hive数据仓库工具能将结构化的数据文件映射为一张数据库表,并提供SQL查询功能,能将SQL语句转变成MapReduce任务来执行。Hive的优点是学习成本低,可以通过类似SQL语句实现快速MapReduce统计,使MapReduce变得更加简单,而不必开发专门的MapReduce应用程序。hive十分适合对数据仓库进行统计分析。 [1] 展开全文
hive是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。hive数据仓库工具能将结构化的数据文件映射为一张数据库表,并提供SQL查询功能,能将SQL语句转变成MapReduce任务来执行。Hive的优点是学习成本低,可以通过类似SQL语句实现快速MapReduce统计,使MapReduce变得更加简单,而不必开发专门的MapReduce应用程序。hive十分适合对数据仓库进行统计分析。 [1]
信息
外文名
hive
兼容性
hadoop生态圈
定    义
在Hadoop上的数据仓库基础构架
依    赖
jdk,hadoop
所属学科
大数据、数据分析
hive简介
hive是基于Hadoop构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop分布式文件系统中的数据:可以将结构化的数据文件映射为一张数据库表,并提供完整的SQL查询功能;可以将SQL语句转换为MapReduce任务运行,通过自己的SQL查询分析需要的内容,这套SQL简称Hive SQL,使不熟悉mapreduce的用户可以很方便地利用SQL语言‘查询、汇总和分析数据。而mapreduce开发人员可以把自己写的mapper和reducer作为插件来支持hive做更复杂的数据分析。它与关系型数据库的SQL略有不同,但支持了绝大多数的语句如DDL、DML以及常见的聚合函数、连接查询、条件查询。它还提供了一系列的1:具进行数据提取转化加载,用来存储、查询和分析存储在Hadoop中的大规模数据集,并支持UDF(User-Defined Function)、UDAF(User-Defnes AggregateFunction)和USTF(User-Defined Table-Generating Function),也可以实现对map和reduce函数的定制,为数据操作提供了良好的伸缩性和可扩展性。 [2]  hive不适合用于联机(online)事务处理,也不提供实时查询功能。它最适合应用在基于大量不可变数据的批处理作业。hive的特点包括:可伸缩(在Hadoop的集群上动态添加设备)、可扩展、容错、输入格式的松散耦合。 [2] 
收起全文
精华内容
参与话题
  • 大数据之Hive

    千人学习 2018-10-22 21:38:14
    hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句实现简单的...
  • HIVE 从入门到精通

    2020-07-30 23:33:23
    HIVE从入门到精通,Hive是基于Hadoop(HDFS, MapReduce)的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。本质是将SQL转换为MapReduce程序。
  • Hive详细介绍及简单应用

    万次阅读 多人点赞 2018-05-24 13:54:47
    1. Hive基本概念1.1 Hive简介1.1.1 什么是HiveHive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。1.1.2 为什么使用Hive1.) 直接使用hadoop所面临的问题 ...

    1. Hive基本概念

    1.1  Hive简介

    1.1.1 什么是Hive

    Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。

    1.1.2 为什么使用Hive

    1.) 直接使用hadoop所面临的问题

    人员学习成本太高

    项目周期要求太短

    MapReduce实现复杂查询逻辑开发难度太大

    2.)

    操作接口采用类SQL语法,提供快速开发的能力。

    避免了去写MapReduce,减少开发人员的学习成本。

    扩展功能很方便。

    1.1.3 Hive的特点

    1.)可扩展

    Hive可以自由的扩展集群的规模,一般情况下不需要重启服务。

    2.)延展性

    Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。

    3.)容错

    良好的容错性,节点出现问题SQL仍可完成执行。

    1.2  Hive架构

    1.2.1 架构图

     

    Jobtracker是hadoop1.x中的组件,它的功能相当于: Resourcemanager+AppMaster

    TaskTracker 相当于:  Nodemanager  +  yarnchild

    1.2.2 基本组成

    1.) 用户接口包括 CLI、JDBC/ODBC、WebGUI。

    2.) 元数据存储通常是存储在关系数据库如 mysql , derby

    3.) 解释器、编译器、优化器、执行器

    1.2.3 各组件的基本功能

    1.) 用户接口主要由三个:CLI、JDBC/ODBC和WebGUI。其中,CLIshell命令行;JDBC/ODBCHiveJAVA实现,与传统数据库JDBC类似;WebGUI是通过浏览器访问Hive

    2.)元数据存储:Hive 将元数据存储在数据库中。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等

    3.)解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行

    1.3 Hive与Hadoop的关系 

    Hive利用HDFS存储数据,利用MapReduce查询数据

     

    1.4 Hive与传统数据库对比


    总结hive具有sql数据库的外表但应用场景完全不同hive只适合用来做批量数据统计分析

    1.5 Hive的数据存储

    1Hive中所有的数据都存储在 HDFS 没有专门的数据存储格式(可支持TextSequenceFileParquetFileRCFILE等)

    2只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据。

    3Hive 中包含以下数据模型:DBTableExternal TablePartitionBucket

         db:在hdfs中表现为${hive.metastore.warehouse.dir}目录下一个文件夹

        table:在hdfs中表现所属db目录下一个文件夹

        external table外部表, table类似,不过其数据存放位置可以在任意指定路径

    普通表: 删除表后, hdfs上的文件都删了

    External外部表删除后, hdfs上的文件没有删除, 只是把文件删除了

        partition:在hdfs中表现为table目录下的子目录

        bucket, hdfs中表现为同一个表目录下根据hash散列之后的多个文件, 会根据不同的文件把数据放到不同的文件中


    1.6 HIVE的安装部署

    1.6.1 安装

    单机版:

    元数据库mysql版:

    安装过程略,下载好后解压即可,感兴趣的朋友可以直接下载我配置好的hive,运行在centos7.4下完美运行,下载页:

    https://download.csdn.net/download/l1212xiao/10434728

    1.6.2 使用方式

    Hive交互shell

    bin/hive

    Hive thrift服务

     

    启动方式,(假如是在hadoop01上):

    启动为前台:bin/hiveserver2

    启动为后台:nohup bin/hiveserver2 1>/var/log/hiveserver.log 2>/var/log/hiveserver.err &

    启动成功后,可以在别的节点上用beeline去连接

    方式(1

    hive/bin/beeline  回车,进入beeline的命令界面

    输入命令连接hiveserver2

    beeline> !connect jdbc:hive2//mini1:10000

    hadoop01hiveserver2所启动的那台主机名,端口默认是10000

    方式(2

    或者启动就连接:

    bin/beeline -u jdbc:hive2://hadoop01:10000 -n hadoop

    接下来就可以做正常sql查询了

    Hive命令

    [hadoop@hdp-node-02 ~]$ hive  -e  ‘sql’

    2. Hive基本操作

    2.1  DDL操作

    2.1.1 创建表

    建表语法

    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]

    说明:

    1、 CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXISTS 选项来忽略这个异常

    2、 EXTERNAL关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。

    3、 LIKE 允许用户复制现有的表结构,但是不复制数据。

    4、 ROW FORMAT

    DELIMITED [FIELDS TERMINATED BY char] [COLLECTION ITEMS TERMINATED BY char]

            [MAP KEYS TERMINATED BY char] [LINES TERMINATED BY char]

       | SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value, property_name=property_value, ...)]

    用户在建表的时候可以自定义 SerDe 或者使用自带的 SerDe。如果没有指定 ROW FORMAT 或者 ROW FORMAT DELIMITED,将会使用自带的 SerDe。在建表的时候,用户还需要为表指定列,用户在指定表的列的同时也会指定自定义的 SerDe,Hive通过 SerDe 确定表的具体的列的数据。

    5、 STORED AS

    SEQUENCEFILE|TEXTFILE|RCFILE

    如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。

    6、CLUSTERED BY

    对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。

    把表(或者分区)组织成桶(Bucket)有两个理由:

    1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。

    2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

    具体实例

    1、 创建内部表mytable

    hive> create table if not exists mytable(sid int,sname string)
        > row format delimited fields terminated by ',' stored as textfile;

    示例, 显示如下:


    2、 创建外部表pageview

     hive> create external table if not exists pageview(
        > pageid int,
        > page_url string comment 'The page URL'
        > )
        > row format delimited fields terminated by ','
        > location 'hdfs://192.168.158.171:9000/user/hivewarehouse/';


    3、 创建分区表invites

    hive> create table student_p(
        > Sno int,
        > Sname string,
        > Sex string,
        > Sage int,
        > Sdept string) 
        > partitioned by(part string) 
        > row format delimited fields terminated by ','stored as textfile;

    4、 创建带桶的表student

     hive> create table student(id int,age int,name string)
        > partitioned by(stat_data string)
        > clustered by(id) sorted by(age) into 2 buckets
        > row format delimited fields terminated by ',';

    2.1.2 修改表

    增加/删除分区

    语法结构

    ALTER TABLE table_name ADD [IF NOT EXISTS] partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...

    partition_spec:

    : PARTITION (partition_col = partition_col_value, partition_col = partiton_col_value, ...)

    ALTER TABLE table_name DROP partition_spec, partition_spec,...

    具体实例

    alter table student_p add partition(part='a') partition(part='b');


    重命名表

    语法结构

    ALTER TABLE table_name RENAME TO new_table_name

    具体实例

     hive> alter table student rename to student1;


    增加/更新列

    语法结构

    ALTER TABLE table_name ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)

    注:ADD是代表新增一字段,字段位置在所有列后面(partition列前)REPLACE则是表示替换表中所有字段。

    ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENT col_comment] [FIRST|AFTER column_name]

    具体实例



     

    2.1.3 显示命令

    show tables

    show databases

    show partitions

    show functions

    desc extended t_name;

    desc formatted table_name;

    2.2  DML操作

    2.2.1 Load

     语法结构

    LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO

    TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]

    说明:

    1、 Load 操作只是单纯的复制/移动操作,将数据文件移动到 Hive 表对应的位置。

    2、 filepath

    相对路径,例如:project/data1

    绝对路径,例如:/user/hive/project/data1

    包含模式的完整 URI,列如:

    hdfs://namenode:9000/user/hive/project/data1

    3、 LOCAL关键字

    如果指定了 LOCALload 命令会去查找本地文件系统中的 filepath

    如果没有指定 LOCAL 关键字,则根据inpath中的uri查找文件

    4、 OVERWRITE 关键字

    如果使用了 OVERWRITE 关键字,则目标表(或者分区)中的内容会被删除,然后再将 filepath 指向的文件/目录中的内容添加到表/分区中。

    如果目标表(分区)已经有一个文件,并且文件名和 filepath 中的文件名冲突,那么现有的文件会被新文件所替代。

     具体实例

    1、 加载相对路径数据。

    hive> load data local inpath 'sc.txt' overwrite into table sc;

    2、 加载绝对路径数据。

      hive> load data local inpath '/home/hadoop/hivedata/students.txt' overwrite into table student;

    3、 加载包含模式数据。

     hive> load data inpath 'hdfs://mini1:9000/hivedata/course.txt' overwrite into table course;

    4、 OVERWRITE关键字使用。

     如上

    2.2.2 Insert

     将查询结果插入Hive

    语法结构

    INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement

    Multiple inserts:

    FROM from_statement

    INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1

    [INSERT OVERWRITE TABLE tablename2 [PARTITION ...] select_statement2] ...

    Dynamic partition inserts:

    INSERT OVERWRITE TABLE tablename PARTITION (partcol1[=val1], partcol2[=val2] ...) select_statement FROM from_statement

     具体实例

    1、基本模式插入。

    2、多插入模式。

    3、自动分区模式。

    导出表数据

    语法结构

    INSERT OVERWRITE [LOCAL] DIRECTORY directory1 SELECT ... FROM ...

    multiple inserts:

    FROM from_statement

    INSERT OVERWRITE [LOCAL] DIRECTORY directory1 select_statement1

    [INSERT OVERWRITE [LOCAL] DIRECTORY directory2 select_statement2] ...

    具体实例

    1、导出文件到本地。

     hive> insert overwrite local directory '/home/hadoop/hivedata/outdata'
        > select * from student;


    说明:

    数据写入到文件系统时进行文本序列化,且每列用^A来区分,\n为换行符。用more命令查看时不容易看出分割符,

    可以使用: sed -e 's/\x01/|/g' filename来查看。

    如:sed -e 's/\x01/,/g' 000000_0

    2、导出数据到HDFS

     hive> insert overwrite directory 'hdfs://mini1:9000/hivedata/outdatasc'
        > select * from sc;


    2.2.3 SELECT

     基本的Select操作

    语法结构

    SELECT [ALL | DISTINCT] select_expr, select_expr, ...

    FROM table_reference

    [WHERE where_condition]

    [GROUP BY col_list [HAVING condition]]

    [CLUSTER BY col_list

      | [DISTRIBUTE BY col_list] [SORT BY| ORDER BY col_list]

    ]

    [LIMIT number]

    注:1order by 会对输入做全局排序,因此只有一个reducer,会导致当输入规模较大时,需要较长的计算时间。

    2sort by不是全局排序,其在数据进入reducer前完成排序。因此,如果用sort by进行排序,并且设置mapred.reduce.tasks>1,则sort by只保证每个reducer的输出有序,不保证全局有序。

    3distribute by根据distribute by指定的内容将数据分到同一个reducer

    4Cluster by 除了具有Distribute by的功能外,还会对该字段进行排序。因此,常常认为cluster by = distribute by + sort by

     

    具体实例

    1、获取年龄大的3个学生。

     hive> select sno,sname,sage from student order by sage desc limit 3;


    2、查询学生信息按年龄,降序排序。

     hive> select sno,sname,sage from student sort by sage desc;

    hive> select sno,sname,sage from student order by sage desc;

    hive> select sno,sname,sage from student distribute by sage;

    3、按学生名称汇总学生年龄。

     hive> select sname,sum(sage) from student group by sname;

    2.3 Hive Join

     语法结构

    join_table:

      table_reference JOIN table_factor [join_condition]

      | table_reference {LEFT|RIGHT|FULL} [OUTER] JOIN table_reference join_condition

      | table_reference LEFT SEMI JOIN table_reference join_condition

    Hive 支持等值连接(equality joins)、外连接(outer joins)和(left/right joins)。Hive 不支持非等值的连接(后续版本已经支持),因为非等值连接非常难转化到 map/reduce 任务。

    另外,Hive 支持多于 2 个表的连接。

    join 查询时,需要注意几个关键点:

    1. 只支持等值join

    例如:

      SELECT a.* FROM a JOIN b ON (a.id = b.id)

      SELECT a.* FROM a JOIN b

        ON (a.id = b.id AND a.department = b.department)

    是正确的,然而:

      SELECT a.* FROM a JOIN b ON (a.id>b.id)

    是错误的。

    tips:后续版本已经可以支持不等值

     

    2. 可以 join 多于 2 个表。

    例如

      SELECT a.val, b.val, c.val FROM a JOIN b

        ON (a.key = b.key1) JOIN c ON (c.key = b.key2)

    如果join中多个表的 join key 是同一个,则 join 会被转化为单个 map/reduce 任务,例如:

      SELECT a.val, b.val, c.val FROM a JOIN b

        ON (a.key = b.key1) JOIN c

        ON (c.key = b.key1)

    被转化为单个 map/reduce 任务,因为 join 中只使用了 b.key1 作为 join key。

    SELECT a.val, b.val, c.val FROM a JOIN b ON (a.key = b.key1)

      JOIN c ON (c.key = b.key2)

    而这一 join 被转化为 2 个 map/reduce 任务。因为 b.key1 用于第一次 join 条件,而 b.key2 用于第二次 join。

       

    3join 时,每次 map/reduce 任务的逻辑:

        reducer 会缓存 join 序列中除了最后一个表的所有表的记录,再通过最后一个表将结果序列化到文件系统。这一实现有助于在 reduce 端减少内存的使用量。实践中,应该把最大的那个表写在最后(否则会因为缓存浪费大量内存)。例如:

     SELECT a.val, b.val, c.val FROM a

        JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key1)

    所有表都使用同一个 join key(使用 1 次 map/reduce 任务计算)。Reduce 端会缓存 a 表和 b 表的记录,然后每次取得一个 c 表的记录就计算一次 join 结果,类似的还有:

      SELECT a.val, b.val, c.val FROM a

        JOIN b ON (a.key = b.key1) JOIN c ON (c.key = b.key2)

    这里用了 2 次 map/reduce 任务。第一次缓存 a 表,用 b 表序列化;第二次缓存第一次 map/reduce 任务的结果,然后用 c 表序列化。

     

    4.LEFT,RIGHT 和 FULL OUTER 关键字用于处理 join 中空记录的情况

    例如:

      SELECT a.val, b.val FROM

    a LEFT OUTER  JOIN b ON (a.key=b.key)

    对应所有 a 表中的记录都有一条记录输出。输出的结果应该是 a.val, b.val,当 a.key=b.key 时,而当 b.key 中找不到等值的 a.key 记录时也会输出:

    a.val, NULL

    所以 a 表中的所有记录都被保留了;

    “a RIGHT OUTER JOIN b”会保留所有 b 表的记录。

     

    Join 发生在 WHERE 子句之前。如果你想限制 join 的输出,应该在 WHERE 子句中写过滤条件——或是在 join 子句中写。这里面一个容易混淆的问题是表分区的情况:

      SELECT a.val, b.val FROM a

      LEFT OUTER JOIN b ON (a.key=b.key)

      WHERE a.ds='2009-07-07' AND b.ds='2009-07-07'

    join a 表到 b 表(OUTER JOIN),列出 a.val 和 b.val 的记录。WHERE 从句中可以使用其他列作为过滤条件。但是,如前所述,如果 b 表中找不到对应 a 表的记录,b 表的所有列都会列出 NULL,包括 ds 列。也就是说,join 会过滤 b 表中不能找到匹配 a 表 join key 的所有记录。这样的话,LEFT OUTER 就使得查询结果与 WHERE 子句无关了。解决的办法是在 OUTER JOIN 时使用以下语法:

      SELECT a.val, b.val FROM a LEFT OUTER JOIN b

      ON (a.key=b.key AND

          b.ds='2009-07-07' AND

          a.ds='2009-07-07')

    这一查询的结果是预先在 join 阶段过滤过的,所以不会存在上述问题。这一逻辑也可以应用于 RIGHT 和 FULL 类型的 join 中。

     

    Join 是不能交换位置的。无论是 LEFT 还是 RIGHT join,都是左连接的。

      SELECT a.val1, a.val2, b.val, c.val

      FROM a

      JOIN b ON (a.key = b.key)

      LEFT OUTER JOIN c ON (a.key = c.key)

    join a 表到 b 表,丢弃掉所有 join key 中不匹配的记录,然后用这一中间结果和 c 表做 join。这一表述有一个不太明显的问题,就是当一个 key 在 a 表和 c 表都存在,但是 b 表中不存在的时候:整个记录在第一次 join,即 a JOIN b 的时候都被丢掉了(包括a.val1,a.val2和a.key),然后我们再和 c 表 join 的时候,如果 c.key 与 a.key 或 b.key 相等,就会得到这样的结果:NULL, NULL, NULL, c.val

     

     具体实例

    1、 查询选修了课程的学生姓名

    hive> select distinct Sname from student inner join sc on student.Sno=Sc.Sno;
    2.查询选修了3门以上的课程的学生学号
    hive> select Sno from (select Sno,count(Cno) CountCno from sc group by Sno)a where a.CountCno>3;


    3 Hive Shell参数

    3.1 Hive命令行

     语法结构

    hive [-hiveconf x=y]* [<-i filename>]* [<-f filename>|<-e query-string>] [-S]

    说明:

    1、 -i 从文件初始化HQL

    2、 -e从命令行执行指定的HQL

    3、 -f 执行HQL脚本

    4、 -v 输出执行的HQL语句到控制台

    5、 -p <port> connect to Hive Server on port number

    6、 -hiveconf x=y Use this to set hive/hadoop configuration variables.

     具体实例

    1、运行一个查询。

     hive -e 'select count(*) from student'

    2、运行一个文件。

    hive -f hql.hql


    3、运行参数文件。

     hive -i initHQL.conf


    3.2 Hive参数配置方式

    Hive参数大全:

    https://cwiki.apache.org/confluence/display/Hive/Configuration+Properties

     

    开发Hive应用时,不可避免地需要设定Hive的参数。设定Hive的参数可以调优HQL代码的执行效率,或帮助定位问题。然而实践中经常遇到的一个问题是,为什么设定的参数没有起作用?这通常是错误的设定方式导致的。

     

    对于一般参数,有以下三种设定方式:

    1.)配置文件 

    2.)命令行参数 

    3.)参数声明 

    配置文件Hive的配置文件包括

    1.)用户自定义配置文件:$HIVE_CONF_DIR/hive-site.xml

    2.)默认配置文件:$HIVE_CONF_DIR/hive-default.xml

    用户自定义配置会覆盖默认配置。

    另外,Hive也会读入Hadoop的配置,因为Hive是作为Hadoop的客户端启动的,Hive的配置会覆盖Hadoop的配置。

    配置文件的设定对本机启动的所有Hive进程都有效。

    命令行参数:启动Hive(客户端或Server方式)时,可以在命令行添加-hiveconf param=value来设定参数,例如:

    bin/hive -hiveconf hive.root.logger=INFO,console

    这一设定对本次启动的Session(对于Server方式启动,则是所有请求的Sessions)有效。

    参数声明:可以在HQL中使用SET关键字设定参数,例如:

    set mapred.reduce.tasks=100;

    这一设定的作用域也是session级的。

    上述三种设定方式的优先级依次递增。即参数声明覆盖命令行参数,命令行参数覆盖配置文件设定。注意某些系统级的参数,例如log4j相关的设定,必须用前两种方式设定,因为那些参数的读取在Session建立以前已经完成了。

     

    4. Hive函数

    4.1 内置运算符

    内容较多,见《Hive官方文档》 

    http://hive.apache.org/

    4.2 内置函数

    内容较多,见《Hive官方文档》 

    https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF

    4.3 Hive自定义函数和Transform

    Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDFuser-defined function)。

    4.3.1 自定义函数类别

    UDF  作用于单个数据行,产生一个数据行作为输出。(数学函数,字符串函数)

    UDAF(用户定义聚集函数):接收多个输入数据行,并产生一个输出数据行。(countmax

     

    4.3.2 UDF开发实例

    1、先开发一个java类,继承UDF,并重载evaluate方法

    package cn.lyx.bigdata.udf

    import org.apache.hadoop.hive.ql.exec.UDF;

    import org.apache.hadoop.io.Text;

     

    public final class Lower extends UDF{

    public Text evaluate(final Text s){

    if(s==null){return null;}

    return new Text(s.toString().toLowerCase());

    }

    }

     

    2、打成jar包上传到服务器

    3、将jar包添加到hiveclasspath

    hive>add JAR /home/hadoop/udf.jar;

    4、创建临时函数与开发好的java class关联

    Hive>create temporary function toprovince as 'cn.lyx.bigdata.udf.ToProvince';

     

    5、即可在hql中使用自定义的函数strip 

    Select strip(name),age from t_test;

    4.3.3 Transform实现

    HiveTRANSFORM 关键字提供了在SQL中调用自写脚本的功能

    适合实现Hive中没有的功能又不想写UDF的情况

     

    使用示例1下面这句sql就是借用了weekday_mapper.py对数据进行了处理.

    CREATE TABLE u_data_new (

      movieid INT,

      rating INT,

      weekday INT,

      userid INT)

    ROW FORMAT DELIMITED

    FIELDS TERMINATED BY '\t';

     

    add FILE weekday_mapper.py;

     

    INSERT OVERWRITE TABLE u_data_new

    SELECT

      TRANSFORM (movieid, rating, unixtime,userid)

      USING 'python weekday_mapper.py'

      AS (movieid, rating, weekday,userid)

    FROM u_data;


    其中
    weekday_mapper.py内容如下

    #!/bin/python

    import sys

    import datetime

     

    for line in sys.stdin:

      line = line.strip()

      movieid, rating, unixtime,userid = line.split('\t')

      weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()

      print '\t'.join([movieid, rating, str(weekday),userid])


    使用示例
    2:下面的例子则是使用了shell的cat命令来处理数据

    FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING '/bin/cat' WHERE a.ds > '2008-08-08';

     


    展开全文
  • Hive总结篇及Hive的优化

    万次阅读 多人点赞 2019-03-25 16:05:21
    Hive学习也有一段时间了,今天来对Hive进行一个总结,也是对自己的总结,作者还是个小白,有不对的地方请大家指出相互学习,共同进步。今天来谈一谈什么是Hive,产生背景,优势等一系列问题。 什么是Hive 老...

    概述

    Hive学习也有一段时间了,今天来对Hive进行一个总结,谈谈自己的理解,作者还是个小白,有不对的地方请大家指出相互学习,共同进步。今天来谈一谈什么是Hive,产生背景,优势等一系列问题。

    什么是Hive

    老规矩:官网地址
    Hive wiki.
    先来谈谈自己的理解:
    有些人可能会说Hive不就是写SQL的吗,那我们其实可以从另一个角度来理解:Hive就是那么强大啊,只要写SQL就能解决问题,其实这些人说的也没错Hive确实就是写SQL的,对于传统的 DBA人员或者会写SQL就很容易上手了,但是您知道他的底层细节吗,怎么优化呢?和传统的关系型数据库又有什么区别呢?等等一系列问题。。。

    Hive是一个构建在Hadoop之上的数据仓库软件,它可以使已经存储的数据结构化,它提供类似sql的查询语句HiveQL对数据进行分析处理。 Hive将HiveQL语句转换成一系列成MapReduce作业并执行(SQL转化为MapReduce的过程你知道吗?)。用户可以很方便的使用命令行和JDBC程序的方式来连接到hive。 目前,Hive除了支持MapReduce计算引擎,还支持Spark和Tez这两中分布式计算引擎。常用于离线批处理。 (Hive On Spark 还是试验版本)

    Hive的产生背景

    大数据的时代,海量的数据对于传统的关系型数据库来说维护起来成本非常高,那该如何是好,Hadoop分布式的框架,可以使用廉价的机器部署分布式系统把数据存储再HDFS之上,通过MR进行计算,分析,这样是可以的,但是,MR大家应该知道,MapReduce编程带来的不便性,编程十分繁琐,在大多情况下,每个MapReduce程序需要包含Mapper、Reduceer和一个Driver,之后需要打成jar包扔到集群上运 行。如果mr写完之后,且该项目已经上线,一旦业务逻辑发生了改变,可能就会带来大规模的改动代码,然后重新打包,发布,非常麻烦(这种方式,也是最古老的方式)
    当大量数据都存放在HDFS上,如何快速的对HDFS上的文件进行统计分析操作?
    一般来说,想要做会有两种方式:

    1. 学Java、学MapReduce(十分麻烦)
    2. 做DBA的:写SQL(希望能通过写SQL这样的方式来实现,这种方式较好)
      然而,HDFS中最关键的一点就是,数据存储HDFS上是没有schema的概念的(schema:相当于表里面有列、字段、字段名称、字段与字段之间的分隔符等,这些就是schema信息)然而HDFS上的仅仅只是一个纯的文本文件而已,那么,没有schema,就没办法使用sql进行查询了啊。。。因此,在这种背景下,就有问题产生:如何为HDFS上的文件添加Schema信息?如果加上去,是否就可以通过SQL的方式进行处理了呢?于是强大的Hive出现了。

    Hive深入剖析

    再来看看官网给我们的介绍:
    官方第一句话就说明了Apache Hive 是构建在Apache Hadoop之上的数据仓库。有助于对大型的数据集进行读、写和管理。
    那我们先对这句话进行剖析:
    首先Hive是构建在Hadoop之上的,其实就是Hive中的数据其实是存储再HDFS上的(加上LOCAL关键字则是在本地),默认在/user/hive/warehouse/table,有助于对大型数据集进行读、写和管理,那也就是意味着传统的关系型数据库已经无法满足现在的数据量了,需要一个更大的仓库来帮助我们存储,这里也引出一个问题:Hive和关系型数据库的区别,后面我们再来聊。
    Hive的特征:
    1.可通过SQL轻松访问数据的工具,从而实现数据仓库任务,如提取/转换/加载(ETL),报告和数据分析。
    2.它可以使已经存储的数据结构化
    3.可以直接访问存储在Apache HDFS™或其他数据存储系统(如Apache HBase™)中的文件
    4.Hive除了支持MapReduce计算引擎,还支持Spark和Tez这两中分布式计算引擎(这里会引申出一个问题,哪些查询跑mr哪些不跑?)
    5.它提供类似sql的查询语句HiveQL对数据进行分析处理。
    6. 数据的存储格式有多种,比如数据源是二进制格式, 普通文本格式等等

    而hive强大之处不要求数据转换成特定的格式,而是利用hadoop本身InputFormat API来从不同的数据源读取数据,同样地使用OutputFormat API将数据写成不同的格式。所以对于不同的数据源,或者写出不同的格式就需要不同的对应的InputFormat和Outputformat类的实现。
    以stored as textfile为例,其在底层java API中表现是输入InputFormat格式:TextInputFormat以及输出OutputFormat格式:HiveIgnoreKeyTextOutputFormat.这里InputFormat中定义了如何对数据源文本进行读取划分,以及如何将切片分割成记录存入表中。而Outputformat定义了如何将这些切片写回到文件里或者直接在控制台输出。

    不仅如此Hive的SQL还可以通过用户定义的函数(UDF),用户定义的聚合(UDAF)和用户定义的表函数(UDTF)进行扩展。
    (几个函数之间的区别)
    Hive中不仅可以使用逗号和制表符分隔值(CSV / TSV)文本文件,还可以使用Sequence File、RC、ORC、Parquet 
    (知道这几种存储格式的区别),
    当然Hive还可以通过用户来自定义自己的存储格式,基本上前面说的到的几种格式完全够了。
    Hive旨在最大限度地提高可伸缩性(通过向Hadoop集群动态添加更多机器扩展),性能,可扩展性,
    容错性以及与其输入格式的松散耦合。
    
    安装部署

    安装部署这里我们就不讲解了,不会的同学,参考作者以前的博客

    Hive基本语法

    该篇博客主要讲解Hive底层的东西和一些优化对于基本的东西可以参考作者以前的博客。
    DDL
    DML
    基本HQL
    内置函数和基本的UDF函数

    UDF函数这里要进行一个讲解UDF、DUAF、UDTF分别是啥。
    我们知道Hive的SQL还可以通过用户定义的函数(UDF),用户定义的聚合(UDAF)和用户定义的表函数(UDTF)进行扩展。
    当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function)。  
    UDF(User-Defined-Function) 一进一出

    UDAF(User- Defined Aggregation Funcation) 聚集函数,多进一出。

    UDTF(User-Defined Table-Generating Functions) 一进多出,如lateral view explore()

    Hive于关系型数据库的区别
    时效性、延时性比较高,可扩展性高;
    Hive数据规模大,优势在于处理大数据集,对于小数据集没有优势
    事务没什么用(比较鸡肋,没什么实际的意义,对于离线的来说)  一个小问题:那个版本开始提供了事务?
    insert/update没什么实际用途,大数据场景下大多数是select
    RDBMS也支持分布式,节点有限 成本高,处理的数据量小
    Hadoop集群规模更大 部署在廉价机器上,处理的数据量大
    数据库可以用在Online的应用中,Hive主要进行离线的大数据分析;
    数据库的查询语句为SQL,Hive的查询语句为HQL;
    数据库数据存储在LocalFS,Hive的数据存储在HDFS;
    数据格式:Hive中有多种存储格式:由于在加载数据的过程中,不需要从用户数据格式到 Hive 定义的数据格式的转换,
    因此,Hive 在加载的过程中不会对数据本身进行任何修改,而只是将数据内容复制或者移动到相应的 HDFS 目录中。
    而在数据库中,不同的数据库有不同的存储引擎,定义了自己的数据格式。所有数据都会按照一定的组织存储,因此,
    数据库加载数据的过程会比较耗时。
    Hive执行MapReduce,MySQL执行Executor;
    
    Hive的优点
    1.简单易上手
    2.扩展能力较好(指集群 HDFS或是YARN)
    3.统一的元数据管理 metastore包括的了数据库,表,字段分区等详细信息
    

    该篇博客对于元数据信息进行了详细的讲解

    4.由于统一的元数据管理所以和spark/impala等SQL引擎是通用的 
    通用是指,在拥有了统一的metastore之后,在Hive中创建一张表,在Spark/impala中是能用的,反之在Spark中创建一张表,
    在Hive中也能用;只需要共用元数据,就可以切换SQL引擎	
    涉及到了Spark sql 和Hive On Spark(实验版本)
    5.使用SQL语法,提供快速开发的能力,支持自定义函数UDF。
    6.避免了去写mapreduce,减少开发人员学习成本。
    7.数据离线处理,比如日志分析,海量数据结构化分析
    
    SQL转化为MapReduce的过程

    了解了MapReduce实现SQL基本操作之后,我们来看看Hive是如何将SQL转化为MapReduce任务的,整个编译过程分为六个阶段:

    1. Antlr定义SQL的语法规则,完成SQL词法,语法解析,将SQL转化为抽象语法树AST Tree
    2. 遍历AST Tree,抽象出查询的基本组成单元QueryBlock
    3. 遍历QueryBlock,翻译为执行操作树OperatorTree
    4. 逻辑层优化器进行OperatorTree变换,合并不必要的ReduceSinkOperator,减少shuffle数据量
    5. 遍历OperatorTree,翻译为MapReduce任务
    6. 物理层优化器进行MapReduce任务的变换,生成最终的执行计划

    可以参考美团的技术沙龙

    Hive内部表和外部表的区别

    未被external修饰的是内部表(managed table),被external修饰的为外部表(external table);
    区别:

    1. 内部表数据由Hive自身管理,外部表数据由HDFS管理;
    2. 内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定;
    3. 删除内部表会直接删除元数据(metadata)及存储数据;删除外部表仅仅会删除元数据,HDFS上的文件并不会被删除;
    行式存储vs列式存储

    行式数据库存储在hdfs上式按行进行存储的,一个block存储一或多行数据。而列式数据库在hdfs上则是按照列进行存储,一个block可能有一列或多列数据。

    如果要将数据进行压缩:

    1. 对于行式数据库,必然按行压缩,当一行中有多个字段,各个字段对应的数据类型可能不一致,压缩性能压缩比就比较差。
    2. 对于列式数据库,必然按列压缩,每一列对应的是相同数据类型的数据,故列式数据库的压缩性能要强于行式数据库。

    如果要进行数据的查询:
    假设执行的查询操作是:select id,name from table_emp;

    1. 对于行式数据库,它要遍历一整张表将每一行中的id,name字段拼接再展现出来,这样需要查询的数据量就比较大,效率低。
    2. 对于列式数据库,它只需找到对应的id,name字段的列展现出来即可,需要查询的数据量小,效率高。
      假设执行的查询操作是:select * from table_emp;

    对于这种查询整个表全部信息的操作,由于列式数据库需要将分散的行进行重新组合,行式数据库效率就高于列式数据库。
    但是,在大数据领域,进行全表查询的场景少之又少,进而我们使用较多的还是列式数据库及列式储存。

    Hive哪些查询会执行mr

    hive 0.10.0为了执行效率考虑,简单的查询,就是只是select,不带count,sum,group by这样的,都不走map/reduce,直接读取hdfs文件进行filter过滤。
    这样做的好处就是不新开mr任务,执行效率要提高不少,但是不好的地方就是用户界面不友好,有时候数据量大还是要等很长时间,但是又没有任何返回。
    改这个很简单,在hive-site.xml里面有个配置参数叫
    hive.fetch.task.conversion
    将这个参数设置为more,简单查询就不走map/reduce了,设置为minimal,就任何简单select都会走map/reduce

    Create Table As Select (CTAS) 走mr
    create table emp2 as select * from emp;
    
    insert一条或者多条 走mr		
    
    Hive静态分区动态分区

    分区的概念
    Hive的分区方式:由于Hive实际是存储在HDFS上的抽象,Hive的一个分区名对应HDFS上的一个目录名,子分区名就是子目录名,并不是一个实际字段。
    分区的好处
    产生背景:如果一个表中数据很多,我们查询时就很慢,耗费大量时间,如果要查询其中部分数据该怎么办呢,这是我们引入分区的概念。
    Partition:分区,每张表中可以加入一个分区或者多个,方便查询,提高效率;并且HDFS上会有对应的分区目录:
    语法:
    Hive分区是在创建表的时候用Partitioned by 关键字定义的,但要注意,Partitioned by子句中定义的列是表中正式的列,
    但是Hive下的数据文件中并不包含这些列,因为它们是目录名,真正的数据在分区目录下。
    静态分区和 动态分区的区别
    创建表的语法都一样

    • 静态分区:加载数据的时候要指定分区的值(key=value),比较麻烦的是每次插入数据都要指定分区的值,创建多个分区多分区一样,以逗号分隔。
    • 动态分区:
      如果用上述的静态分区,插入的时候必须首先要知道有什么分区类型,而且每个分区写一个load data,太烦人。使用动态分区可解决以上问题,其可以根据查询得到的数据动态分配到分区里。其实动态分区与静态分区区别就是不指定分区目录,由系统自己选择。
    首先,启动动态分区功能
    
    hive> set hive.exec.dynamic.partition=true;
    
    采用动态方式加载数据到目标表 
    加载之前先设置一下下面的参数
    
    hive (default)> set hive.exec.dynamic.partition.mode=nonstrict
    1
    开始加载
    
    insert into table emp_dynamic_partition partition(deptno)
    select empno , ename , job , mgr , hiredate , sal , comm, deptno from emp;
    

    加载数据方式并没有指定具体的分区,只是指出了分区字段。
    在select最后一个字段必须跟你的分区字段,这样就会自行根据deptno的value来分区。
    删除分区:
    ALTER TABLE my_partition_test_table DROP IF EXISTS PARTITION (day='2018-08-08');

    Hive优化

    1.我们知道大数据场景下不害怕数据量大,害怕的是数据倾斜,怎样避免数据倾斜,找到可能产生数据倾斜的函数尤为关键,数据量较大的情况下,慎用count(distinct),count(distinct)容易产生倾斜问题。
    2.设置合理的map reduce 的task数量
    map阶段优化

    	mapred.min.split.size: 指的是数据的最小分割单元大小;min的默认值是1B
    	mapred.max.split.size: 指的是数据的最大分割单元大小;max的默认值是256MB
    	通过调整max可以起到调整map数的作用,减小max可以增加map数,增大max可以减少map数。
    	需要提醒的是,直接调整mapred.map.tasks这个参数是没有效果的。
    

    举例:
    a) 假设input目录下有1个文件a,大小为780M,那么hadoop会将该文件a分隔成7个块(6个128m的块和1个12m的块),从而产生7个map数
    b) 假设input目录下有3个文件a,b,c,大小分别为10m,20m,130m,那么hadoop会分隔成4个块(10m,20m,128m,2m),从而产生4个map数
    即,如果文件大于块大小(128m),那么会拆分,如果小于块大小,则把该文件当成一个块。

    其实这就涉及到小文件的问题:如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,
    而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。
    而且,同时可执行的map数是受限的。那么问题又来了。。是不是保证每个map处理接近128m的文件块,就高枕无忧了?
    答案也是不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,
    如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

    我们该如何去解决呢???
    我们需要采取两种方式来解决:即减少map数和增加map数;

    • 减少map数量
    假设一个SQL任务:
    Select count(1) from popt_tbaccountcopy_mes where pt = ‘2012-07-04’;
    该任务的inputdir  /group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04
    共有194个文件,其中很多是远远小于128m的小文件,总大小9G,正常执行会用194个map任务。
    Map总共消耗的计算资源: SLOTS_MILLIS_MAPS= 623,020
    
    
    我通过以下方法来在map执行前合并小文件,减少map数:
    set mapred.max.split.size=100000000;
    set mapred.min.split.size.per.node=100000000;
    set mapred.min.split.size.per.rack=100000000;
    set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
    再执行上面的语句,用了74个map任务,map消耗的计算资源:SLOTS_MILLIS_MAPS= 333,500
    对于这个简单SQL任务,执行时间上可能差不多,但节省了一半的计算资源。
    大概解释一下,100000000表示100M, set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;这个参数表示执行前进行小文件合并,前面三个参数确定合并文件块的大小,大于文件块大小128m的,按照128m来分隔,小于128m,大于100m的,按照100m来分隔,把那些小于100m的(包括小文件和分隔大文件剩下的),进行合并,最终生成了74个块。
    
    • 增大map数量
    如何适当的增加map数? 
    当input的文件都很大,任务逻辑复杂,map执行非常慢的时候,可以考虑增加Map数,
    来使得每个map处理的数据量减少,从而提高任务的执行效率。
       假设有这样一个任务:
       Select data_desc,
              count(1),
              count(distinct id),
              sum(case when …),
              sum(case when ...),
              sum(…)
      from a group by data_desc
      如果表a只有一个文件,大小为120M,但包含几千万的记录,如果用1个map去完成这个任务,
      肯定是比较耗时的,这种情况下,我们要考虑将这一个文件合理的拆分成多个,
      这样就可以用多个map任务去完成。
         set mapred.reduce.tasks=10;
          create table a_1 as 
          select * from a 
          distribute by rand(123); 
    
       这样会将a表的记录,随机的分散到包含10个文件的a_1表中,再用a_1代替上面sql中的a表,
       则会用10个map任务去完成。
       每个map任务处理大于12M(几百万记录)的数据,效率肯定会好很多。
    
       看上去,貌似这两种有些矛盾,一个是要合并小文件,一个是要把大文件拆成小文件,
       这点正是重点需要关注的地方,
       使单个map任务处理合适的数据量;
    

    reduce阶段优化

    	Reduce的个数对整个作业的运行性能有很大影响。如果Reduce设置的过大,那么将会产生很多小文件,
    	对NameNode会产生一定的影响,
    	而且整个作业的运行时间未必会减少;如果Reduce设置的过小,那么单个Reduce处理的数据将会加大,
    	很可能会引起OOM异常。
    	如果设置了mapred.reduce.tasks/mapreduce.job.reduces参数,那么Hive会直接使用它的值作为Reduce的个数;
    	如果mapred.reduce.tasks/mapreduce.job.reduces的值没有设置(也就是-1),那么Hive会
    	根据输入文件的大小估算出Reduce的个数。
    	根据输入文件估算Reduce的个数可能未必很准确,因为Reduce的输入是Map的输出,而Map的输出可能会比输入要小,
    	所以最准确的数根据Map的输出估算Reduce的个数。
    
    1. Hive自己如何确定reduce数:
      reduce个数的设定极大影响任务执行效率,不指定reduce个数的情况下,Hive会猜测确定一个reduce个数,基于以下两个设定:
      hive.exec.reducers.bytes.per.reducer(每个reduce任务处理的数据量,默认为1000^3=1G)
      hive.exec.reducers.max(每个任务最大的reduce数,默认为999)
      计算reducer数的公式很简单N=min(参数2,总输入数据量/参数1)
      即,如果reduce的输入(map的输出)总大小不超过1G,那么只会有一个reduce任务;
    如:select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt; 
                /group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04 总大小为9G多,
                因此这句有10个reduce
    
    
    1. 调整reduce个数方法一:
    调整hive.exec.reducers.bytes.per.reducer参数的值;
    set hive.exec.reducers.bytes.per.reducer=500000000; (500M)
    select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt; 这次有20个reduce
    
    1. 调整reduce个数方法二;
    set mapred.reduce.tasks = 15;
    select pt,count(1) from popt_tbaccountcopy_mes where pt = '2012-07-04' group by pt;这次有15个reduce
    
    1. reduce个数并不是越多越好;
    同map一样,启动和初始化reduce也会消耗时间和资源;
    另外,有多少个reduce,就会有多少个输出文件,如果生成了很多个小文件,那么如果这些小文件作为下一个任务的输入,
    则也会出现小文件过多的问题;
    
    1. 什么情况下只有一个reduce;
      很多时候你会发现任务中不管数据量多大,不管你有没有设置调整reduce个数的参数,任务中一直都只有一个reduce任务;
      其实只有一个reduce任务的情况,除了数据量小于hive.exec.reducers.bytes.per.reducer参数值的情况外,还有以下原因:
    • 没有group by的汇总,比如把select pt,count(1) from popt_tbaccountcopy_mes where pt = ‘2012-07-04’ group by pt;
      写成 select count(1) from popt_tbaccountcopy_mes where pt = ‘2012-07-04’;
      这点非常常见,希望大家尽量改写。
    • 用了Order by
    • 有笛卡尔积
      通常这些情况下,除了找办法来变通和避免,我暂时没有什么好的办法,因为这些操作都是全局的,所以hadoop不得不用一个reduce去完成;
      同样的,在设置reduce个数的时候也需要考虑这两个原则:使大数据量利用合适的reduce数;使单个reduce任务处理合适的数据量;

    合并小文件

      我们知道文件数目小,容易在文件存储端造成瓶颈,给 HDFS 带来压力,影响处理效率。
      对此,可以通过合并Map和Reduce的结果文件来消除这样的影响。
      用于设置合并属性的参数有:
    		是否合并Map输出文件:hive.merge.mapfiles=true(默认值为真)
    		是否合并Reduce 端输出文件:hive.merge.mapredfiles=false(默认值为假)
    		合并文件的大小:hive.merge.size.per.task=256*1000*1000(默认值为 256000000)
    

    Hive优化之小文件问题及其解决方案
    小文件是如何产生的
    1.动态分区插入数据,产生大量的小文件,从而导致map数量剧增。

    2.reduce数量越多,小文件也越多(reduce的个数和输出文件是对应的)。

    3.数据源本身就包含大量的小文件。

    小文件问题的影响
    1.从Hive的角度看,小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,启动,执行会浪费大量的资源,严重影响性能。

    2.在HDFS中,每个小文件对象约占150byte,如果小文件过多会占用大量内存。这样NameNode内存容量严重制约了集群的扩展。

    小文件问题的解决方案
    从小文件产生的途经就可以从源头上控制小文件数量,方法如下:

    1.使用Sequencefile作为表存储格式,不要用textfile,在一定程度上可以减少小文件。
    
    2.减少reduce的数量(可以使用参数进行控制)。
    
    3.少用动态分区,用时记得按distribute by分区。
    

    对于已有的小文件,我们可以通过以下几种方案解决:

    1.使用hadoop archive命令把小文件进行归档。
    
    2.重建表,建表时减少reduce数量。
    
    3.通过参数进行调节,设置map/reduce端的相关参数,如下:
    

    设置map输入合并小文件的相关参数:

    [java] view plain copy
    //每个Map最大输入大小(这个值决定了合并后文件的数量)  
    set mapred.max.split.size=256000000;    
    //一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)  
    set mapred.min.split.size.per.node=100000000;  
    //一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)    
    set mapred.min.split.size.per.rack=100000000;  
    //执行Map前进行小文件合并  
    set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;   
    
    设置map输出和reduce输出进行合并的相关参数:
    [java] view plain copy
    //设置map端输出进行合并,默认为true  
    set hive.merge.mapfiles = true  
    //设置reduce端输出进行合并,默认为false  
    set hive.merge.mapredfiles = true  
    //设置合并文件的大小  
    set hive.merge.size.per.task = 256*1000*1000  
    //当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge。  
    set hive.merge.smallfiles.avgsize=16000000  
    

    3.Write good SQL : 说道sql优化很惭愧,自己sql很烂,不多比比了,但是sql优化确实很关键。。。
    4.存储格式:可以使用列裁剪,分区裁剪,orc,parquet等存储格式。参考该博客

    Hive支持ORCfile,这是一种新的表格存储格式,通过诸如谓词下推,压缩等技术来提高执行速度提升。
    对于每个HIVE表使用ORCFile应该是一件容易的事情,并且对于获得HIVE查询的快速响应时间非常有益。
    作为一个例子,考虑两个大表A和B(作为文本文件存储,其中一些列未在此处指定,即行试存储的缺点)以及一个简单的查询,如:
    SELECT A.customerID, A.name, A.age, A.address join
    B.role, B.department, B.salary
    ON A.customerID=B.customerID;
    此查询可能需要很长时间才能执行,因为表A和B都以TEXT形式存储,进行全表扫描。
    将这些表格转换为ORCFile格式通常会显着减少查询时间:
    
    ORC支持压缩存储(使用ZLIB或如上所示使用SNAPPY),但也支持未压缩的存储。
    	CREATE TABLE A_ORC (
    	customerID int, name string, age int, address string
    	) STORED AS ORC tblproperties (“orc.compress" = “SNAPPY”);
    
    	INSERT INTO TABLE A_ORC SELECT * FROM A;
    
    
    	CREATE TABLE B_ORC (
    	customerID int, role string, salary float, department string
    	) STORED AS ORC tblproperties (“orc.compress" = “SNAPPY”);
    
    	INSERT INTO TABLE B_ORC SELECT * FROM B;
    
    	SELECT A_ORC.customerID, A_ORC.name,
    	A_ORC.age, A_ORC.address join
    	B_ORC.role, B_ORC.department, B_ORC.salary
    	ON A_ORC.customerID=B_ORC.customerID;
    

    5.压缩格式:大数据场景下存储格式压缩格式尤为关键,可以提升计算速度,减少存储空间,降低网络io,磁盘io,所以要选择合适的压缩格式和存储格式,那么首先就了解这些东西,作者以前博客已经进行了详细的说明,参考该博客
    6.MAP JOIN
    这里写图片描述
    MapJoin简单说就是在Map阶段将小表读入内存,顺序扫描大表完成Join。
    上图是Hive MapJoin的原理图,出自Facebook工程师Liyin Tang的一篇介绍Join优化的slice,从图中可以看出MapJoin分为两个阶段:
    (1)通过MapReduce Local Task,将小表读入内存,生成HashTableFiles上传至Distributed Cache中,这里会对HashTableFiles进行压缩。
    (2)MapReduce Job在Map阶段,每个Mapper从Distributed Cache读取HashTableFiles到内存中,顺序扫描大表,在Map阶段直接进行Join,将数据传递给下一个MapReduce任务。
    也就是在map端进行join避免了shuffle。
    7.引擎的选择

    Hive可以使用ApacheTez执行引擎而不是古老的Map-Reduce引擎。 
    我不会详细讨论在这里提到的使用Tez的许多好处; 相反,我想提出一个简单的建议:
    如果它没有在您的环境中默认打开,请在您的Hive查询的开头将以下内容设置为'true'来使用Tez:
    设置hive.execution.engine = tez;
    通过上述设置,您执行的每个HIVE查询都将利用Tez。
    目前Hive On Spark还处于试验阶段,慎用。。
    

    8.Use Vectorization

    向量化查询执行通过一次性批量执行1024行而不是每次单行执行,从而提高扫描,聚合,筛选器和连接等操作的性能。
    在Hive 0.13中引入,此功能显着提高了查询执行时间,并可通过两个参数设置轻松启用:
    设置hive.vectorized.execution.enabled = true;
    设置hive.vectorized.execution.reduce.enabled = true;
    

    9.cost based query optimization

    Hive 自0.14.0开始,加入了一项”Cost based Optimizer”来对HQL执行计划进行优化,这个功能通  
    过”hive.cbo.enable”来开启。在Hive 1.1.0之后,这个feature是默认开启的,它可以自动优化HQL中多个JOIN的顺序,并
    选择合适的JOIN算法.
    Hive在提交最终执行前,优化每个查询的执行逻辑和物理执行计划。这些优化工作是交给底层来完成。
    根据查询成本执行进一步的优化,从而产生潜在的不同决策:如何排序连接,执行哪种类型的连接,并行度等等。
    要使用基于成本的优化(也称为CBO),请在查询开始处设置以下参数:
    设置hive.cbo.enable = true;
    
    设置hive.compute.query.using.stats = true;
    
    设置hive.stats.fetch.column.stats = true;
    
    设置hive.stats.fetch.partition.stats = true;
    

    10.模式选择

    • 本地模式
      对于大多数情况,Hive可以通过本地模式在单台机器上处理所有任务。
      对于小数据,执行时间可以明显被缩短。通过set hive.exec.mode.local.auto=true(默认为false)设置本地模式。
      hive> set hive.exec.mode.local.auto;
      hive.exec.mode.local.auto=false

    • 并行模式
      Hive会将一个查询转化成一个或者多个阶段。这样的阶段可以是MapReduce阶段、抽样阶段、合并阶段、limit阶段。
      默认情况下,Hive一次只会执行一个阶段,由于job包含多个阶段,而这些阶段并非完全互相依赖,
      即:这些阶段可以并行执行,可以缩短整个job的执行时间。设置参数:set hive.exec.parallel=true,或者通过配置文件来完成。
      hive> set hive.exec.parallel;
      hive.exec.parallel=false

    • 严格模式
      Hive提供一个严格模式,可以防止用户执行那些可能产生意想不到的影响查询,通过设置
      Hive.mapred.modestrict来完成
      set Hive.mapred.modestrict;
      Hive.mapred.modestrict is undefined

    11.JVM重用
    Hadoop通常是使用派生JVM来执行map和reduce任务的。这时JVM的启动过程可能会造成相当大的开销,
    尤其是执行的job包含偶成百上千的task任务的情况。JVM重用可以使得JVM示例在同一个job中时候使用N此。
    通过参数mapred.job.reuse.jvm.num.tasks来设置。

    12.推测执行
    Hadoop推测执行可以触发执行一些重复的任务,尽管因对重复的数据进行计算而导致消耗更多的计算资源,
    不过这个功能的目标是通过加快获取单个task的结果以侦测执行慢的TaskTracker加入到没名单的方式来提高整体的任务执行效率。

    Hadoop的推测执行功能由2个配置控制着,通过mapred-site.xml中配置

    mapred.map.tasks.speculative.execution=true

    mapred.reduce.tasks.speculative.execution=true

    展开全文
  • hive

    千次阅读 2020-06-01 21:52:12
    hive数据仓库工具 hive是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。hive数据仓库工具能将结构化的数据文件映射为一张数据库...

    hive数据仓库工具

           hive是基于Hadoop的一个数据仓库工具,用来进行数据提取、转化、加载,这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。hive数据仓库工具能将结构化的数据文件映射为一张数据库表,并提供SQL查询功能,能将SQL语句转变成MapReduce任务来执行。Hive的优点是学习成本低,可以通过类似SQL语句实现快速MapReduce统计,使MapReduce变得更加简单,而不必开发专门的MapReduce应用程序。hive是十分适合数据仓库的统计分析和Windows注册表文件

            hive是基于Hadoop构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop分布式文件系统中的数据:可以将结构化的数据文件映射为一张数据库表,并提供完整的SQL查询功能;可以将SQL语句转换为MapReduce任务运行,通过自己的SQL查询分析需要的内容,这套SQL简称Hive SQL,使不熟悉mapreduce的用户可以很方便地利用SQL语言‘查询、汇总和分析数据。而mapreduce开发人员可以把自己写的mapper和reducer作为插件来支持hive做更复杂的数据分析。它与关系型数据库的SQL略有不同,但支持了绝大多数的语句如DDL、DML以及常见的聚合函数、连接查询、条件查询。它还提供了一系列的1:具进行数据提取转化加载,用来存储、查询和分析存储在Hadoop中的大规模数据集,并支持UDF(User-Defined Function)、UDAF(User-Defnes AggregateFunction)和USTF(User-Defined Table-Generating Function),也可以实现对map和reduce函数的定制,为数据操作提供了良好的伸缩性和可扩展性。hive不适合用于联机(online)事务处理,也不提供实时查询功能。它最适合应用在基于大量不可变数据的批处理作业。hive的特点包括:可伸缩(在Hadoop的集群上动态添加设备)、可扩展、容错、输入格式的松散耦合。

             hive 构建在基于静态批处理的Hadoop 之上,Hadoop 通常都有较高的延迟并且在作业提交和调度的时候需要大量的开销。因此,hive 并不能够在大规模数据集上实现低延迟快速的查询,例如,hive 在几百MB 的数据集上执行查询一般有分钟级的时间延迟。 

             因此,hive 并不适合那些需要高实性的应用,例如,联机事务处理(OLTP)。hive 查询操作过程严格遵守Hadoop MapReduce 的作业执行模型,hive 将用户的hiveQL 语句通过解释器转换为MapReduce 作业提交到Hadoop 集群上,Hadoop 监控作业执行过程,然后返回作业执行结果给用户。hive 并非为联机事务处理而设计,hive 并不提供实时的查询和基于行级的数据更新操作。hive 的最佳使用场合是大数据集的批处理作业,例如,网络日志分析。

     

    展开全文
  • hive使用beeline将hql结果导出为csv文件

    千次阅读 2018-09-21 10:25:44
    编写shell脚本自动化导出指定hql结果到csv文件并删除sql语句和关闭连接日志 1. hql文件准备 select a.enodebid as enodebid, sum(xdrsize) as totalXdrSize, sum(failed) as totalFailed, ...

    编写shell脚本自动化导出指定hql结果到csv文件并删除sql语句和关闭连接日志

    1. hql文件准备

    select a.enodebid as enodebid,
    	   sum(xdrsize) as totalXdrSize,
    	   sum(failed) as totalFailed,
    	   sum(success) as totalSuccess
      from test.imsiBackFill a
     where date_id = 20180920
       and hour = 10
     group by enodebid;

    2. shell脚本编写

    #!/bin/bash
    #要查询的sql语句 eg: *.hql
    sqlFile=$1
    #导出文件完整路径 eg: */resultData.csv
    exportFilePath=$2
    #导入hive查询结果命令 注意beeline使用完整路径
    /usr/local/hive-1.2.2/bin/beeline -u jdbc:hive2://mace:10000 --outputformat=csv2 --showHeader=true -f ${sqlFile} >${exportFilePath}
    #处理导出文件 删除sql及最后一行
    rowNum=$(cat ${sqlFile}|wc -l)
    #删除sql语句(默认为sql文件的行数)
    $(sed -e "1,${rowNum}d" $exportFilePath -i)
    exportFileRowNum=$(cat ${exportFilePath}|wc -l)
    #删除关闭beeline连接(最后一行)
    $(sed -e "${exportFileRowNum}d" $exportFilePath -i)

    3.执行命令

    sh exportHiveDataBySQL.sh */select.hql */resultData.csv

    注: sed命令 是linux下利用脚本处理文件。详细参考:http://www.runoob.com/linux/linux-comm-sed.html

    展开全文
  • hive&&beeline 数据导入导出

    千次阅读 2017-09-01 17:07:18
    hive&&beeline 数据导入导出hive数据导入方式 从本地文件系统中导入数据到Hivehive -e "load data local inpath 'localpath' into table xxx;" 从HDFS上导入数据到Hive表 hadoop dfs -put localpath 从别的...
  • beeline 查询表数据导出到本地文件csv

    千次阅读 2019-01-23 15:31:32
    beeline -u jdbc:hive2://10.000.000.000:10000 -n test -p test -d org.apache.hive.jdbc.HiveDriver --outputformat=csv2 -e "select * from test limit 10" &gt; data.csv  
  • hive上处理数据的过程中,不免要导出数据,以下是我在查看相关资料,自己试验成功的方法: 1.用insert,写到hdfs目录下,但是目录好像要由hive用户创建才可以,否则会报错 INSERT OVERWRITE DIRECTORY '/tmp/...
  • Hive教程(一) Hive入门教程

    万次阅读 多人点赞 2017-10-10 22:25:51
    Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。其优点是学习成本低,可以通过类SQL语句快速实现简单的...
  • Hive面试题(一)

    万次阅读 多人点赞 2019-05-08 13:22:47
    2.谈一下hive的特点,以及hive和RDBMS有什么异同 3.说一下hive中sort by、order by、cluster by、distribute by各代表的意思 4.简要描述数据库中的 null,说出null在hive底层如何存储,并解释select a.* from t1 a...
  • Hive入门及常用指令

    万次阅读 多人点赞 2018-06-18 10:29:53
    Hive 最近在公司实习,对hive进行了学习,做了些整理的笔记。 基础命令 show databases; # 查看某个数据库 use 数据库; # 进入某个数据库 show tables; # 展示所有表 desc 表名; # 显示表结构 show partitions ...
  • 总结:HiveHive on Spark和SparkSQL区别

    万次阅读 多人点赞 2020-09-11 00:43:36
    Hive的原理大家可以参考这篇大数据时代的技术hivehive介绍,实际的一些操作可以看这篇笔记:新手的Hive指南,至于还有兴趣看Hive优化方法可以看看我总结的这篇Hive性能优化上的一些总结 Hive on Mapreduce执行...
  • HIVE入门精通

    千次阅读 2016-09-29 17:33:09
    1背景 应用于工业的商务智能收集分析所需的数据集正在大量增长,使得传统的数据仓库解决方案变得过于昂贵。Hadoop是一个流行的开源map-reduce实现,用于像yahoo, Facebook一类的公司。来存储和处理商用硬件上的大...
  • 完整的大数据知识体系,大数据学习路线图

    千次阅读 多人点赞 2019-01-17 11:26:49
     一、Java语言以java语言为基础掌握面向对象编程思想所涉及的知识,以及该知识在面向对象编程思想中的应用,培养学生设计程序的能力。掌握程度:精通。  二、数据结构与算法掌握基于JAVA语言的底层数据结...
  • 在Tableau Desktop中,选择适当的服务器、Cloudera Hadoop、Hortonworks Hadoop Hive、MapR Hadoop Hive或Amazon EMR,然后输入连接所需的信息。 6.3.1Cloudera Hadoop 在开始页面上的“连接”下,单击“Cloudera...
  • 大数据技术学习路线

    万次阅读 多人点赞 2018-07-26 10:13:53
    一、大数据技术基础 1、linux操作基础 linux系统简介与安装 linux常用命令–文件操作 linux常用命令–用户管理与权限 linux常用命令–系统管理 linux常用命令–免密登陆配置与网络管理 linux上常用软件安装 linux...
  • 倾情大奉送--Spark入门实战系列

    万次阅读 多人点赞 2016-12-18 22:02:43
    这一两年Spark技术很火,自己也凑热闹,反复的试验、研究,有痛苦万分也有欣喜若狂,抽空把这些整理成文章共享...文章内容的整理一般是先介绍原理,随后是实战例子,由于面向的是入门读者,在实战中多截图,还请谅解。
  • Hive架构以及应用介绍

    万次阅读 多人点赞 2019-08-11 14:21:24
    那么Hive究竟是什么,为什么在Hadoop家族中占有这么重要的地位,本篇文章将围绕Hive的体系结构(架构)、Hive的操作、Hive与Hbase的区别等对Hive进行全方面的阐述。 在此之前,先给大家介绍一个业务场景,让大家...
  • Cloudera Hadoop 4系列实战课程视频教程 Cloudera Hadoop 4系列实战课程视频教程1.part1.rar Cloudera Hadoop 4系列实战课程视频教程1.part2.rar Cloudera Hadoop 4系列实战课程视频教程1.part3.rar ...
1 2 3 4 5 ... 20
收藏数 1,708
精华内容 683
关键字:

hive