Hive 学习笔记一(介绍,架构,运行机制,与传统数据库对比,下载安装,DDL操作)

一、Hive简介

1.什么是Hive

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

2.为什么使用Hive

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

②避免了去写MapReduce。

③扩展功能很方便。

3.Hive的特点

①可扩展

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

②延展性

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

③容错

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

二、Hive架构


Hive的体系结构包括以下几个部分:

1.用户接口:包括shell命令、Jdbc/Odbc和WebUi,其中最常用的是shell这个客户端方式对Hive进行相应操作。

2.Hive解析器(驱动Driver):Hive解析器的核心功能就是根据用户编写的Sql语法匹配出相应的MapReduce模板,形成对应的MapReduce job进行执行。

3.Hive元数据库(MetaStore):Hive将表中的元数据信息存储在数据库中,如derby(自带的)、Mysql(实际工作中配置的),Hive中的元数据信息包括表的名字、表的列和分区、表的属性(是否为外部表等)、表的数据所在的目录等。Hive中的解析器在运行的时候会读取元数据库MetaStore中的相关信息。 

Hive包含以下数据模型:

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

    Table:在HDFS中表现为所属DB目录下一个文件夹。

    Exteranl Table:与Table类似,不过其存放位置可以在任意指定路径。

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

    Bucket:在hdfs中表现为同一个表目录下根据hash散列之后的多个文件。

 HIve之所以配置新数据库Mysql而不是使用自带的derby数据库,是因为derby的局限性:derby不允许用户打开多个客户端对其进行共享操作,同一时刻只能有一个用户使用它。 

4.Hadoop:Hive用HDFS进行存储,用MapReduce进行计算——-Hive这个数据仓库的数据存储在HDFS中,业务实际分析计算是利用MapReduce执行的。 

从上面的体系结构中可以看出,在Hadoop的HDFS与MapReduce以及MySql的辅助下,Hive其实就是利用Hive解析器将用户的SQl语句解析成对应的MapReduce程序而已,即Hive仅仅是一个客户端工具,这也是为什么我们在Hive的搭建过程中没有分布与伪分布搭建的原因。

三、运行机制


Hive的运行机制正如图所示:创建完表之后,用户只需要根据业务需求编写Sql语句,而后将由Hive框架将Sql语句解析成对应的MapReduce程序,通过MapReduce计算框架运行job,便得到了我们最终的分析结果。 

在Hive的运行过程中,用户只需要创建表、导入数据、编写Sql分析语句即可,剩下的过程将由Hive框架自动完成,而创建表、导入数据、编写Sql分析语句其实就是数据库的知识了。

四、Hive与传统数据库的对比


1.查询语言:由于SQL被广泛的应用在数据仓库中,因此,专门针对Hive设计出了类SQL的查询语句HQL。

2.数据的存储位置:Hive是建立在Hadoop上的,所有的Hive的数据都是存储在HDFS上,而本地数据库则可以将数据保存在块设备或者本地文件系统中。

3.数据格式:Hive中没有定义专门的数据格式,数据格式可以由用户执行,用户定义数据格式需要制定三个属性:列分隔符(空格,"\t","\x001"等),行分隔符("\n"等),以及读取数据的方法(三种默认格式:TextFile,SequenceFile,RCFile)。

由于在加载数据过程中,不需要从用户数据格式到Hive定义的数据格式转换,因此Hive在加载过程中不会对数据本身进行修改,只是将数据内容复制或移动到相应的HDFS目录下。

传统数据库中,不同的数据库有不同的存储引擎,定义了自己的数据格式,所有的数据都会按照一定的组织存储,因此数据库加载数据的过程会比较耗时。

4.数据更新。由于Hive是针对数据仓库应用设计的,而数据仓库的内容是读多写少的。因此,Hive不支持对数据的修改(1.2版本支持添加数据)。而传统数据库中的数据通常需要经常修改,可是添加和修改数据。

5.索引。Hive在加载数据的时候不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些key建立索引。Hive要访问数据中满足条件的特定值时,需要暴力扫描整个数据,因此访问延迟高,但是Hive使用了MapReduce,可以并行访问数据,在大数据量的访问方面,相对于传统数据库仍保持着优势。

传统数据库通常会针对一个或者几个列建立索引,对于少量的特定条件的数据的访问,数据库可以由很高的效率,很低的延迟。

6.Hive具备传统数据库的外表,但是应用场景完全不同,Hive只适合用来对批量数据进行统计和分析。

五、Hive的下载,安装,与配置

需要: JDK(1.7版本以上)

            MySql

            Hadoop

下载:http://hive.apache.org/

安装:直接于linux下解压即可。

配置:

1.配置HIVE_HOME的环境变量:

export HIVE_HOME=/hive #hive为hive的安装地址
export PATH=${HIVE_HOME}/bin:$PATH #将HIVE_HOME配置到path中,linux应使用":"分割。

2.修改Hive的配置文件:

进入配置文件的目录。

①复制修改hive-env.sh文件。

cp hive-env.sh.template hive-env.sh
#将以下内容写入:
export JAVA_HOME=/export/servers/jdk
export HADOOP_HOME=/export/servers/hadoop
export HIVE_HOME=/export/servers/hive

