hive是一个基于hadoop的数据仓库工具,将结构化数据映射为一张表,提供类SQL查询功能。这里可以理解为它架构在Hadoop之上,可以将类sql语句(hive支持的HQL)转换为MapReduce任务进行运行,就可以避免复杂的mapreduce编程。
hive的一些性质:
(1)优点:
(2)缺点
一个一个解释图中的模块:
1)用户接口:Client
负责CLI(Command-line interface)、JDBC/ODBC(jdbc访问hive)、WEBUI(浏览器访问hive)。
2)元数据:MetaStore
元数据包括:表名、表所属的数据库、表的拥有者、列/分区字段、表的类型、表的数据所在目录。
3)hadoop
使用HDFS存储、使用mapreduce进行计算。
4)驱动器:driver
综合来看,hive一次任务的执行就是:hive收到客户端用户的指令(SQL),使用自己的Driver,结合元数据(MetaStore)
,将这些指令翻译成MapReduce,提交到hadoop中执行,最后将执行结果输出到用户交互接口。
安装过程逻辑如上图,先将hive装上,再安装MySQL,然后将hive的元数据配置到MySQL上,然后介绍hive的三种访问方式,最后简单介绍一下hive的交互命令。
下载地址:https://dlcdn.apache.org/hive/hive-3.1.2/
sudo vim /etc/profile.d/my_env.sh
,向其中添加HIVE_HOME的内容。source /etc/profile
使得环境变量生效。bin/schematool -dbType derby -initSchema
如果初始化的时候报错:
in thread "main"java.lang.NoSuchMethodError:com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V
解决方案参考: http://www.shangdixinxi.com/detail-1151470.html
安装完之后启动一下:
bin/hive
/user/hive/warehouse/test
1)检查系统是否安装过MySQL,一般系统会自动安装一个,需要把它卸载:
rpm -qa|grep mariadb
sudo rpm -e --nodeps mariadb-libs
2)mysql下载安装、解压、执行rpm安装:
具体可以参考这篇文章:https://blog.csdn.net/weixin_43451430/article/details/115553108
按照上面文章到修改root密码之后,然后配置修改mysql库下表中root用户允许任意ip连接:
我们可以看到运行前后,这个user表的变化,说明任何ip用户都可以登录访问这个Mysql了。
1)将MySQL的JDBC驱动拷贝到Hive的lib目录下。jdbc驱动下载介绍:https://blog.csdn.net/HDZ1821/article/details/104373946
2)配置Metastore到MySQL
vim $HIVE_HOME/conf/hive-site.xml
并在hive-site.xml文件中添加以下内容:
<configuration>
<property>
<name>javax.jdo.option.ConnectionURLname>
<value>jdbc:mysql://hadoop100:3306/metastore?useSSL=falsevalue>
property>
<property>
<name>javax.jdo.option.ConnectionDriverNamename>
<value>com.mysql.jdbc.Drivervalue>
property>
<property>
<name>javax.jdo.option.ConnectionUserNamename>
<value>rootvalue>
property>
<property>
<name>javax.jdo.option.ConnectionPasswordname>
<value>123456value>
property>
<property>
<name>hive.metastore.schema.verificationname>
<value>falsevalue>
property>
<property>
<name>hive.metastore.event.db.notification.api.authname>
<value>falsevalue>
property>
<property>
<name>hive.metastore.warehouse.dirname>
<value>/user/hive/warehousevalue>
property>
configuration>
mysql> create database metastore;
mysql> quit;
schematool -initSchema -dbType mysql -verbose
总结一下上面这三步:就是新建配置文件,覆盖掉hive的默认文件,这个配置了元数据存在哪个数据库、用啥用户、驱动和密码来访问这个数据库、这些数据是存在hdfs哪个文件目录下等信息。配置完之后就可以通过再次启动hive来进行测试了。
通过以上测试,我们可以发现多个客户端可以使用同一个hive,并进行操作。这在不配置MySQL前是不行的,因为hive默认的元数据库derby不与其他客户端共享数据。
(1)直接访问:类似于上面测试的内容:直接通过bin/hive
启动,然后进行操作。
(2)使用元数据服务的方式访问hive:
1)为啥需要使用元数据服务方式?
希望通过第三方通过服务的方式访问hive。客户端连接metastore服务,metastore再去连接MySQL数据库来存取元数据。有了metastore服务,就可以有多个客户端同时连接,而且这些客户端不需要知道MySQL数据库的用户名和密码,只需要连接metastore 服务即可。
2)怎么配置元数据服务方式?
①在hive-site.xml文件中添加配置信息:
<property>
<name>hive.metastore.urisname>
<value>thrift://hadoop100:9083value>
property>
②启动metastore:这是一个后端进程、启动之后需要再开一个shell窗口启动
hive --service metastore
(3)使用JDBC方式访问hive:
这里为了好理解JDBC访问hive,我们必须要了解元数据服务metastore:先贴个链接
本文介绍的主要是本地模式的JDBC访问,即:
MetaStore 服务仍然和 Hive 服务运行在同一个进程中,但连接的却是另一个进程中运行的数据库,在同一台机器上或者远程机器上。此时如果客户端要访问Hive,走的过程如下图所示:
此时client通过Thrift Server来访问hive,简略图如下图所示。
接下来介绍如何配置
(1)在hive-site.xml文件中添加如下配置信息
<property>
<name>hive.server2.thrift.bind.hostname>
<value>hadoop100value>
property>
<property>
<name>hive.server2.thrift.portname>
<value>10000value>
property>
(2)启动metastore(前提是启动了metastore)
bin/hive --service hiveserver2
(3)启动beeline客户端
bin/beeline -u jdbc:hive2://hadoop100:10000 -n hhh
这里容易报错:Error: Could not open client transport with JDBC Uri: jdbc:hive2://hadoop102:10000: Failed to open new session: java.lang.RuntimeException
是因为在core.site.xml缺少配置文件,代理对象设置为自己的用户名,解决办法详见。
启动之后见到下面这里的东西就算成功了:
启动之后的分析:
(1)启动metastore:hive --service metastore
是前台进程
启动hiveserver2:bin/hive --service hiveserver2
也是前台进程。
启动hiveserver2之后,发现有两个RunJar进程:
然后分别用ps -aux | grep 进程号
分析这两个RunJar具体信息,如下图所示:
其中一个是HiveServer2,一个是HiveMetaStore。显然,前端进程不方便(因为一直要保持开启进程活着,显然切换为后端进程比较好)。开起了上面的任意进程,就不能通过bin/hive
进行启动了。
(2)编写hive服务启动的脚本:
写在前面,nohup放在命令开头,表示不挂起,也就是关闭程序终端也能够继续保持运行状态。
nohup hive --service metastore 2>&1 &
nohup hive --service hiveserver2 2>&1 &
2>&1
: 表示将错误重定向到标准输出上
&
: 放在命令结尾,表示后台运行
一般会组合使用: nohup [xxx 命令操作]> file 2>&1 &
,表示将xxx 命令运行的结
果输出到file 中,并保持命令启动的进程在后台运行。
#!/bin/bash
HIVE_LOG_DIR=$HIVE_HOME/logs
if [ ! -d $HIVE_LOG_DIR ]
then
mkdir -p $HIVE_LOG_DIR
fi
#检查进程是否运行正常,参数1 为进程名,参数2 为进程端口
function check_process()
{
pid=$(ps -ef 2>/dev/null | grep -v grep | grep -i $1 | awk '{print $2}')
ppid=$(netstat -nltp 2>/dev/null | grep $2 | awk '{print $7}' | cut -d '/' -f 1)
echo $pid
[[ "$pid" =~ "$ppid" ]] && [ "$ppid" ] && return 0 || return 1
}
function hive_start()
{
metapid=$(check_process HiveMetastore 9083)
cmd="nohup hive --service metastore >$HIVE_LOG_DIR/metastore.log 2>&1 &"
[ -z "$metapid" ] && eval $cmd || echo "Metastroe 服务已启动"
server2pid=$(check_process HiveServer2 10000)
cmd="nohup hiveserver2 >$HIVE_LOG_DIR/hiveServer2.log 2>&1 &"
[ -z "$server2pid" ] && eval $cmd || echo "HiveServer2 服务已启动"
}
function hive_stop()
{
metapid=$(check_process HiveMetastore 9083)
[ "$metapid" ] && kill $metapid || echo "Metastore 服务未启动"
server2pid=$(check_process HiveServer2 10000)
[ "$server2pid" ] && kill $server2pid || echo "HiveServer2 服务未启动"
}
case $1 in
"start")
hive_start
;;
"stop")
hive_stop
;;
"restart")
hive_stop
sleep 2
hive_start
;;
"status")
check_process HiveMetastore 9083 >/dev/null && echo "Metastore 服务运行正常" || echo "Metastore 服务运行异常"
check_process HiveServer2 10000 >/dev/null && echo "HiveServer2 服务运行正常" || echo "HiveServer2 服务运行异常"
;;
*)
echo Invalid Args!
echo 'Usage: '$(basename $0)' start|stop|restart|status'
;;
esac
赋予权限:
chmod +x $HIVE_HOME/bin/hiveservices.sh
上面的代码也挺简单的,他通过服务名和端口号来查询是否有这个服务,再让它挂起或者关闭。
有时候,你的选择真的很少,继续前行吧。