hive学习笔记(版本2.3.5)

1,621 阅读8分钟

hive.apache.org 顶级项目

hive产生的原因

不是所有进行数据分析的人都是程序员,而且MapReduce写起来有成本。说白了就是用SQL进行数据分析HDFS里的东西。

元数据是最值钱的。spark利用了hive的metastore

hive简介

  • 数据仓库
  • 解释器(sql),编译器(转换成MR),优化器等
  • hive运行需要元数据(表的元数据),存在mysql中(基本都用mysql)

hdfs中数据的元数据还是NameNode里的

hive架构

hive架构

  • 用户接口
    • 命令行(CLI),CLI启动的时候会启动一个hive副本(这个副本是metastore client 去连接元数据)
    • jdbc
    • WebUI,没人用
  • hive讲元数据存在关系型数据库中,基本都用mysql。元数据包含表的名字,表的列,分区及属性。表是否为managerTable(内部表,自管理的表)或externalTable。表的数据存放目录。
  • 编译器,优化器,执行器完成HQL的分析。
  • hive的数据在hdfs中,大部分查询由MR完成。(包含*的查询,比如select * from tbl不会生成MapRedcue任务)

hive搭建模式

使用内置的内存数据库Derby

An embedded metastore database is mainly used for unit tests. Only one process can connect to the metastore database at a time, so it is not really a practical solution but works well for unit tests.就是说只适合单元测试。

通过网络连接到MySQL中,经常用到的模式

In this configuration, you would use a traditional standalone RDBMS server. The following example configuration will set up a metastore in a MySQL server. This configuration of metastore database is recommended for any real use.

使用thrift通过metastore server访问元数据

In remote metastore setup, all Hive Clients will make a connection to a metastore server which in turn queries the datastore (MySQL in this example) for metadata. Metastore server and client communicate using Thrift Protocol. Starting with Hive 0.5.0, you can start a Thrift server by executing the following command:hive --service metastore默认端口9083

搭建

客户端连接metastore服务,metastore再去连接MySQL数据库来存取元数据。有了metastore服务,就可以有多个HIVE客户端同时连接,而且这些客户端不需要知道MySQL数据库的用户名和密码,只需要连接metastore 服务即可。

  • 找两台机器node1,node2一个装server 一个作为客户端。metastore服务端需要有mysql驱动包
  • 修改hive-default.xml.templatehive-site.xml,把配置删除干净了.,$-1d
        <property>
                <name>hive.metastore.warehouse.dir</name>
                <value>/user/hive_remote/warehouse</value>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionURL</name>
                <value>jdbc:mysql://node01:3306/hive_remote?createDatabaseIfNotExist=true</value>
        </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>
        </property>
        <property>
                <name>javax.jdo.option.ConnectionPassword</name>
                <value>123</value>
        </property>
	<property>
		<name>hive.metastore.warehouse.dir</name>
		<value>/user/hive_remote/warehouse</value>
	</property>
	<property>
		<name>hive.metastore.uris</name>
		<value>thrift://node03:9083</value>
	</property>

服务端执行元数据库的初始化操作,schematool -dbType mysql -initSchema

hive sql

  • 默认进入的是default库。并且这个库不能drop
  • desc formatted psn formatted是看表的详细信息。
  • 在metastore中也能看到 hive表和列的信息。
  • insert into xxx values 是map操作。
  • 默认分隔符是^A
  • hive 数据类型
  • 字符串类型string
  • 支持array、map、struct 字符串等等

DDL

文档

  • 建表语句
1,小明1,lol-book-movie,beijing:mashibing-shanghai:pudong
2,小明2,lol-book-movie,beijing:mashibing-shanghai:pudong
3,小明3,lol-book-movie,beijing:mashibing-shanghai:pudong
4,小明4,lol-book-movie,beijing:mashibing-shanghai:pudong
5,小明5,lol-movie,beijing:mashibing-shanghai:pudong
6,小明6,lol-book-movie,beijing:mashibing-shanghai:pudong
7,小明7,lol-book,beijing:mashibing-shanghai:pudong
8,小明8,lol-book,beijing:mashibing-shanghai:pudong
9,小明9,lol-book-movie,beijing:mashibing-shanghai:pudong
create table psn
(id int, name string, likes array<string>, address map<string,string>) 
row format delimited 
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
lines terminated by '\n'
;
  • 查看表信息desc xxx。详细信息desc formatted xxx
  • 插入数据DML
  • load是纯的copy操作。
--local 代表是从本地 上传一份数据。不加local 代表是数据在hdfs中
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
--实操
load data local inpath '/opt/hive-2.3.5/data.txt' into table psn;

如果向/user/hive_remote/warehouse/psn 中上传文件 这个数据会被psn表查出来。 写时检查,读时检查

  • insert overwrite local directory ‘本地路径文件’ select ...插入 查询结果 到本地的文件
  • insert overwrite table tablename select ...把查询结果插入到一个表中

内部表外部表(managed external)

Managed vs External

