精华内容
下载资源
问答
  • Hive详解

    2018-08-04 13:45:43
    hive详解      
    展开全文
  • HIVE详解

    千次阅读 2017-12-19 13:28:01
    HIVE详解HIVE基本概念HIVE简介什么是hive?hive是基于hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。为什么使用Hive直接使用hadoop所面临的问题:​ 人员学习成本太高...

    HIVE详解

    HIVE基本概念

    HIVE简介

    什么是hive?

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

    为什么使用Hive

    直接使用hadoop所面临的问题:

    ​ 人员学习成本太高

    ​ 项目周期要求太短

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

    为什么使用HIve

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

    ​ 避免去屑MapReduce,减少开发人员的学习成本

    ​ 扩展功能很方便

    Hive的特点

    可扩展:

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

    延展性:

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

    容错:

    ​ 良好的容错性,节点出现问题SQL仍然可以执行。

    Hive架构

    架构图

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

    TaskTracker相当于:NodeManager+yarnchild

    基本组成

    ​ 用户接口:包括CLI、JDBC/ODBC、WebGUI。

    ​ 元数据存储:通常是储存在关系数据库如mysql,derby中

    ​ 解释器、编译器、优化器、执行器。

    各组建基本功能

    用户接口主要由三个:CLI、JDBC/ODBC和webGUI。其中,CLI为shell命令行;JDBC/ODBC是HIVE的JAVA实现,与传统数据库JDBC类似;WebGUI是通过浏览器访问HIVE。

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

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

    Hive与Hadoop的关系

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

    Hive与传统数据库对比

    Hive RDBMS
    查询语言 HQL
    数据存储 HDFS
    MapReduce
    执行延迟
    处理数据规模
    索引 0.8版本之后加入位图索引

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

    Hive的数据存储

    1.Hive中所有的数据都存储在HDFS中,没有专业的数据储存格式(可支持Text,SequenceFile,ParquetFile,RCFILE等)

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

    3.Hive中包含以下数据模型:DB,Table,External table,Partition,Bucket。

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

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

    ​ external table:外部表,与table类似,不过其数据存放位置可以指定任意路径。普通标删除之后,hdfs上的文件都删了。

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

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

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

    Hive使用

    hive交互shell

    bin/hive

    Hive thrift服务

    启动方式:

    启动为前台:

    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//YOURIP:10000

    方式(2):

    启动时直接连接:

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

    HIVE基本操作

    DDL操作

    创建表

    建表语法:

    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 BUCKERTS]
    
    [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采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在那个桶中。

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

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

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

    具体实例

    创建外部表mytable

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

    创建外部表

    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.7.1:9000/user/hive/warehouse';

    创建分区表invites

    create table student_p(sno int,snamr string,sex string,sage int,sdept string) partitioned by(part string) row format delimited fields terminated by ',' stored as textfile;

    创建带桶的表

    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 ',';

    修改表

    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 partiotion(part='a') partition(part='b')

    命名表

    语法结构

    ALTER TABLE table_name RENAME TO new_table_name

    具体实例:

    alter table mytable rename to mystudent;

    增加/更新列

    语法结构

    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]

    显示命令

    show tables
    show databases
    show partitions
    show functions
    desc extended t_name;
    desc formatted table_name;

    DML操作

    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关键字

    ​ 如果指定了Local,load命令回去查找本地文件系统中的filepath。

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

    ​ 4.Overwrite关键字

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

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

    具体实例:

    加载相对路径数据

    load data local inpath 'buckets.txt' into table student patition{stat_data='20131231'}

    加载绝对路径的数据

    load data local inpath '/root/app/datafile/buckets.txt' into table student partition(stat_date='20131231')

    加载包含模式数据

    load data local inpath 'hdfs://192.168.11.191:9000/user/hive/warehouse/student/stat_data=20131230/bucket.txt' into table student partition(stat_date='20131230');

    overwrite关键字使用:

    load data inpath 'buckets.txt' overwrite into table studnet partition{stat_data='20131230'};

    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
    

    导出表数据

    语法结构:

    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] ...
    
    

    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]
    

    注:

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

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

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

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

    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)
        是错误的

    注意:现在有一些书说可以实现不等值连接

    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.key作为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.

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

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

    例如

    select a.val,b.val,c.val from a
        join b om (a.key = b.key) join c on (c.key = b.key1)
        所有表都使用相同一个join.key(使用一次map/reduce任务计算)。Reduce端会缓存a表和b表的记录,然后每次取得一个C表的记录就计算一次join结果。
    

    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记录时也会输出。

    Hive参数配置方式

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

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

    ​ 配置文件

    ​ 命令行参数

    ​ 参数声明

    配置文件:hive的配置文件包括:

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

    ​ 默认配置文件:$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建立以前就已经完成了。

    Hive自定义函数和Transform

    当hive提供的内置函数无法满足你的业务需要处理时,此时就可以考虑使用用户自定义函数(UDF:user-defined fuction)

    自定义函数类别

    UDF作用于单个数据行,产生一个数据行作为输出行。(数学函数,字符串函数)UDAF(用户自定义聚集函数):接受多个输入数据行,并产生一个输出数据行。

    UDF开发实例

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

    package com.mingming.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包添加hive的classpath

    hive>JAR /home/hadoop/udf.ajr

    4.创建临时函数与开发的java calss关联

    Hive>create temporary function toLower as ‘com.mingming.udf.Lower’

    5.即可在hql中使用自定义的函数toLower

    select toLower(name),age from t_test;

    Transform实现

    hive的Transform关键字提供饿了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])
    
    展开全文
  • hive详解

    2019-06-17 21:11:45
    工作流程:HIVE先定义一张表(这张表的结构和字段数据都存储在MYSQL或DERBY数据库中,这张表的信息就是元数据),再从本地或是HDFS上将文件加载到HIVE,通过mapreduce对数据进行计算,最后输出到HDFS上,形成一个或...

    一.什么是HIVE:

    Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。
    工作流程:HIVE先定义一张表(这张表的结构和字段数据都存储在MYSQL或DERBY数据库中,这张表的信息就是元数据),再从本地或是HDFS上将文件加载到HIVE,通过mapreduce对数据进行计算,最后输出到HDFS上,形成一个或多个文件。最后用户可通过sql语句对HIVE进行查询。

    1.什么是数据仓库:(针对大数据)

    数据仓库是面向主题的,是对历史数据进行分析的。默认情况下只能读取数据,不能修改删除。侧重于分析,决策。

    2.hive的安装模式:(元数据存放数据库,一般选择本地模式,如何安装,请看另一篇博客)

    1.内嵌模式:使用derby数据库,为hive自带数据库,只能允许一次会话连接。
    2.本地模式:使用mysql数据库
    3.远程模式

    二.HIVE和MapReduce的对比:

    MapReduce缺点:

    1.人员学习成本太高
    2.项目周期要求太短
    3.MapReduce实现复杂查询逻辑开发难度太大

    HIVE的优势:

    1.可扩展 :Hive可以自由的扩展集群的规模,一般情况下不需要重启服务。
    2.延展性 :Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。
    3.容错: 良好的容错性,节点出现问题SQL仍可完成执行。

    HIVE基本组成:(了解)

    1.用户接口:包括 CLI、JDBC/ODBC、WebGUI。
    2.元数据存储:通常是存储在关系数据库如 mysql , derby中。
    3.解释器、编译器、优化器、执行器。
    4.用户接口主要由三个:CLI、JDBC/ODBC和WebGUI。其中,CLI为shell命令行;JDBC/ODBC是Hive的JAVA实现,与传统数据库JDBC类似;WebGUI是通过浏览器访问Hive。
    5.元数据存储:Hive 将元数据存储在数据库中。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表等),表的数据所在目录等
    6.解释器、编译器、优化器完成 HQL 查询语句从词法分析、语法分析、编译、优化以及查询计划的生成。生成的查询计划存储在 HDFS 中,并在随后有 MapReduce 调用执行。

    工作图:
    |在这里插入图片描述
    三.HIVE的基本操作:

    hive表中字段类型:
    1.基本类型:数值类型(int,float,double),boolean,string,时间类型
    2.数组类型:array<>,如name array<string>
    3.map类型:map<key:value>
    4.struct类型:struct<key1:value1,key2:value2>

    1.表的创建:(最基本,类似于MYSQL)

    CREATE [TEMPORARY] TABLE t_uer(id int,name string,hobby arrary<strring>) ROW FOMAT DELIMITED FIELDS TERMINATED BY "\t" COLLECTION ITEMS TERMINATED BY "," MAP KEYS TERMINATED BY ":"//创建一张名为t_user的表,[]中的可不要
    

    2.分区:(提高数据查询效率)

    CREATE [TEMPORARY] TABLE t_uer(id int,name string,hobby arrary<strring>) PARTITIONED BY (gender int) ROW FOMAT DELIMITED FIELDS TERMINATED BY "\t" COLLECTION ITEMS TERMINATED BY "," MAP KEYS TERMINATED BY ":"//以gender作为分区标准,也是一个字段。
    

    3.分桶:

    CREATE [TEMPORARY] TABLE t_uer(id int,name string,age int,hobby arrary<strring>) CLUSTERED BY (age) INTO 5 BUCKETS ROW FOMAT DELIMITED FIELDS TERMINATED BY "\t" COLLECTION ITEMS TERMINATED BY "," MAP KEYS TERMINATED BY ":"//以age为分桶,分5个
    

    四.为什么要进行分区分桶:

    hive是一个数据仓库,针对的是大数据,但每次进行sql查询的时候,会对表中所有数据进行遍历导致效率相对低,所以通过分区分桶,可将数据进行限定范围的查询。分区的时候,会形成一个类似于文件夹的目录,暂且就称之为目录,一张表会有一个或多个这样的目录,但可能出现数据倾斜度。分桶则直接形成多个文件,由自己分桶时定义,并按类的hash值将数据进行分散存储,可解决数据倾斜度过大。分区后可继续进行分桶。

    五.加载数据:
    分区:HDFS上加载不需要local,LINUX需要

    LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
    

    分桶:
    1.创建一张临时表t_tmp,将数据load进去

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

    2.用insert插入到分桶的表中,会启动mapreduce

    LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE t_tmp
    set hive.enforce.bucketing=true;//开启分桶支持
    insert into tablename select * from t_tmp
    

    六.自定义函数中的UDF,分为3种:

    在这里插入图片描述

    展开全文
  • hive详解之hive数据存储 hive数据存储格式 HIve的文件存储格式有四种:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET,前面两种是行式存储,后面两种是列式存储;所谓的存储格式就是在Hive建表的时候指定的将表中的...

    hive详解之hive数据存储

    hive数据存储格式

    HIve的文件存储格式有四种:TEXTFILE 、SEQUENCEFILE、ORC、PARQUET,前面两种是行式存储,后面两种是列式存储;所谓的存储格式就是在Hive建表的时候指定的将表中的数据按照什么样子的存储方式,如果指定了A方式,那么在向表中插入数据的时候,将会使用该方式向HDFS中添加相应的数据类型。
    
    如果为textfile的文件格式,直接load就OK,不需要走MapReduce;如果是其他的类型就需要走MapReduce了,因为其他的类型都涉及到了文件的压缩,这需要借助MapReduce的压缩方式来实现。
    
    只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据。
    
    比对三种主流的文件存储格式TEXTFILE 、ORC、PARQUET
    
    压缩比:ORC >  Parquet >  textFile(textfile没有进行压缩)
    

    压缩比案例

    1,textfile,创建表,存储数据格式为TEXTFILE
    create table log_text (
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
    )
    row format delimited fields terminated by '\t'
    stored as textfile ;
     
    向表中加载数据
     
    load data local inpath '/opt/module/datas/log.data' into table log_text ;
    查看表中数据大小
     
    这个过程不会走MapReduce,而是直接将文件上传到了HDFS,在HDFS上文件的名字还叫log.data
    dfs -du -h /user/hive/warehouse/db_hive.db/log_text;
    18.1 M  /user/hive/warehouse/db_hive.db/log_text/log.data
    
    2,ORC,创建表,存储数据格式为ORC
    create table log_orc(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
    )
    row format delimited fields terminated by '\t'
    stored as orc ;
     
    向表中加载数据
    insert into table log_orc select * from log_text ;
     
    查看表中数据大小
    这个过程要走MapReduce,而且文件是按照列式存储的,还会对文件进行压缩,Orc默认使用的压缩方式是
    zlib因此会更加节省空间,hadfs上是新的文件名,
     
    hive (db_hive)> dfs -du -h /user/hive/warehouse/db_hive.db/log_orc;
    2.8 M  /user/hive/warehouse/db_hive.db/log_orc/000000_0
     
     
    3,Parquet,创建表,存储数据格式为parquet
    create table log_parquet(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
    )
    row format delimited fields terminated by '\t'
    stored as parquet ; 
     
    向表中加载数据
    insert into table log_parquet select * from log_text ;
     
    查看表中数据大小这个过程要走MapReduce,而且文件是按照列式存储的,因此会更加节省空间,
    hadfs上是新的文件名,
    hive (db_hive)> dfs -du -h /user/hive/warehouse/db_hive.db/log_parquet;
    13.1 M  /user/hive/warehouse/db_hive.db/log_parquet/000000_0
     
    存储文件的压缩比总结:
    ORC >  Parquet >  textFile
     
     
    select count(*) from log_text;
     
    select count(*) from log_orc;
     
    select count(*) from log_parquet;
     
    由于本身数据有点少,存储文件的查询速度总结:查询速度相近。
    

    解释:hdfs dfs -du -h 输出三列数据的含义

    命令 hdfs dfs -du -h /data/

    结果 102.3 M 307.0 M /data/

    第一列标示该目录下总文件大小

    第二列标示该目录下所有文件在集群上的总存储大小和你的副本数相关,我的副本数是3 ,所以

    第二列的是第一列的三倍 (第二列内容=文件大小*副本数)

    第三列标示你查询的目录

    自定义压缩格式

    在建表的时候,如果我们指定了列式存储的方式,他会默认使用对于的压缩方式将我们的数据进行压缩,与此同时我们能够自己定制在文件存储的时候使用什么样子的压缩方式,例子如下:

    1.创建一个非压缩的的ORC存储方式
    create table log_orc_none(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
    )
    row format delimited fields terminated by '\t'
    stored as orc tblproperties ("orc.compress"="NONE");
    插入数据
    hive (default)> insert into table log_orc_none select * from log_text ;
     
    2.创建一个SNAPPY压缩的ORC存储方式
    create table log_orc_snappy(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
    )
    row format delimited fields terminated by '\t'
    stored as orc tblproperties ("orc.compress"="SNAPPY");
    插入数据
    hive (default)> insert into table log_orc_snappy select * from log_text ;
     
    3.创建一个默认压缩的ORC存储方式
    create table log_orc(
    track_time string,
    url string,
    session_id string,
    referer string,
    ip string,
    end_user_id string,
    city_id string
    )
    row format delimited fields terminated by '\t'
    stored as orc ;
     
    向表中加载数据
    insert into table log_orc select * from log_text ;
     
    对比三者的压缩比:
     
    hive (db_hive)> dfs -du -h /user/hive/warehouse/db_hive.db/log_orc_none;
    18.1 M  /user/hive/warehouse/db_hive.db/log_orc_none/log.data
     
    hive (db_hive)> dfs -du -h /user/hive/warehouse/db_hive.db/log_orc_snappy;
    3.8 M  /user/hive/warehouse/db_hive.db/log_orc_snappy/000000_0
     
    hive (db_hive)> dfs -du -h /user/hive/warehouse/db_hive.db/log_orc;
    2.8 M  /user/hive/warehouse/db_hive.db/log_orc/000000_0
     
    总结:
    没有压缩的orc格式相当于textfile,默认的压缩格式压缩比最大,snappy对数据进行了压缩
    orc存储文件默认采用ZLIB压缩,ZLIB采用的是deflate压缩算法。因此比snappy压缩的小。
    文件没有压缩的话,HDFS上显示的是原来的文件名,如果压缩的话,使用类似于000000_0的文件名
    

    解释:TBLPROPERTIES

    实际上就是table properties,TBLPROPERTIES允许开发者定义一些自己的键值对信息。可以对TBLPROPERTIES进行查看和修改(部分可修改)。在TBLPROPERTIES中有一些预定义信息,比如last_modified_user和last_modified_time,其他的一些预定义信息包括:
    
    TBLPROPERTIES ("comment"="table_comment")
    TBLPROPERTIES ("hbase.table.name"="table_name")
    TBLPROPERTIES ("immutable"="true") or ("immutable"="false") 
    TBLPROPERTIES ("orc.compress"="ZLIB") or ("orc.compress"="SNAPPY") or ("orc.compress"="NONE")
    TBLPROPERTIES ("transactional"="true") or ("transactional"="false")
    TBLPROPERTIES ("NO_AUTO_COMPACTION"="true") or ("NO_AUTO_COMPACTION"="false"), the default is "false" 
    TBLPROPERTIES ("compactor.mapreduce.map.memory.mb"="mapper_memory") 
    TBLPROPERTIES ("compactorthreshold.hive.compactor.delta.num.threshold"="threshold_num") 
    TBLPROPERTIES ("compactorthreshold.hive.compactor.delta.pct.threshold"="threshold_pct") 
    TBLPROPERTIES ("auto.purge"="true") or ("auto.purge"="false") 
    TBLPROPERTIES ("EXTERNAL"="TRUE") 
    

    (1)comment:可以用来定义表的描述信息

    (2)hbase.table.name:hive通过 storage handler(暂放)将hive与各种工具联系起来,这是是使用hive接入hbase时,设置的属性(暂放)

    (3)immutable:顾名思义‘不可变的’,当表的这个属性为true时,若表中无数据时可以insert数据,但是当表已经有数据时,insert操作会失败。不可变表用来防止意外更新,避免因脚本错误导致的多次更新,而没有报错。本人实际中还没用到这个属性。

    (4)orc.compress:这是orc存储格式表的一个属性,用来指定orc存储的压缩方式(暂放)。

    (5) transactional,NO_AUTO_COMPACTION,compactor.mapreduce.map.memory.mb, compactorthreshold.hive.compactor.delta.num.threshold, compactorthreshold.hive.compactor.delta.pct.threshold:这5个属性与hive的事务支持有关,先不做了解。

    (6)auto.purge:当设置为ture时,删除或者覆盖的数据会不经过回收站,直接被删除。配置了此属性会影响到这些操作: Drop Table, Drop Partitions, Truncate Table,Insert Overwrite.

    (7)EXTERNAL:通过修改此属性可以实现内部表和外部表的转化。

    修改tblproperties

    ALTER TABLE table_name SET TBLPROPERTIES (property_name = property_value, property_name = property_value, ... );
    

    hive数据模型

    Hive 中所有的数据都存储在 HDFS 中,Hive 中包含以下数据模型:Table,External Table,Partition,Bucket即内部表、外部表、分区表和桶表。

    内部表

    内部表也称为管理表。因为这种表,Hive会或多或少地控制数据的生命周期。Hive默认情况下回将这些表的数据存储在由配置项hive.metastore.warehouse.dir所定义的目录(比如/user/hive/warehouse)的子目录下。

    如果我有一个表test,那么在HDFS中会创建/user/hive/warehouse/test目录(这里假定hive.metastore.warehouse.dir配置为/user/hive/warehouse);test表所对应的所有数据都存放在这个目录中。

    如果删除这张表,则表在关系数据中存储的元数据以及在warehouse目录下的数据也会被清除掉。

    同时管理表不方便与其他工作共享数据。例如我们有一份由Pig或者其他工具创建并且主要由这一工具使用的数据,同时我们还想使用Hive在这份数据上执行一些查询,可是并没有给予Hive对数据的所有权,我们可以创建一个外部表指向这份数据,而并不需要对其具有所有权。

    外部表

    为了避免潜在产生混淆的可能性,如果用户不想使用默认的表路径,那么最好是使用外部表。

    外部表可以读取指定目录下的以逗号为分隔的数据:

    CREATE EXTERNAL TABLE IF NOT EXISTS stocks(
     exchange   STRING,
     symbol     STRING,
     ymd        STRING,
     price_open FLOAT,
     price_high FLOAT,
     volume     INT,
     price_adj_close  FLOAT)
    ROW FORMAT DELIMITED FIFLDS TERMINATED BY ',' --逗号分隔文件
    LOCATION '/data/stocks'  --指定Hive数据的路径
    

    因为表是外部的,所以Hive并非认为完全拥有这份数据,从而删除该表的时候不会删除这份数据。不过描述表的元数据信息会被删除掉。

    内部表和外部表的区别

    1.未被external修饰的是内部表(managed table),被external修饰的为外部表(external table)

    2.Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。

    3.在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。这样外部表相对来说更加安全些,数据组织也更加灵活,方便共享源数据。

    4.内部表数据由Hive自身管理,外部表数据由HDFS管理;内部表数据存储的位置是hive.metastore.warehouse.dir(默认:/user/hive/warehouse),外部表数据的存储位置由自己制定(如果没有LOCATION,Hive将在HDFS上的/user/hive/warehouse文件夹下以外部表的表名创建一个文件夹,并将属于这个表的数据存放在这里);

    5.对内部表的修改会将修改直接同步给元数据,而对外部表的表结构和分区进行修改,则需要修复(MSCK REPAIR TABLE table_name;)

    对于什么时候使用外部表,什么时候内部表,并没有一个固定的规范,通过最近一段时间的观察,大概总结了一下几点:

    1.做etl处理时,通常会选择内部表做中间表,因为清理时,会将HDFS上的文件同时删除

    2.如果怕误删数据,可以选择外部表,因为不会删除文件,方便恢复数据

    3.如果对数据的处理都是通过hql语句完成,选择内部表,如果有其他工具一同处理,选择外部表

    借鉴学习:

    https://blog.csdn.net/qq_36743482/article/details/78393678?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

    分区表

    分区表用于水平分散压力,将数据从物理上转移到和使用最频繁的用户更近的地方。分区是以字段的形式在表结构中存在,通过describe table命令可以查看到字段存在, 但是该字段不存放实际的数据内容,仅仅是分区的表示(伪列)。分区分为静态分区和动态分区

    (1)静态分区

    静态分区表:所谓的静态分区表指的就是,我们在创建表的时候,就已经给该表中的数据定义好了数据类型,在进行加载数据的时候,我们已经知道该数据属于什么类型,并且直接加载到该分区内就可以了。来看一个简单的分区表的创建语句(这里创建的是一张内部表):

    create table if not exists sopdm.wyp2(id int,name string,tel string)
    
    partitioned by(age int)
    
    row format delimited
    
    fields terminated by ','
    
    stored as textfile;
    

    –overwrite是覆盖,into是追加

    insert into table sopdm.wyp2
    
    partition(age='25')
    
    select id,name,tel from sopdm.wyp;
    

    (2)动态分区
    动态分区表:所谓的动态分区表,其实建表方式跟静态分区表没有区别,最主要的区别是在载入数据的时候,静态分区表我们载入数据之前必须保证该分区存在,并且我么已经明确知道载入的数据的类型,知道要将数据加载到那个分区当中去,而动态分区表,在载入的时候,我们事先并不知道该条数据属于哪一类,而是需要hive自己去判断该数据属于哪一类,并将该条数据加载到对应的目录中去。建表语句跟静态分区表的建表语句相同,这里不再赘述,主要来看看数据的加载:

    –设置为true表示开启动态分区功能(默认为false)

    set hive.exec.dynamic.partition=true;

    –设置为nonstrict,表示允许所有分区都是动态的(默认为strict)

    set hive.exec.dynamic.partition.mode=nonstrict;

    –insert overwrite是覆盖,insert into是追加

    set hive.exec.dynamic.partition.mode=nonstrict;

    insert overwrite table sopdm.wyp2
    
    partition(age)
    
    select id,name,tel,age from sopdm.wyp;
    

    分桶表

    分桶之前要执行命令set hive.enforce.bucketiong=true;

    CREATE TABLE bucketed_user (id INT) name STRING)
    
    CLUSTERED BY (id) INTO 4 BUCKETS;
    

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

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

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

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

    分区又分桶

    可以对数据表分区之后继续分桶。

    img

    但是分区之后继续分桶,我们在hdfs文件系统上看不出分桶的多个数据表文件,只能看见一个文件,但是能从文件路径上看出分区的信息。
    img
    看看分区又分桶的查询结果:
    img

    展开全文
  • Apache hive详解

    千次阅读 2018-05-28 18:20:03
    Apache hive详解1. Apache hive 简介1.1 什么是HiveHive是基于hadoop的一个数据仓库工具,可以将结构化数据文件映射为一张数据库表,并提供类SQL查询功能.Hive的本质是将SQL装换为MapReduce程序;主要用途:用来做离线...
  • Hive详解
  • 大数据之Hive详解

    千人学习 2019-08-06 10:28:57
    Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。是hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类SQL查询功能。本质是将HQL转化成...
  • 大数据技术Hbase和Hive详解,今天给大家介绍一下关于零基础学习大数据之HBASE和HIVE是多么重要的技术,那么两者有什么区别呢?下面我们一起来看一下吧。 ApacheHive是一个构建在hadoop基础设施之上的数据仓库。通过...
  • hive详解ppt

    2016-03-22 17:19:32
    hive详细介绍ppt
  • 11_离线计算系统_第11天(HIVE详解)v.2 学习必备;1、熟练掌握hive的使用 2、熟练掌握hql的编写 3、理解hive的工作原理 4、具备hive应用实战能力
  • 大数据之Hive详解 资深大数据、java讲师,十年开发经验,曾经任职于北大...
  • HBase集成Hive详解

    2020-08-25 12:56:29
    Hive提供了与HBase的集成,使得能够在HBase表上使用hive sql 语句进行查询、插入操作以及进行Join和Union等复杂查询,同时也可以将hive表中的数据映射到Hbase中。 一、HBase与Hive的对比 Hive 数据仓库 Hive...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,433
精华内容 4,573
关键字:

hive详解