AmosCloud

Library

Have a Question?

If you have any question you can ask below or enter what you are looking for!

Hive

Hive

一、是什么

  • Hive是Hadoop生态中的一个数据仓库工具用于海量数据的分析,Hive可以将HDFS上的文件映射为关系表,使用HiveSQL对HDFS数据进行处理,Hive底层使用MapReduce完成计算。

  • data base 数据库

    • 体量:关系型数据库通过通过库、表将中大型数据管理为关系表
    • 速度:提供低延迟的数据增(insert)删(delete)改(update)查(select)操作
  • data warehouse 数据仓库

    • 体量:将数据库不能存储的更海量的数据进行管理
    • 速度:提供更高延迟的数据库增(insert)查(select)操作

二、Hive的安装和使用

  • 关于版本:
    生产环境主流版本:
    1.2.x (兼容Spark2.x)
    2.3.x (兼容Spark3.x)
    最新版本3.x

  • 当前安装选择版本为2.3.9
    apache-hive-2.3.9-bin.tar.gz

  • Hive需要使用HDFS和Mysql

  1. Centos安装mysql

    1. 下载
      https://dev.mysql.com/downloads/mysql/

    2. 执行安装脚本

#!/bin/bash
echo -e "\033[4;40;31m欢迎使用mysql离线安装自动化脚本 v1.0\033[0m"
echo -e "\033[4;40;31m作者:Amos QQ:410507803 E-Mail:amos@amoscloud.com\033[0m\n"

read -p "请输入mysql8的zx压缩包文件所在路径(eg:/opt/mysql8.xxx.xz):" FILE_PATH
read -p "请输入想要安装的目录(eg:/usr/local/mysql):" DEST_PATH

rpm -e --nodeps $(rpm -qa | grep mariadb)

echo -e "\033[40;32m   (1/13)正在解压,请耐心等待解压过程约1-3分钟... \033[0m"
tar Jxf $FILE_PATH -C .
echo -e "\033[40;32m   解压完成 \033[0m"

echo -e "\033[40;32m   (2/13)移动加压后的文件到$DEST_PATH \033[0m"
mv mysql-8*x86_64 $DEST_PATH

echo -e "\033[40;32m   (3/13)添加环境变量$DEST_PATH \033[0m"
echo "export MYSQL_HOME=$DEST_PATH" >>/etc/profile
echo 'export PATH=.:$MYSQL_HOME/bin:$PATH' >>/etc/profile
source /etc/profile

echo -e "\033[40;32m   (4/13)创建data目录 \033[0m"
mkdir $DEST_PATH/data

echo -e "\033[40;32m   (5/13)创建my.cnf配置文件 \033[0m"
rm -rf /etc/my.cnf
echo "
[client]
port=3306
socket=/tmp/mysql.sock
[mysqld]
port=3306
user=mysql
socket=/tmp/mysql.sock
basedir=$DEST_PATH
datadir=$DEST_PATH/data
log-error=$DEST_PATH/error.log
pid-file = $DEST_PATH/mysql.pid
transaction_isolation = READ-COMMITTED
character-set-server = utf8
collation-server = utf8_general_ci
lower_case_table_names = 1
" > /etc/my.cnf
echo 'sql_mode = "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"' >> /etc/my.cnf

echo -e "\033[40;32m   (6/13)创建mysql组 \033[0m"
groupadd mysql

echo -e "\033[40;32m   (7/13)创建mysql用户并加入mysql组 \033[0m"
useradd -g mysql mysql

echo -e "\033[40;32m   (8/13)修改安装目录权限和所有者 \033[0m"
chown -R mysql:mysql $DEST_PATH
chmod -R 755 $DEST_PATH

echo -e "\033[40;32m   (9/13)初始化mysql \033[0m"
$DEST_PATH/bin/mysqld --initialize --user=mysql

echo -e "\033[40;32m   (10/13)尝试启动mysql \033[0m"
$DEST_PATH/support-files/mysql.server start

echo -e "\033[40;32m   (11/13)将mysqld添加为服务并设置开机自启动 \033[0m"
cp $DEST_PATH/support-files/mysql.server /etc/init.d/mysqld
chmod 755 /etc/init.d/mysqld
chkconfig --add mysqld
chkconfig --level 345 mysqld on

echo -e "\033[40;32m   (12/13)重启mysql \033[0m"
service mysqld restart

echo -e "\033[40;32m   (13/13)读取临时密码 \033[0m"
TEMP_PW=$(cat $DEST_PATH/error.log | grep 'password' | awk -F' ' '{print $NF}')

echo -e "