②修改log4j文件。

cp hive-log4j.properties.template hive-log4j.properties
#使用vim的搜索功能找到EventCounter,修改成org.apache.hadoop.log.metrics.EventCounter

③创建并修改hive-site.xml文件。

touch hive-site.xml
<!--将以下信息写入到hive-site.xml文件中-->
<configuration>
        <property>
                <name>javax.jdo.option.ConnectionURL</name>
                <value>jdbc:mysql://hadoop02:3306/hivedb?createDatabaseIfNotExist=true</value><!--hadoop2为mysql地址-->
        </property>
        <property>
                <name>javax.jdo.option.ConnectionDriverName</name>
                <value>com.mysql.jdbc.Driver</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionUserName</name>
                <value>root</value><!--mysql的账号-->
        </property>
        <property>
                <name>javax.jdo.option.ConnectionPassword</name>
                <value>root</value><!--mysql的密码-->
        </property>
</configuration>

3.在MySql中创建hive的元数据库。

create table hivedb

4.确认MySql对hive所使用的账号密码授权。

grant all privileges on *.* to root@"%" identified by "root" with grant option;
grant all privileges on *.* to root@"localhost" identified by "root" with grant option;

5.输入hive启动Hive。

附录:

1.启用Hive时出现Terminal initialization failed; falling back to unsupported
    将hadoop目录下的/share/hadoop/yarn/lib/jline-0.09*.jar
替换为hive目录下的/lib/jline2.12.jar
2.需要将MySql的驱动放入到Hive的lib目录下
3.出现异常:
Logging initialized using configuration in jar:file:/export/servers/apache-hive-2.0.0-bin/lib/hive-common-2.0.0.jar!/hive-log4j2.properties
Exception in thread "main" java.lang.RuntimeException: Hive metastore database is not initialized. Please use schematool (e.g. ./schematool -initSchema -dbType ...) to create the schema. If needed, don't forget to include the option to auto-create the underlying database in your JDBC connection string (e.g. ?createDatabaseIfNotExist=true for mysql)
处理方法:
     schematool -dbType mysql -initSchema

六、Hive的使用

1.打开客户端:

①bin/shell

②Hive thrift服务

启动为前台:bin/hiveserver2
启动为后台:nohup bin/hiveserver2 1>/var/log/hiveserver.log2>/var/log/hiveserver.err & #启用Hiveserver2时根据成功或失败分别将日志写入不同的文件内。
启动成功后,可以在别的节点上用beeline去连接
方式(1)
hive/bin/beeline  回车,进入beeline的命令界面
输入命令连接hiveserver2
beeline> !connect jdbc:hive2//mini1:10000
(hadoop01是hiveserver2所启动的那台主机名,端口默认是10000)
方式(2)
启动就连接:
bin/beeline -u jdbc:hive2://mini1:10000 -n hadoop

2.基本使用

①DDL操作:数据定义语言,用来管理数据库。

    建表操作:

    hive创建表有三种方式:

    第一种:

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 选项来忽略这个异常。
    EXTERNAL关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
