Hive是什么原理搭建使用
hive是基于hadoop的数据仓库。
因为使用hadoop分析离线数据需要写mapreduce写这个巨麻烦所以hive这个框架就出现了。他通过写sql放到hive里面执行然后,通过hive的解析器来执行mapreduce代码然后最终得出结果,相当于本质就是用mapreduce做的,但是hive可以不仅仅是用mapreduce计算还可以使用spark他是基于内存的计算的比mapreduce基于io磁盘操作要快,但是存储最终还是依赖hadoop的hdfs。所以hive非常依赖hadoop。
hive通过命令行,或者页面客户端连接hive服务
hive分为客户端和服务端这个不用说肯定都知道,是服务肯定进行连接,有连接就有客户端。
hive除了依靠hdfs进行大数据的存储,他还有一个和数据的映射关系的存储,因为hdfs存储的类似如下文件
张三,18岁,三年级2班,2020-12-12
里斯,18岁,三年级2班,2020-12-12
就是存储的这种类似日志的文件内容 虽然格式是好的但是不想数据库有列。所以你需要在hive中定义列。
所以需要有一个数据库表来存第一列张三 里斯 代表name字段,第二列是age字段。
他这个映射关系是存储在关系型数据库里的,可以用hive连接mysql存储 这个叫hive的元数据。
他执行sql的时候需要去关系数据库找对应关系。
下面说一下hive的数据模型
就是在hdfs上是怎么存的。
一个fs路径就是一个数据库 比如 /user/hive/warehouse/abc.db
/user/hive/warehouse 是默认hive的路径default表默认在这个路径
下面有表
/user/hive/warehouse/abc.db/t_user
表下面有分区
/user/hive/warehouse/abc.db/t_user/2023。分区一般是时间等数据或者分类等等
分区下面有桶
分桶就是根据数据一个规则hash什么的拆分到不同的具体文件上就是上面 张三那种数据多个文件就根据一定规则存储多个没有规则存一个就是一个桶
就是这样存的hive原始数据
再说一下hive的服务端结构模型。 他有三种模式 我就说 远程模式。
因为他有元数据就是我说存mysql得那个映射关系数据,这个数据他需要一个服务操作所以他弄了一个服务来启动操作mysql中数据的服务 启动方式 hive --service matastore 这样一个操作元数据的方式就启动了
是这样的hive客户端有两个版本第一个是最早的就是hive cli 他可以直接操作matastore 上面这个元数据服务 缺点是 得有hive一堆东西跟着也不安全
第二版客户端升级了升级之后 hive在服务端搞了一个hiveserver2的一个服务 这个服务来连接matastore 然后向外暴露一个端口
启动方式是 hive --service2
然后可以用第二个客户端连接就是beeline cli hive4.0应该是默认用这个了 所以需要启动一个hive2的服务就是那个hiveserver2
连接的时候使用 语法如下。 !connect
这样你
hive安装
先关了防火墙防止出现端口不通的问题
因为hive需要借助hadoop的存储和mapreduce的计算
所以需要在hadoop的core-site.xml配置文件添加如下
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
其中注意root是用户 你的用户如果不是root就写成你的用户名字
意思就是允许任何用户任何主机以root用户操作权限 需要重启
安装hive 远程模式 其他模式就不管了
解压hive.tar.gz
往上说hive和hadoop的guava的jar包会冲突
解决办法把hadoop中common/lib下面的guavajar放到 hive的lib中
然后给hive添加mysql的驱动因为hive需要连接mysql也是放到hvie的lib目录下
配置hive环境变量
打开hive-env.xml
export HADOOP_HOME=/hadoop
export HIVE_CONF_DIR=/hive/conf
export HIVE_AUX_JARS_PATH=/hive/lib
打开hive-site.xml
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://ip:3306/hive?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=UTF-8</value>
<description>
JDBC connect string for a JDBC metastore.
To use SSL to encrypt/authenticate the connection, provide database-specific SSL flag in the connection URL.
For example, jdbc:postgresql://myhost/db?ssl=true for postgres database.
</description>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>Username to use against metastore database</description>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>数据库密码</value>
<description>password to use against metastore database</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
<property>
<name>hive.server2.thrift.bind.host</name>
<value></value>
</property>
<property>
<name>hive.metastore.uris</name>
<value>thrift://ip:9083</value>
</property>
<property>
<name>hive.metastore.uris</name>
<value>thrift://ip:9083</value>
</property>
<property>
<name>hive.metastore.event.db.notification.api.auth</name>
<value>false</value>
</property>
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
hive的metastore服务启动的之前需要先 创建mysql的表
schematool -initSchema -dbType mysql -verbos 执行之后就有表在mysql了
启动metastore服务
hive --service metastore
后台启动
nohup hive --service metastore &
服务成功启动jps会有一个runjar的进程
开启debug日志就是
hive --service metastore --hiveconf
hive.root.logger=DEBUG,console
上面就是元数据服务启动成功了
下面为了hive的beeline客户端可以使用需要在启动一个服务连接metastore服务
这个在启动的一个服务叫hiveserver2 ,beeline这个客户端是连接这个服务的
hiveserver1服务也有但是已经废弃了,现在用的都是hiveserver2 这个不能访问mysql要通过metastore服务
下面开始启动hiveserver2 启动要有顺序。先启动metastore在启动hiveserver2 因为有依赖关系
nohup hive --service hiveserver2 &
然后启动beelin客户端开始对hiveserver2进行连接命令行是
!connect jdbc:hive2://ip:10000
账号是root 密码可以直接确认
这个账号要具备hdfs权限密码可以是空的 就是前面在hadoop里面配置的那个账号
来个插曲 如果使用第一代客户端hive客户端那么可以其他机器上面解压hive然后配置文件加入
<property>
<name>hive.metastore.uris</name>
<value>thrift://ip:9083</value>
</property>
在启动hive客户端就可以直接连接上metastore服务了
hive开始使用基本语法创建库什么和mysql一样
使用hive创建库 创建表
然后把数据丢到hive表的文件下面就可以查出来数据但是这时候 还不能做关系映射
需要指定映射的分隔符
如下
create table t_user(id int,name varchar(255),age int)
row format delimited fields terminated by ',';
备注如果类型和文件中数据的字段类型映射不上就是null不会出现报错就是数据出不来,映射不上的字段出不来其他的没事
idea创建hive连接 创建好项目右边有database然后安装hive链接驱动
hive语法。建立表是最重要的
建表语法如下所示:
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name --表名
[(col_name data_type [COMMENT col_comment],
... [constraint_specification])] --列名 列数据类型
[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
] --分桶表分桶规则
[SKEWED BY (col_name, col_name, ...) ON ((col_value, col_value, ...), (col_value, col_value, ...), ...)
[STORED AS DIRECTORIES]
] --指定倾斜列和值
[
[ROW FORMAT row_format]
[STORED AS file_format]
| STORED BY 'storage.handler.class.name' [WITH SERDEPROPERTIES (...)]
] -- 指定行分隔符、存储文件格式或采用自定义存储格式
[LOCATION hdfs_path] -- 指定表的存储位置
[TBLPROPERTIES (property_name=property_value, ...)] --指定表的属性
[AS select_statement]; --从查询结果创建表
创建数据表解释说明:
1、 CREATE TABLE 创建一个指定名字的表。如果相同名字的表已经存在,则抛出异常;用户可以用 IF NOT EXISTS 选项来忽略这个异常。hive中的表可以分为内部表(托管表)和外部表,区别在于,外部表的数据不是有hive进行管理的,也就是说当删除外部表的时候,外部表的数据不会从hdfs中删除。而内部表是由hive进行管理的,在删除表的时候,数据也会删除。一般情况下,我们在创建外部表的时候会将表数据的存储路径定义在hive的数据仓库路径之外。hive创建表主要有三种方式,第一种直接使用create table命令,第二种使用create table ... as select...(会产生数据)。第三种使用create table tablename like exist_tablename命令。
2、 EXTERNAL关键字可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径(LOCATION),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部表,仅记录数据所在的路径,不对数据的位置做任何改变。在删除表的时候,内部表的元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。
3、 LIKE 允许用户复制现有的表结构,但是不复制数据。
4、 ROW FORMAT DELIMITED 不写使用默认的分隔符 就是‘\001’ 在vim中 ctrl+v ctrl+a 都可以出^A就是 \001 文本是SOH
[FIELDS TERMINATED BY char] 字段时间的分隔符
[COLLECTION ITEMS TERMINATED BY char] 集合元素之间分隔符
[MAP KEYS TERMINATED BY char] map映射kv之间分隔符
[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)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
7、create table命令介绍2
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [db_name] table_name LIKE existing_table_orview_name ---指定要创建的表和已经存在的表或者视图的名称。
[LOCATION hdfs_path] ---数据文件存储的hdfs文件地址信息。
8、CREATE [EXTERNAL] TABLE [IF NOT EXISTS]
[db_Name] table_name ---指定要创建的表名称
...指定partition&bucket等信息,指定数据分割符号。
[AS select_statement] ---导入的数据
这个上面的创建表的语句是从https://blog.csdn.net/m0_48758256/article/details/108647224 这个作者这里抄过来的
row format delimited 是用hive默认的类处理数据LazySimpleSerDe
来个创建表的demo。 基本数据类型的
create database if not exists 数据库名字;
use 数据库名字;
create table 表名字(
id int comment "id",
name string comment "名字",
name_age int comment "年龄",
) comment "表备注"
row format delimited
fields terminated by '\t'
上传表数据
hadoop fs -put 文件名字 fs的路径最后不用/
复杂数据类型的
创建表
create table 表名字(
id int,
name string,
map_name map<string,int>
) row format delimited
fields terminated by ',' --字段之间分隔符
collection items terminated by '-' --制定集合之间的分隔符
map keys terminated by ':'; --指定key value之间分隔符
)
内部表被hive完全管理
describe formatted 库.表
可以看表类型manage_table 就是内部表
创建表的时候不加create external table 就是内部表加了关键词就是外部表
外部表只管理元数据删除的时候不会删除数据 只删除元数据更安全
创建外部表不指定location 默认放到 hive路径 和内部是一样的 但是外部表删除的时候不会删除文件夹内部表会删除文件夹
创建分区表
create table 表名字(
id int comment "id",
name string comment "名字",
name_age int comment "年龄",
) comment "表备注"
partitioned by (字段名并且不能和上面的重复 string) --这个是分区意思就是fs下面的一个文件
row format delimited
fields terminated by '\t'
静态分区语句。 分区表在fs上面存储的不一样会是一个文件夹 然后是分区等于值可以过滤使用下面才是文件
load data local inpath ‘/路径/文件全名’ into table 表名字 partition(定义的分区字段名字='字段指定的值分区字段都是这个名字')
如果分区弄多个字段就是根据分区写的顺序 一层一层的创建文件夹 不断的嵌套不是并列的比如省份下的城市就是多分区 根据省份和城市分区 这个叫递进关系。
一个字段叫单分区表 多个分区字段叫多重分区
动态分区
开启动态分区
set hive.exec.dynamic.partition=true;
指定动态分区模式,分为nonstick非严格模式和strict严格模式
strict 严格模式要求至少有一个分区是静态分区
set hive.exec.dynamic.partition.mode=nonstrict;
执行insert select
select的表必须和insert的表字段要对应
因为创建表的时候分区字段在后面相当于创建表的时候多一个字段 那么执行insert的时候 就需要添加分区字段
比如
insert into 分区的表 partition(分区字段) select temp*,temp.某个需要根据分区的字段 from 临时表 as temp ;
分区写完了。开始写分桶
分区是分的是文件夹。分桶分的是真实的文件。
分桶建表语句
clustered by(创建表中的某个字段) [sorted by(表中某个字段 desc)] into 3 buckets.;
上面的3代表几个桶 【】中括号的语法可以添加可以不加加了会根据指定的排好序
桶功能需要开启
set hive.enforce.bucketing=true;
然后根据普通表的数据
insert into 创建好的分桶表 select * from 临时表;
分桶和动态分区一样需要从临时表把数据通过insert into select语法来做数据
解决笛卡尔积的问题 join 优化非常有效 链接的时候
事物表
没有begin那些
只支持orc格式文件默认事物配置是关系的需要开启
表必须是分桶的
表参数transactional=true
外部表不能成为acid表。不允许从非acid会话读取写入acid表
创建事物表
需要在分区创建的基础上
分区语法之后 as orc tblporperties('transactional='true'');
***使用事物之前配置
set hive.support.concurrency = true;--hive是否支持并发
set hive.enforce.bucketing=true;
set hive.exec.dynamic.partition.mode = nonstrict;
set hive.txn.manager = org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;--事物管理类
set hive.compactor.initiator.on =true; --是否在metastore实例上运行启动线程和清理线程
set hive.compactor.worker.threads =1;--在metastore实例上运行多少个压缩程序工作线程