\033[40;32m  mysql的初始临时密码为:$TEMP_PW \033[0m

\033[40;32m  使用初始密码登录mysql后,您可以使用如下SQL修改初始密码: \033[0m
\033[40;33m  ALTER user 'root'@'localhost' IDENTIFIED BY 'a123456'; \033[0m

\033[40;32m  使用如下SQL添加可远程访问的root用户: \033[0m
\033[40;33m  CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password  BY 'a123456'; \033[0m
\033[40;33m  GRANT ALL ON *.* TO 'root'@'%'; \033[0m
\033[40;33m  FLUSH PRIVILEGES; \033[0m

\033[40;32m  3秒后将使用初始密码登录mysql,感谢您的使用 \033[0m
"

sleep 3

mysql -uroot -p$TEMP_PW
  1. 测试使用
mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interfa                         ce can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or                          its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current                          input statement.

mysql>
  1. Hive下载解压改名

    • bin
hive # hive的客户端
beeline # jdbc客户端 用于连接hiveserver2
hiveserver2 # 启动一个JDBC服务端
schematool # 模板初始化工具

ext # 外部命令,如果需要将Hive添加到其他的框架和组件中,可以直接将ext中的命令复制到其他组件的bin目录
hive-config.sh # 查看Hive的配置
hplsql # sql的辅助工具
metatool # 元数据管理工具
  1. 修改配置文件
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
  <property>
   <name>javax.jdo.option.ConnectionURL</name>
   <value>jdbc:mysql://node01:3306/metastore?createDatabaseIfNotExist=true</value>
  </property>
    <property>
   <name>javax.jdo.option.ConnectionDriverName</name>
   <value>com.mysql.cj.jdbc.Driver</value>
  </property>
    <property>
     <name>javax.jdo.option.ConnectionUserName</name>
     <value>root</value>
  </property>
  <property>
     <name>javax.jdo.option.ConnectionPassword</name>
     <value>123456</value>
  </property>
</configuration>
  • hive-env.sh
    # 配置Hadoop环境变量
    HADOOP_HOME=/opt/hadoop-2.7.7
    # 设置hive配置文件所在目录
    export HIVE_CONF_DIR=/opt/hive-2.3.9/conf
    # 设置JVM环境
    JAVA_HOME=/opt/jdk1.8.0_291
  1. 配置环境变量

  2. 将Mysql驱动jar包上传到Hive安装中的lib目录
    https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.25

  3. 使用Hive的schematool初始化metastore

schematool -initSchema -dbType mysql
[root@node01 bin]# schematool -initSchema -dbType mysql
Metastore connection URL:        jdbc:mysql://node01:3306/metastore?createDatabaseIfNotExist=true
Metastore Connection Driver :    com.mysql.cj.jdbc.Driver
Metastore connection User:       root
Starting metastore schema initialization to 2.3.0
Initialization script hive-schema-2.3.0.mysql.sql
Initialization script completed
schemaTool completed
  1. 测试客户端
    # 使用bin目录中的hive命令启动Hive客户端
    hive

三、Hive操作

  • Hive允许使用HiveSQL直接对HDFS上的数据进行操作

  • Hive默认将HiveSQL翻译成MR任务并执行

  • Hive2.x之后的版本也支持将Hive的计算引擎替换为Spark或者Tez

  • SQL(Struct Query Language)

    • DDL(建库建表)
    • DML(库和表的修改)
    • DQL(查询)
    • DCL

3.1 DDL

    • hive默认使用hdfs的/user/hive/warehouse作为自己的默认数据库,直接在default中创建的表 会在/user/hive/warehouse直接存放
-- 创建数据库
create database 库名 [location <path>];
-- 删除数据库
drop database 库名 [cascade];
-- 查看库信息
desc database db2;
-- CREATE  外部   TABLE   如果不存在    表名
CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_name
-- (列名  数据类型 ,列名  数据类型,列名  数据类型... )
[(col_name data_type [COMMENT col_comment], ...)]
-- 给表加注释
[COMMENT table_comment]
-- 为hive的表设置分区
[PARTITIONED BY (col_name data_type [COMMENT col_comment], ...)]
-- 设置hive表为支持分桶操作
-- 设置按哪些字段进行分桶(对应MR的分区器)
[CLUSTERED BY (col_name, col_name, ...)
-- 设置分桶时,直接对某些字段进行排序(对应MR,Mapper输出的key的排序方式)
[SORTED BY (col_name [ASC|DESC], ...)]
-- 设置输出为几个文件(对应MR的reducer的线程数)
INTO num_buckets BUCKETS]
-- 行格式化
[[ROW FORMAT ]
DELIMITED
-- 设置字段结束的字符
-- 常用的为\t 也可能使用一些特殊字符,避免让分割字符出现在字段内容中,hive默认使用'\u0001'字符作为分隔符
[FIELDS TERMINATED BY char]
-- 设置集合元素结束的字符 通常使用','
[COLLECTION ITEMS TERMINATED BY char]
-- 设置map结构中key结束的字符 通常使用':'
[MAP KEYS TERMINATED BY char]
-- 设置一行数据的结束字符 通常使用'\n'
[LINES TERMINATED BY char]]
-- STORED AS 指定存储文件类型
-- 常用的存储文件类型:SEQUENCEFILE(二进制序列文件)、TEXTFILE(文本)、ORCFILE(列式存储格式文件)
-- 如果文件数据是纯文本,可以使用STORED AS TEXTFILE。如果数据需要压缩,使用 STORED AS SEQUENCEFILE。
[STORED AS file_format]
-- 指定表存储的位置
[LOCATION hdfs_path]
  • 分区表的创建和使用
-- 创建一级分区表
create table t_weblog_par(value string)
partitioned by (dt string);

-- 创建二级分区
create table t_weblog_par2(value string)
partitioned by (month string,day string);
-- 加载数据到二级分区
load data local inpath '/root/logs/access.log-20210701' into table t_weblog_par2 partition (month='2021-07',day='01');

hive客户的特殊操作

  1. hive客户端中提供了直接使用linux本地命令的方式

    # 语法: !本地命令;
    ! ls /root;
  2. hive客户端中提供了直接使用hdfs命令的方式

    # 语法: dfs -命令 ;
    dfs -ls /;

hive的配置

  • hive默认配置
    hive安装目录下conf中有 hive-default.xml中包含hive的所有默认配置

  • hive的自定义配置
    安装hive时通常会创建hive-site.xml,在其中设置需要的配置项,hive-site.xml的优先级高于hive-default.xml

  • hive在客户端内临时修改配置

-- 查看当前hive客户端的所有配置
set;
-- 查看某个具体参数的配置情况
set name;
-- 例如
set hive.cli.print.header;
-- 可以在当前客户端中临时修改所有配置
set name=value;
-- 例如
set hive.cli.print.header=false;

四、Hive的核心概念

4.1 内部表外部表

  • 内部表(管理表):删除表时会直接删除HDFS上对应的数据文件
  • 外部表:删除表示仅删除表结构信息,不修改HDFS上的原始文件
  • 查看表的类型:
    desc extended 表名;
    desc formatted 表名;
    Table Type:             MANAGED_TABLE
    Table Type:             EXTERNAL_TABLE

4.2 分区表

  • 将表分成多个文件夹

  • 出现原因:
    Hive中每个表对应HDFS一个目录,如果将文件直接放在表目录中,当需要查询表中的部分数据时,每次都需要加载全表数据,造成没必要的性能消耗

  • 解决方案:
    由于Hive底层运行MR或者SparkCore,所以每次读取数据时,只能直接指定到文件或目录,无法在文件内部进行筛选,此时我们可以将hive的表查分成多个子目录,按照条件将数据加载到不同的子目录中,执行HQL时,只需要使用where加分区字段的方式,就可以直接从子目录中加载部分数据,避免全表查询

4.3 分桶表

  • 将表分为多个文件
-- hive数据清洗
-- 准备数据表
-- ip time rcode up down

create table t_extracted_weblog as select
    t1.fields[0] ip,
    substr(t1.fields[3],2) time,
    t1.fields[8] rcode,
    t1.fields[9] up,
    t1.fields[size(t1.fields)-1] down
from(
    select split(value,' ') fields from t_weblog_par
    ) t1
;

-- 创建分桶表
create table t_weblog_bucketed(
     `ip` string,
     `time` string,
     `rcode` string,
     `up` string,
     `down` string)
-- 按照ip分桶
     clustered by (ip)
-- 按照up的降序进行桶内排序
    sorted by (up desc)
    into 10 BUCKETS;

-- insert into table 表名 select语句
-- 将后面select语句的查询结构插入到前面的表中
-- select语句的查询结构字段需要与前表字段名和类型一致
insert into table t_weblog_bucketed select * from t_extracted_weblog limit 10;
  • 如果在hive 1.x或者2.x早期版本中
    可能会存在创建的分桶表,但是插入数据时,没有对数据进行文件的划分,原因是,默认hive执行MR设置的mapreduce.job.reduces=-1,此时需要将mapreduce.job.reduces设置为需要分桶的个数
set mapreduce.job.reduces=10;