zoukankan      html  css  js  c++  java
  • Hive入门指南

    转自:http://blog.csdn.net/zhoudaxia/article/details/8842576

    1、安装与配置

        Hive是建立在Hadoop上的数据仓库软件,用于查询和管理存放在分布式存储上的大规模数据集。它提供:

        (1)一系列的工具,可以方便地对数据进行提取/转化/加载(ETL);

        (2)一种可以对各种数据格式上进行结构化的机制;

        (3)存取存放在Apache HDFS或其他存储系统如Apache HBase上的文件;

        (4)通过MapReduce执行查询功能。

        Hive 定义了简单的类SQL查询语言,称为QL,它允许熟悉SQL的用户查询数据。同时,这个语言也允许熟悉MapReduce的开发者开发自定义的mapper和reducer来处理内建的mapper和reducer无法完成的复杂分析工作。QL也可以被扩展,以让用户自定义标量函数(UDF's)、聚合(UDAF's)和表函数(UDTF's)。

        Hive并不要求使用"Hive格式"来读写数据--没有这样的格式,Hive没有专门的数据格式。 Hive可以很好的工作在Apache Thrift、控制分隔符、或用户指定的数据格式上。

        Hive并不是为OLTP工作负载设计的,也不提供实时查询和行级别的更新。它最常用于批量作业,比较适合工作在只追加的大数据集上(如Web日志)。Hive的核心设计思想是可伸缩性(通过动态添加到Hadoop集群的机器来进行横向扩展)、可扩展性(使用MapReduce框架和UDF/UDAF/UDTF)、容错性、与输入格式的松耦合性。

        从http://hive.apache.org/releases.html处下载最新的稳定版hive-0.9.0.tar.gz。下一步你需要解压缩Tar包,这将会创建一个名为hive-x.y.z的子目录:
    $ tar -xzvf hive-x.y.z.tar.gz
        设置HIVE_HOME环境变量指向到Hive的安装目录:
    $ cd hive-x.y.z
    $ export HIVE_HOME=$(pwd)
        最后,将$HIVE_HOME/bin添加到你的PATH环境变量中:
    $ export PATH=$HIVE_HOME/bin:$PATH

        2、运行Hive

        Hive使用Hadoop,这意味着你必须在PATH里面设置了hadoop路径,或者导出export HADOOP_HOME=<hadoop-install-dir>也可以。另外,你必须在创建Hive库表前,在HDFS上创建/tmp和/user/hive/warehouse(也称为hive.metastore.warehouse.dir),并且将它们的权限设置为chmod g+w。完成这个操作的命令如下:
    $ $HADOOP_HOME/bin/hadoop fs -mkdir /tmp
    $ $HADOOP_HOME/bin/hadoop fs -mkdir /user/hive/warehouse
    $ $HADOOP_HOME/bin/hadoop fs -chmod g+w /tmp
    $ $HADOOP_HOME/bin/hadoop fs -chmod g+w /user/hive/warehouse
        我同样发现设置HIVE_HOME是很重要的,但并非必须。
    $ export HIVE_HOME=<hive-install-dir>
        在Shell中使用Hive命令行(cli)模式:
    $ $HIVE_HOME/bin/hive

        3、配置文件管理概述
        (1)Hive默认的配置文件保存在 <install-dir>/conf/hive-default.xml,你可以修改其中的配置,并重命名这个文件为 <install-dir>/conf/hive-site.xml(注:我建议你还是保留原始配置文件)。
        (2)Hive配置文件的位置可以通过设置HIVE_CONF_DIR环境变量来改变。
        (3)Log4j的配置保存在<install-dir>/conf/hive-log4j.properties。
        (4)Hive的配置存在于Hadoop之上,这意味着Hadoop的配置默认会被继承到Hive中。
        (5)Hive配置可以被如下方式控制:
        编辑hive-site.xml并定义任何需要的变量 (包括hadoop的变量)
        从cli模式使用使用set命令。使用如下方式:
    $ bin/hive -hiveconf x1=y1 -hiveconf x2=y2
        这个例子分别设置了变量x1为y1,x2为y2。设置使用 HIVE_OPTS环境变量 "-hiveconf x1=y1 -hiveconf x2=y2" 与上面的功能相同。
        Hive查询是执行map-reduce查询,并且这些查询是可以被hadoop的配置所控制的。命令行命令 'SET' 可以被用来设置任何hadoop(或者hive)的配置变量,例如:
    hive> SET mapred.job.tracker=myhost.mycompany.com:50030;
    hive> SET -v;
        后者SET -v用来查看当前全部的设置。而不使用 -v 选项,则是用来查看当前与Hadoop不同的配置。
        4、Hive,Map-Reduce与本地模式
        Hive编译器会为绝大多数查询生成map-reduce的jobs。这些Jobs使用下面这个变量来表明被提交到Map-Reduce集群中:

        mapred.job.tracker
        由于这通常是在一个多节点的map-reduce集群中被指出,Hadoop同样有个就近的方式来在用户的工作机上运行map-reduce jobs。这就在小数据集的查询上显得非常有用 - 在这种情况下,本地模式运行通常会比将任务提交到整个大集群中查询更快。数据从HDFS上获取是透明的。同样的,由于本地模式仅运行一个reducer,这样,在大数据查询上是非常慢的。
        从0.7版本开始,Hive全面支持本地运行模式,要使用这个模式,请按照下列进行设置:
    hive> SET mapred.job.tracker=local;
        另外,mapred.local.dir应该指定一个合法的本机路径(注:安装hive的那台服务器)(例如:/tmp/<username>/mapred/local)。否则用户将获取一个定位本地空间的异常抛出)。
        从0.7版本开始,Hive同样支持自动/非自动地使用本地模式来完成map-reduce jobs,相关的选项是:
    hive> SET hive.exec.mode.local.auto=false;
        请注意这个功能默认是关闭的,如果打开,Hive将分析每一个查询的map-reduce job,并且如果以下阀值被确认为OK,就尝试运行在本地:
        (1)全部job的输入低于:hive.exec.mode.local.auto.inputbytes.max (128MB 默认)
        (2)全部的map任务数低于:hive.exec.mode.local.auto.tasks.max (4 个默认)
        (3)全部reduce任务数等于1或者0。
        对于小数据集上的查询,或者带有多个map-reduce jobs的查询,但是这些job的输入是很小的(注:小于上述条件),jobs仍可能使用本地模式来运行。
        注意,可能hadoop服务器节点和hive客户端的运行时环境不同(由于不同的jvm版本或者不同的软件库)。这可能会导致运行本地模式时出现一些意外的错误。同样需要注意的是,本地运行模式是运行在一个独立的子jvm中(hive 客户端的子进程)。如果用户愿意,子jvm所能使用的最大内存数可以通过选项hive.mapred.local.mem来进行控制。默认设置是0,这时Hive让Hadoop来决定子jvm的默认内存限制。

        5、错误日志
        Hive使用log4j来记录日志。默认来说,日志不会被返回到CLI模式的控制台上。默认的日志记录等级是WARN,并被保存到以下文件夹中:
    /tmp/<user.name>/hive.log
        如果用户愿意,日志可以通过修改下面的参数来返回到控制台上:
    bin/hive -hiveconf hive.root.logger=INFO,console
        另外,用户可以改变记录等级:
    bin/hive -hiveconf hive.root.logger=INFO,DRFA
        注意,配置项hive.root.logger在hive初始化以后,不能通过使用'set'命令来改变了。
        Hive也会在在/tmp/<user.name>/ 下为每个hive会话保存查询日志,但是可以通过修改hive-site.xml中的hive.querylog.location属性来变更。
        Hive在一个hadoop集群上的运行日志是由Hadoop的配置所决定的。通常Hadoop会为每个map和reduce任务创建日志文件,并保存在运行任务的集群服务器上。日志文件可以通过Hadoop Jobtracker提供的Web UI上的Task Detail页面来跟踪观察。
        运行本地模式时(mapred.job.tracker=local),Hadoop/Hive会将执行日志放在本机上,从0.6版本开始,Hive使用hive-exec-log4j.properties (如果不存在,则是使用hive-log4j.properties文件)来决定默认日志的保存方式。默认的配置文件将为每个通过本地模式执行的查询生成一个日志,并存放到/tmp/<user.name>下。这样做的目的是为了将配置单独管理,并可以将日志集中存放到一个用户需要的位置上(例如一个NFS文件服务器)。执行日志对调试运行时错误并无帮助。
        错误日志对于定位问题非常有用,请将存在的任何bug发送到hive-dev@hadoop.apache.org
        6、DDL操作
        创建Hive表和查看使用
    hive> CREATE TABLE pokes (foo INT, bar STRING);
        创建一个包含两个字段,名称为pokes的表,第一个字段是int(注:整型),第二个字段是string(注:字符串)
    hive> CREATE TABLE invites (foo INT, bar STRING) PARTITIONED BY (ds STRING);
        创建一个名为invites的表,其中包含两个字段和一个叫做ds的分区(partition)字段。分区字段是一个虚拟的字段,本身并不包含在数据中,但是是从加载进来的数据中特别衍生出来的数据集。
        默认情况下,表被假定是纯文本的格式,并且使用^A(ctrl-a)来作为数据分割的。
    hive> SHOW TABLES;
        列出所有的表
    hive> SHOW TABLES '.*s';
        列出所有结尾包含 's' 的表名。匹配方式使用Java正则表达式,查看下列连接获取关于Java正则的信息http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html
    hive> DESCRIBE invites;
        查看invites表的全部字段
        可以修改表名,增加删除新的字段等:
    hive> ALTER TABLE pokes ADD COLUMNS (new_col INT);
    hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');
    hive> ALTER TABLE events RENAME TO 3koobecaf;
        删除表:
    hive> DROP TABLE pokes;

        7、元数据存储
        元数据默认使用Derby数据库保存在本地文件系统中,并保存在./metastore_db下。通过修改conf/hive-default.xml中的javax.jdo.option.ConnectionURL变量修改。
        当前,在默认配置下,元数据每次只能同时被一个用户所使用。
    元数据可以存储在任何一个使用JPOX支持的数据库中,这些关系型数据库的连接和类型可以通过两个变量进行控制。javax.jdo.option.ConnectionURL和javax.jdo.option.ConnectionDriverName。
        你需要查看数据库的JDO(或JPOX)手册来获取更多信息。
        数据库的Schema定义在JDO元数据注释文件package.jdo中,位置在src/contrib/hive/metastore/src/model。
        计划在未来,元数据存储引擎可以成为一个独立的服务。
        如果你想将元数据作为一个网络的服务来在多个节点中访问,请尝试HiveDerbyServerMode。
        8、DML操作
        将文件中的数据加载到Hive中:
    hive> LOAD DATA LOCAL INPATH './examples/files/kv1.txt' OVERWRITE INTO TABLE pokes;
        加载到pokes表的文件包含两个用ctrl-a符号分割的数据列,'LOCAL' 意味着文件是从本地文件系统加载,如果没有 'LOCAL' 则意味着从HDFS中加载。
        关键词 'OVERWRITE' 意味着当前表中已经存在的数据将会被删除掉。
        如果没有给出 'OVERWRITE',则意味着数据文件将追加到当前的数据集中。
        注意,通过load命令加载的数据不会被校验正确性。如果文件在HDFS上,他将会被移动到hive所管理的文件系统的命名空间中。Hive目录的根路径是在hive-default.xml文件中的变量hive.metastore.warehouse.dir决定的。
        我们建议用户在使用Hive建表之前就创建好这个变量指定的目录。
    hive> LOAD DATA LOCAL INPATH './examples/files/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');
    hive> LOAD DATA LOCAL INPATH './examples/files/kv3.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-08');
        上面这两个LOAD语句,将加载不同的数据到invites表的分区(partition)中。invites表必须事先使用ds创建好partition。
    hive> LOAD DATA INPATH '/user/myname/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');
        上述命令是将HDFS上的文件加载到表中。
        注意从HDFS中加载数据,将会把数据移动到目录下。这几乎是瞬间完成的。(注:因为只是在HDFS元数据中修改了文件路径的指向。)

        9、SQL 查询
        (1)查询示例

        下面会演示一些查询范例,在build/dist/examples/queries中可以找到。更多的,可以在hive源码中的ql/src/test/queries/positive中可以找到。
        (2)SELECTS和FILTERS
    hive> SELECT a.foo FROM invites a WHERE a.ds='2008-08-15';
        从invite表的字段 'foo' 中选择所有分区ds=2008-08-15的结果。这些结果并不存储在任何地方,只在控制台中显示。
        注意下面的示例中,INSERT (到hive表,本地目录或者HDFS目录) 是可选命令。
    hive> INSERT OVERWRITE DIRECTORY '/tmp/hdfs_out' SELECT a.* FROM invites a WHERE a.ds='2008-08-15';
        从invites表中选择分区ds=2008-08-15 的所有行,并放入HDFS目录中。结果数据存放于/tmp/hdfs_out目录中的文件(多个文件,文件数量取决于mapper的数量)。
        存在分区的表在使用 WHERE 条件过滤的时候必须至少指定一个分区来查询。
    hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/local_out' SELECT a.* FROM pokes a;
        选择pokes表中所有的数据并放到一个本地(注:当前服务器)的文件路径中。
    hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a;
    hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a WHERE a.key < 100;
    hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/reg_3' SELECT a.* FROM events a;
    hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_4' select a.invites, a.pokes FROM profiles a;
    hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT COUNT(*) FROM invites a WHERE a.ds='2008-08-15';
    hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT a.foo, a.bar FROM invites a;
    hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/sum' SELECT SUM(a.pc) FROM pc1 a;
        字段计算和,最大值,最小值同样可以使用,注意对不包含HIVE-287的Hive版本,你需要使用COUNT(1) 来代替 COUNT(*)。
        (3)GROUP BY
    hive> FROM invites a INSERT OVERWRITE TABLE events SELECT a.bar, count(*) WHERE a.foo > 0 GROUP BY a.bar;
    hive> INSERT OVERWRITE TABLE events SELECT a.bar, count(*) FROM invites a WHERE a.foo > 0 GROUP BY a.bar;
        注意对不包含HIVE-287的Hive版本,你需要使用COUNT(1) 来代替 COUNT(*)。
        (4)JOIN
    hive> FROM pokes t1 JOIN invites t2 ON (t1.bar = t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo;
        (5)MULTITABLE INSERT(多重插入)
    FROM src
    INSERT OVERWRITE TABLE dest1 SELECT src.* WHERE src.key < 100
    INSERT OVERWRITE TABLE dest2 SELECT src.key, src.value WHERE src.key >= 100 and src.key < 200
    INSERT OVERWRITE TABLE dest3 PARTITION(ds='2008-04-08', hr='12') SELECT src.key WHERE src.key >= 200 and src.key < 300
    INSERT OVERWRITE LOCAL DIRECTORY '/tmp/dest4.out' SELECT src.value WHERE src.key >= 300;
        (6)STREAMING
    hive> FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING '/bin/cat' WHERE a.ds > '2008-08-09';
        在map中使用脚本/bin/cat对数据的流式访问(类似于hadoop streaming)。同样的, 流式访问也可以使用在reduce阶段(请查看Hive Tutorial范例)。

        10、简单的使用范例
        (1)用户对电影的投票统计

        首先,创建一个使用tab分割的文本文件的表

    1. CREATE TABLE u_data (  
    2.         userid INT,  
    3.         movieid INT,  
    4.         rating INT,  
    5.         unixtime STRING)  
    6. ROW FORMAT DELIMITED  
    7. FIELDS TERMINATED BY ' '  
    8. STORED AS TEXTFILE;  
        然后,下载这个数据文件并解压:
    wget http://www.grouplens.org/system/files/ml-data.tar+0.gz
    tar xvzf ml-data.tar+0.gz
        将这个文件加载到刚刚创建的表中:
    LOAD DATA LOCAL INPATH 'ml-data/u.data' OVERWRITE INTO TABLE u_data;
        计算表u_data中的总行数:
    SELECT COUNT(*) FROM u_data;
        注意对不包含HIVE-287的Hive版本,你需要使用COUNT(1) 来代替 COUNT(*)。
        现在,我们可以在表u_data中做一些复杂的数据分析
        创建weekday_mapper.py:

    [python] view plaincopy
    1. import sys  
    2. import datetime  
    3.   
    4. for line in sys.stdin:  
    5.   line = line.strip()  
    6.   userid, movieid, rating, unixtime = line.split(' ')  
    7.   weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()  
    8.   print ' '.join([userid, movieid, rating, str(weekday)])  
        使用mapper脚本:

    1. CREATE TABLE u_data_new (  
    2.         userid INT,  
    3.         movieid INT,  
    4.         rating INT,  
    5.         weekday INT)  
    6. ROW FORMAT DELIMITED  
    7. FIELDS TERMINATED BY ' ';  
    8. add FILE weekday_mapper.py;  
    9. INSERT OVERWRITE TABLE u_data_new  
    10. SELECT  
    11.         TRANSFORM (userid, movieid, rating, unixtime)  
    12.         USING 'python weekday_mapper.py'  
    13.         AS (userid, movieid, rating, weekday)  
    14. FROM u_data;  
    15. SELECT weekday, COUNT(*)  
    16. FROM u_data_new  
    17. GROUP BY weekday;  
        注意对0.5.0及更早的的Hive版本,你需要使用COUNT(1) 来代替 COUNT(*)。
        (2)Apache Web日志数据
        Apache日志格式是可以自定义的,作为大多数网管来说都是使用默认设置。

        我们可以给默认的Apache日志创建一个如下的表。更多的关于正则序列化/反序列化(!RegexSerDe)可以在这里看到:http://issues.apache.org/jira/browse/HIVE-662

    1. add jar ../build/contrib/hive_contrib.jar;  
    2. CREATE TABLE apachelog (  
    3.         host STRING,  
    4.         identity STRING,  
    5.         user STRING,  
    6.         time STRING,  
    7.         request STRING,  
    8.         status STRING,  
    9.         size STRING,  
    10.         referer STRING,  
    11.         agent STRING)  
    12. ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'  
    13. WITH SERDEPROPERTIES (  
    14.         "input.regex" = "([^]*) ([^]*) ([^]*) (-|\[^\]*\]) ([^ "]*|"[^"]*") (-|[0-9]*) (-|[0-9]*)(?: ([^ "]*|".*") ([^ "]*|".*"))?",  
    15.         "output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s"  
    16. )  
    17. STORED AS TEXTFILE;  
        11、Hive的基本概念

        下面整理自Hive Tutorial部分:https://cwiki.apache.org/confluence/display/Hive/Tutorial

        (1)Hive是什么?
        Hive是基于hadoop构建的数据仓库基础架构,通过提供一系列的工具,使得用户能够方便的做数据ETL,数据结构化,并针对存放在hadoop上的海量数据进行查询和分析。
    hive定义了一种简单的类SQL查询语言---QL,QL语言方便熟悉SQL语言的用户去查询数据。此外,hive也支持熟悉map-reduce的开发者使用map-reduce程序对数据做更加复杂的分析。hive可以很好的结合thrift和控制分隔符,也支持用户自定义分隔符。
        (2)Hive不是什么?
        Hive基于hadoop,hadoop是批处理系统,不能保证低延迟,因此,hive的查询也不能保证低延迟。
        Hive的工作模式是提交一个任务,等到任务结束时被通知,而不是实时查询。相对应的是,类似于oracle这样的系统当运行于小数据集的时候,响应非常快,可当处理的数据集非常大的时候,可能需要数小时。需要说明的是,hive即使在很小的数据集上运行,也可能需要数分钟才能完成。
        总之,低延迟不是hive追求的首要目标。hive的设计目标是:可伸缩、可扩展、容错及输入格式松耦合。
        (3)数据单元
        按照数据的粒度大小,hive数据可以被组织成:
        1)databases: 避免不同表产生命名冲突的一种命名空间
        2)tables:具有相同scema的同质数据的集合
        3)partitions:一个表可以有一个或多个决定数据如何存储的partition key
        4)buckets(或clusters):在同一个partition中的数据可以根据某个列的hash值分为多个bucket。partition和bucket并非必要,但是它们能大大加快数据的查询速度。

        12、数据类型
        (1)简单类型:

    TINYINT - 1 byte integer
    SMALLINT - 2 byte integer
    INT - 4 byte integer
    BIGINT - 8 byte 
    BOOLEAN - TRUE/ FALSE
    FLOAT - 单精度
    DOUBLE - 双精度
    STRING - 字符串集合
        (2)复杂类型:
        Structs: structs内部的数据可以通过DOT(.)来存取,例如,表中一列c的类型为STRUCT{a INT; b INT},我们可以通过c.a来访问域a。
        Maps(Key-Value对):访问指定域可以通过['element name']进行,例如,一个Map M包含了一个group->gid的k-v对,gid的值可以通过M['group']来获取。
        Arrays:array中的数据为相同类型,例如,假如array A中元素['a','b','c'],则A[1]的值为'b'。

        13、内建运算符和函数

        包括关系运算符(A=B, A!=B, A<B等等)、算术运算符(A+B, A*B, A&B, A|B等等)、逻辑运算符(A&&B, A|B等等)、复杂类型上的运算符(A[n], M[key], S.x)、各种内建函数。

        14、语言能力
        hive查询语言提供基本的类sql操作,这些操作基于table和partition,包括:
        1. 使用where语句过滤制定行
        2. 使用select查找指定列
        3. join两张table
        4. group by
        5. 一个表的查询结果存入另一张表
        6. 将一个表的内容存入本地目录
        7. 将查询结果存储到hdfs上
        8. 管理table和partition(creat、drop、alert)
        9. 在查询中嵌入map-reduce程序

  • 相关阅读:
    PHP封装数据库连接
    MySQL和php数据访问
    php测试题
    微信分享缩略图
    js时间戳转时间格式
    php调用微信客服消息接口给用户发送信息
    ueditor富文本
    转:【CSS/JS学习】如何实现单行/多行文本溢出的省略(...)--老司机绕过坑道的正确姿势
    jq实现div移入与移出以及获得与失去焦点
    mysql索引
  • 原文地址:https://www.cnblogs.com/huangmr0811/p/5571016.html
Copyright © 2011-2022 走看看