Hive3 单机版(含Derby 多用户及Spark on Hive)

时间:2022-11-20 10:53:29

Hive3 单机版(含Derby 多用户)

DerbyDB

Derby是Java 编写的内存数据库,https://db.apache.org/derby/
它有两种运行模式:1、内嵌模式,单用户;2、网络模式,多用户

# 1. 下载
## 注意对应JDK 的版本
## https://db.apache.org/derby/releases/release-10_14_2_0.html

# 2. 安装
tar -xf db-derby-10.14.2.0-bin.tar.gz -C /opt/modules
cd /opt/modules && mv db-derby-10.14.2.0-bin derby-10.14.2.0
cd derby-10.14.2.0 && rm bin/*.bat

# 3. 启动
cd /opt/modules/derby-10.14.2.0 && bin/startNetworkServer -h 0.0.0.0
## 或放置后台
nohup /opt/modules/derby-10.14.2.0/bin/startNetworkServer -h 0.0.0.0 &
## 当前目录将作为derby 服务的根目录
## /opt/modules/derby-10.14.2.0 == derby://localhost:1527/

# 4. 使用
cd /opt/modules/derby-10.14.2.0
bin/ij  # 启动Derby 自带的客户端,help; 可查看帮助
ij> connect 'jdbc:derby://localhost:1527/data/testdb;create=true';
## 将会在/opt/modules/derby-10.14.2.0/data/ 下创建testdb 目录,用于存储testdb 的数据
create schema test;
create table test.tb1 (id int primary key, name varchar(20));
insert into test.tb1 values(1, 'Hotpepper');
select * from test.tb1;
## ID         |NAME
## --------------------------------
## 1          |Hotpepper

# 5. 停止
cd /opt/modules/derby-10.14.2.0 && bin/stopNetworkServer

# 6. 内嵌模式
## 以上是网络模式,支持多个客户端同时连接,而内嵌模式只支持一个客户端
## 先停止网络模式,使用以下命令进行内嵌模式的连接
cd /opt/modules/derby-10.14.2.0
bin/ij  # 启动Derby 自带的客户端
## 连接当前路径下的firstdb,没有则创建/opt/modules/derby-10.14.2.0/firstdb
ij> connect 'jdbc:derby:firstdb;create=true';
## 连接绝对路径下的/opt/modules/derby-10.14.2.0/data/testdb
ij> connect 'jdbc:derby:/opt/modules/derby-10.14.2.0/data/testdb;create=false';
## 另外,用网络模式创建的数据库也可以用内嵌模式连接,它们的格式是一样的,只是客户端连接方式不一样

Hadoop3

# 1. 下载
https://archive.apache.org/dist/hadoop/common/hadoop-3.1.3/hadoop-3.1.3.tar.gz

# 2. 安装
tar -xf hadoop-3.1.3.tar.gz
mv hadoop-3.1.3 /opt/modules/hadoop-3.1.3-pure
## 解压即可,无须其他配置,hive 调用mr 时默认会启动hadoop-local 模式

Hive3

BaseConf

# 1. 下载
https://dlcdn.apache.org/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gz
## hive 3.1.3 使用log4j 2.17.1,避免了JNDI 的漏洞

# 2. 安装
tar -xf apache-hive-3.1.3-bin.tar.gz -C /opt/modules
cd /opt/modules && mv apache-hive-3.1.3-bin hive-3.1.3

# 3. 修正
cd /opt/modules/hive-3.1.3/lib
mv guava-19.0.jar guava-19.0.jar.bak
cp /opt/modules/hadoop-3.1.3-pure/share/hadoop/common/lib/guava-27.0-jre.jar .
## guava 版本和Hadoop 一致才能正常运行

# 4. Derby 依赖
cd /opt/modules/hive-3.1.3/lib
cp /opt/modules/derby-10.14.2.0/lib/{derbyclient.jar,derbytools.jar} .
## 使用Derby 网络模式(多用户)时会用到

hive-env.sh

cat > /opt/modules/hive-3.1.3/conf/hive-env.sh << 'EOF'
export HADOOP_HOME=/opt/modules/hadoop-3.1.3-pure
EOF

hive-site.xml

单用户模式

使用Derby内嵌模式,指定本地文件系统,仅支持一个用户连接

cat > /opt/modules/hive-3.1.3/conf/hive-site.xml << 'EOF'
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <!-- Derby 内嵌模式元数据存储路径,不存在则自动创建 -->
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:derby:;databaseName=/opt/modules/localfs/hive_metastore;create=true</value>
  </property>
  <!-- Derby 内嵌模式的驱动类 -->
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>org.apache.derby.jdbc.EmbeddedDriver</value>
  </property>
  <!-- Derby 内嵌模式真实数据的本地存储路径 -->
  <property>
    <name>hive.metastore.warehouse.dir</name>
    <value>/opt/modules/localfs/hive_warehouse</value>
  </property>
  <!-- 查询结果显示列名 -->
  <property>
    <name>hive.cli.print.header</name>
    <value>true</value>
  </property>
  <!-- 显示当前数据库名称 -->
  <property>
    <name>hive.cli.print.current.db</name>
    <value>true</value>
  </property>
  <!-- 元数据检查,比较耗内存,测试时关闭,生产中须设为true -->
  <property>
    <name>hive.metastore.schema.verification</name>
    <value>false</value>
  </property>
  <!-- Metastore 服务地址,它是Hive2 之后提供元数据访问的进程 -->
  <!-- 如VALUE 为空即<value/>,Hive 则直连MySQL,无须启动Metastore 进程 -->
  <!--
  <property>
    <name>hive.metastore.uris</name>
    <value>thrift://0.0.0.0:9083</value>
  </property>
  -->
  <!-- HiveServer2 可让JDBC、Python 等向Hive 提交任务 -->
  <property>
    <name>hive.server2.thrift.bind.host</name>
    <value>0.0.0.0</value>
  </property>
  <property>
    <name>hive.server2.thrift.port</name>
    <value>10000</value>
  </property>
  <!--
    避免 Internal error processing get_current_notificationEventId
    或者在Hadoop 的core-site.xml 添加
    hadoop.proxyuser.hive.hosts=HS2_HOST
    hadoop.proxyuser.hive.groups=*
  -->
  <property>
    <name>hive.metastore.event.db.notification.api.auth</name>
    <value>false</value>
  </property>
</configuration>
EOF

多用户模式

使用Derby网络模式,支持多个用户同时使用

cat > /opt/modules/hive-3.1.3/conf/hive-site.xml << 'EOF'
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <!-- Derby 网络模式元数据存储路径,不存在则自动创建 -->
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:derby://localhost:1527/data/hive_metastore;create=true</value>
  </property>
  <!-- Derby 网络模式的驱动类 -->
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>org.apache.derby.jdbc.ClientDriver</value>
  </property>
  <!-- Derby 网络模式真实数据的本地存储路径 -->
  <property>
    <name>hive.metastore.warehouse.dir</name>
    <value>/opt/modules/derby-10.14.2.0/data/hive_warehouse</value>
  </property>

  <!-- 查询结果显示列名 -->
  <property>
    <name>hive.cli.print.header</name>
    <value>true</value>
  </property>
  <!-- 显示当前数据库名称 -->
  <property>
    <name>hive.cli.print.current.db</name>
    <value>true</value>
  </property>
  <!-- 元数据检查,比较耗内存,测试时关闭,生产中须设为true -->
  <property>
    <name>hive.metastore.schema.verification</name>
    <value>false</value>
  </property>

  <!-- Metastore 服务地址,它是Hive2 之后提供元数据访问的进程 -->
  <!-- 如VALUE 为空即<value/>,Hive 则直连MySQL,无须启动Metastore 进程 -->
  <!--
  <property>
    <name>hive.metastore.uris</name>
    <value>thrift://0.0.0.0:9083</value>
  </property>
  -->

  <!-- HiveServer2 可让JDBC、Python 等向Hive 提交任务 -->
  <property>
    <name>hive.server2.thrift.bind.host</name>
    <value>0.0.0.0</value>
  </property>
  <property>
    <name>hive.server2.thrift.port</name>
    <value>10000</value>
  </property>

  <!--
    避免 Internal error processing get_current_notificationEventId
    或者在Hadoop 的core-site.xml 添加
    hadoop.proxyuser.hive.hosts=HS2_HOST
    hadoop.proxyuser.hive.groups=*
  -->
  <property>
    <name>hive.metastore.event.db.notification.api.auth</name>
    <value>false</value>
  </property>
</configuration>
EOF

初始化元数据

# 删除旧的元数据目录
cd /opt/modules/localfs && rm -rf hive_metastore hive_warehouse
## 如果没有在hive-site.xml 中指定,默认Derby 会在hive 安装目录生成一个metastore_db

# 调用初始化元数据的工具
cd /opt/modules/hive-3.1.3 && bin/schematool -dbType derby -initSchema -verbose

简单测试SQL

-- 0. 启动Hive 客户端
cd /opt/modules/hive-3.1.2 && bin/hive

-- 1. 创建数据库
create database if not exists testdb;

-- 2. 使用数据库
use testdb;

-- 3. 创建表
drop table if exists tb1;
create table tb1(id int, name varchar(32));

-- 4. 插入数据
insert into tb1 values (1, "aaa"), (2, "bbb");

-- 5. 查询数据
select * from tb1;

-- 6. 删除数据库,cascade 表示级联强制删除有数据的库
use default;  -- 虽直接删除也可以,但还是切换一下好
drop database testdb cascade;

-- 7. 查看数据库列表
show databases;

-- 8. 退出Hive
quit;

启动后台服务

cd /opt/modules/hive-3.1.3

# 启动MetaStore
nohup bin/hive --service metastore &

# 启动HiveServer2,供第三方客户端连接,例如DBeaver
nohup bin/hive --service hiveserver2 &

DBeaver

连接Derby

# 内嵌模式
jdbc:derby:/opt/modules/localfs/hive_metastore;create=true

# 网络模式
jdbc:derby://localhost:1527/data/testdb;create=false

连接HS2

# 须HiveServer2 已启动,详见`启动后台服务`
jdbc:hive2://localhost:10000

Spark on Hive

# 0. 参考`Spark系列/PySpark/PySpark 单机版(含spark-submit).md`
## 创建Spark3 单机版,可以不设置`conf/spark-defaults.conf`

# 1. 拷贝hive-site.xml 到Spark3
cd /opt/modules/spark-3.1.3/conf
cp /opt/modules/hive-3.1.3/conf/hive-site.xml .

# 2. 拷贝Derby 数据库的连接驱动
cd /opt/modules/spark-3.1.3/jars
cp /opt/modules/derby-10.14.2.0/lib/{derbyclient.jar,derbytools.jar} .

# 3. 验证Spark on Hive
cd /opt/modules/spark-3.1.3
bin/spark-sql -e "show databases; show tables;" 
bin/spark-sql -e "select * from testdb.tb2"
## 多条语句用分号分隔,单条语句就不用分号了

# 4. 注意!hive.metastore.warehouse.dir(hive-site.xml) 会被
## spark.sql.warehouse.dir(spark-defaults.conf) 覆盖(如果有的话)
## https://spark.apache.org/docs/latest/sql-data-sources-hive-tables.html
## Note that the hive.metastore.warehouse.dir property in hive-site.xml is deprecated since Spark 2.0.0. Instead, use spark.sql.warehouse.dir to specify the default location of database in warehouse. You may need to grant write privilege to the user who starts the Spark application.

已知问题

重启Hive 才能查到新数据

有时候会出现,通常在创建新表时,存储使用parquet格式时
推荐使用Spark on Hive,参考上面的章节配置

-- 0. 启动hive
bin/hive

-- 1. 创建parquet 表
use testdb;
create table tb2(id int, name varchar(32)) stored as parquet;

-- 2. 插入新数据
use testdb;
insert into tb2 values (1, 'aa'), (2, 'bb'), (3, 'cc');
insert into tb2 values (4, 'dd');
insert into testdb.tb2 values (5, 'ee');

-- 3. 查询报错
select * from testdb.tb2;
select count(*) from tb2 where id > 0;

-- 4. 重启hive
quit;
bin/hive

-- 5. 查询成功
select count(*) from testdb.tb2 where id > 0;

-- 6. HiveServer2
-- HS2 也有类似的情况,需要重启HS2,再在DBeaver 上重新连接即可查询到数据

参考资料

Local/Embedded Metastore Database (Derby)
Configure Hive to Use Network Derby
Derby 数据库简单介绍和使用方法