create external table psn1
(id int, name string, likes array<string>, address map<string,string>)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
lines terminated by '\n'
--表的位置 对应hdfs
--只要这个目录有数据,就能映射到hive表
location '/data';
  • 内部表create table xxx 删除表时会把数据删掉。默认建的表就是内部表
  • 外部表create external table xxx 删除表的时候数据不会删,只删元数据。
  • 外部表可以先有数据,再有表。

分区表

create table psn2
(id int, name string, likes array<string>, address map<string,string>)
--本身就是一个字段
partitioned by (gender string)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
lines terminated by '\n';
--load指定分区
load data local inpath '/opt/hive-2.3.5/data.txt' into table psn2 partition(gender='man');

--多分区表 gender age
create table psn3
(id int, name string, likes array<string>, address map<string,string>)
partitioned by (gender string,age int)
row format delimited
fields terminated by ','
collection items terminated by '-'
map keys terminated by ':'
lines terminated by '\n';
--load 时 必须两个分区都指定上。分区的顺序是可以换的,它不是按照顺序来的。
load data local inpath '/opt/hive-2.3.5/data.txt' into table psn3 partition(gender='man',age=12);
  • 添加分区列
alter table psn3 add partition(gender='girl');
--FAILED: ValidationFailureSemanticException partition spec {gender=girl} doesn't contain all (2) partition columns
--需要指定所有的分区列
  • 删除表的分区列的时候 会把所有分区都删除了。
alter table psn3 drop partition(age='12');
--Dropped the partition gender=girl/age=12
--Dropped the partition gender=man/age=12
--OK
  • 在实际工作中控制分区的力度。分区是为了提高查询效率的例如按天分区。

修复分区

手动建的分区目录。但是元数据里没有记录 所以 需要修复分区

hive> msck repair table psn4;
OK
Partitions not in metastore:	psn4:age=10	psn4:age=12
Repair: Added partition to metastore psn4:age=10
Repair: Added partition to metastore psn4:age=12
Time taken: 0.313 seconds, Fetched: 3 row(s)

msck repair

动态分区

删除和更新数据,需要配置。

hive 支持事务!,但是没有提交和回滚操作。(潜台词就是别进行删除和更新数据) 表还需要分桶才行 等等一系列条件。

hive serde

serializer and deserilizer 序列化和反序列化 插入的时候写正则

hiveserver2

  • 如果要用jdbc连接hive 那么需要hiveserver2

HiveServer2 (HS2) is a server interface that enables remote clients to execute queries against Hive and retrieve the results (a more detailed intro here). The current implementation, based on Thrift RPC, is an improved version of HiveServer and supports multi-client concurrency and authentication. It is designed to provide better support for open API clients like JDBC and ODBC.

hiveserver2的搭建和使用

数据量大小 数据条数 即每条多大

为什么有hiveserver2?
hiveserver2作为一个服务端 (同时又是 metastore server 的客户端)。
能够让多个客户端通过hiveserver2来进行数据的分析
比如java程序 jdbc
beeline客户端。也是通过jdbc连接的。一般只允许查询!
不论是hive 还是hiveserver2 都是通过配置文件找的元数据服务

官网推荐在生产环境使用hiveserver2

在搭建hiveserver2服务的时候需要修改hdfs的超级用户的管理权限,修改配置如下

<!--在hdfs集群的core-site.xml文件中添加如下配置文件-->
	<property>
		<name>hadoop.proxyuser.root.groups</name>	
		<value>*</value>
    </property>
    <property>
		<name>hadoop.proxyuser.root.hosts</name>	
		<value>*</value>
    </property>
<!--配置完成之后重新启动集群,或者在namenode的节点上执行如下命令-->
	hdfs dfsadmin -fs hdfs://node1:8020 -refreshSuperUserGroupsConfiguration
	hdfs dfsadmin -fs hdfs://node2:8020 -refreshSuperUserGroupsConfiguration

hive函数

用的时候查就行。

行转列
name  subject   score
zs    yuwen     100
zs    wuli      20 
zs    yingyu    80
ls    yuwen     98
ls    wuli      39 
ls    yingyu    67
========================
想要的效果
name  yuwen   yingyu   wuli
zs    100     80        20
ls    98      67        39
========================
select name,
sum(case when subject = 'yuwen' then score else 0 end),
sum(case when subject = 'yingyu' then score else 0 end),
sum(case when subject = 'wuli' then score else 0 end)
from cj
group by name;
  • UDAF 多对一 聚合函数
  • UDTF 一对多 例如explode
  • UDF 一进一出 用户自定义函数
  • 脱敏函数、身份证15位转18位函数。等等
--用hive 来进行Wordcount
select m.word,count(m.word) from 
  (select explode(split(str ,' ')) as word from wc) as m
group by m.word;

hive的参数操作和运行方式

  • hive查询没有表头 启动hive cli的时候 加参数hive --hiveconf hive.cli.print.header=true只在当前会话有效。
  • cli 中 set命令 看见所有配置。命令行中修改配置set hive.cli.print.header=true
  • 在用户的家目录中有一个隐藏文件叫.hivehistoryhive操作的历史记录
  • 在用户家目录中创建一个隐藏文件.hiverc 里面可以写语句和set等操作。 这样hive启动的时候会读取,并执行。