2.COMMMENT ''
可以添加对表的描述信息。
3.PARTITIONED BY()
按照属性进行分区。
Hive Select查询中一般会扫描整个表内容,会消耗很多时间做没必要的工作。有时候只需要扫描表中关心的一部分数据,因此建表时引入了partition概念。
4.CLUSTERED BY
对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分。Hive也是 针对某一列进行桶的组织。Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中。 
把表(或者分区)组织成桶(Bucket)有两个理由:
(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive 在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
5.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 确定表的具体的列的数据。
6.STORED AS 
SEQUENCEFILE|TEXTFILE|RCFILE
如果文件数据是纯文本,可以使用 STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
7.见1中的EXTERNAL说明。

 


第二种:

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
  LIKE existing_table_or_view_name
  [LOCATION hdfs_path];

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


第三种

CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
[AS select_statement];

1.AS只会复制属性以及属性值到新的表中。

2.使用AS创建的表,并不会带原表的分区(分区丢失),包括一些字段的约束等(可以通过describe formatted查看)。

3.新表中会将原表的分区作为字段出现在新表中。



修改表
增加分区
ALTER TABLE table_name ADD [IF NOT EXISTS] partition_spec [ LOCATION 'location1' ] partition_spec [ LOCATION 'location2' ] ...
partition_spec:  
(partition_col = partition_col_value, partition_col = partiton_col_value, ...)


重命名分区
ALTER TABLE table_name PARTITION partition_spec RENAME TO PARTITION partition_spec;  
partition_spec:  
  :(partition_col = partition_col_value, partition_col = partiton_col_value, ...) 

交换分区
ALTER TABLEtable_name_1 EXCHANGE PARTITION (partition_spec) WITH TABLE table_name_2;

该语句允许将一个分区中的数据移动另一个拥有相同schema但没有那个分区的表中。

恢复分区

Hive在元存储中为每个表存储了一个分区列表,然而如果新分区直接添加到HDFS中(使用hadoop fs –put),Hive不会知道这些分区,除非在每个新添加的分区上执行ALTER TABLEtable_name ADD PARTITION命令。为了避免重复执行上述命令,可以使用如下的命令:

MSCK REPAIR TABLE table_name;



删除分区

ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec,PARTITION partition_spec,... 
可以使用上述语句删除表的分区,该语句将会删除指定分区的数据和元数据。对于受NO DROP CASCADE的表,可以使用IGNORE PROTECTION删除指定的分区或一组分区,该语句如下:
ALTER TABLE table_name DROP [IF EXISTS] PARTITION partition_spec IGNORE PROTECTION;


接档/归档分区
ALTER TABLE table_name ARCHIVE PARTITION partition_spec;  
ALTER TABLE table_name UNARCHIVE PARTITION partition_spec;

Hive中的归档移动分区中的文件到Hadoop归档中(HAR),该语句只会减少文件的数量,但不提供压缩。

修改表/分区的文件格式
ALTER TABLE table_name [PARTITION partitionSpec] SET FILEFORMAT file_format

可以使用上述语句修改表或者分区的文件格式,Hive支持的文件格式有:SEQUENCEFILE、TEXTFILE、RCFILE 、ORC和INPUTFORMAT input_format_classnameOUTPUTFORMAT output_format_classname,默认的文件格式为TEXTFILE,由配置参数hive.default.fileformat指定。TEXTFILE指以纯文本文件存储数据,在数据需要压缩时使用SEQUENCEFILE,使用INPUTFORMAT和OUTPUTFORMAT指定输入格式和输出格式的类名,比如'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextInputFormat'。

修改表/分区的位置
ALTER TABLE table_name [PARTITIONpartitionSpec] SET LOCATION "newlocation" 
修改表/分区的Touch

TOUCH读元数据,然后写回。这能够触发前置或者后者hook的执行,假设是存在一个记录表或者分区修改的hook和直接修改HDFS上文件的外部脚本。由于外部脚本在Hive之外修改文件,修改不会被hook所记录,这是外部脚本可以调用TOUCH以触发hook,然后标记上述表或者分区为已修改的。修改表或者分区的TOUCH语句如下:

ALTER TABLE table_name TOUCH [PARTITION partitionSpec]; 
修改表/分区的保护

可以在表级或者分区级设置数据保护。启用NO_DROP将保护表或者分区被删除,启用OFFLINE将阻止表或者分区中的数据被查询,但元数据依然可以被访问。如果表中的任何分区启用了NO_DROP,该表也不能被删除。修改表或者分区保护的语句如下:

ALTER TABLE table_name [PARTITION partition_spec] ENABLE|DISABLE NO_DROP;  
ALTER TABLE table_name [PARTITION partition_spec] ENABLE|DISABLE OFFLINE;
重命名表
ALTER TABLE table_name RENAME TO new_table_name 
修改表的属性
ALTER TABLE table_name SET TBLPROPERTIES (property_name = property_value, property_name = property_value,... )

使用该语句可以增加表的元数据,last_modified_by, last_modified_time属性自动被添加和管理,可以使用DESCRIBE EXTENDED table_name查询新增的表属性。

修改表的注释

要修改表的注释,只需要使用上面介绍的修改表属性语句,将property_name指定为'comment' 属性即可:

ALTER TABLE table_name SET TBLPROPERTIES('comment' = new_comment); 
增加SerDe属性

增加SerDe属性的语句为:

ALTER TABLE table_name SET SERDE serde_class_name [WITH SERDEPROPERTIES serde_properties]  
ALTER TABLE table_name SET SERDEPROPERTIES  
(property_name = property_value,property_name = property_value, ... ) 

该语句允许向SerDe对象增加自定义的元数据。SerDe属性在SerDe被Hive初始化时传递给表的SerDe。

修改标的存储属性
ALTER TABLE table_name CLUSTEREDBY (col_name, col_name, ...) [SORTED BY (col_name, ...)] INTO num_buckets BUCKETS

该语句改变表的物理存储属性。

需要注意的时,上述修改表的语句仅修改表的Hive的元数据,不会重新组织或者重新格式化现存数据,用户需要确定实际的数据布局符合元数据的定义。

修改列名/类型/位置/注释

下面的语句允许修改列名称、列类型、列注释、列位置。该语句仅修改Hive元数据,不会触动表中的数据,用户需要确定实际的数据布局符合元数据的定义。

ALTER TABLE table_name CHANGE [COLUMN] col_old_name col_new_name column_type [COMMENTcol_comment] [FIRST|(AFTER column_name)]  


增加/替换/删除列

增加或者替换列的语句如下,其中ADD COLUMNS在现有列之后但在分区列之前增加新列,REPLACE COLUMNS先删除现存列,然后再增加新列。替换列只能在表使用自带SerDe(DynamicSerDe,MetadataTypedColumnsetSerDe, LazySimpleSerDe and ColumnarSerDe)时使用。

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

该语句也可以被用来删除列。




参考资料:hive 创建表的三种方式     Hive学习之修改表、分区、列

猜你喜欢

转载自blog.csdn.net/qq_38344394/article/details/80604047
今日推荐