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了。
开始用Navicat访问链接试试。
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文件中添加以下内容:<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <!-- jdbc 连接的URL --> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://hadoop100:3306/metastore?useSSL=false</value> </property> <!-- jdbc 连接的Driver--> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> </property> <!-- jdbc 连接的username--> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>root</value> </property> <!-- jdbc 连接的password --> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>123456</value> </property> <!-- Hive 元数据存储版本的验证 --> <property> <name>hive.metastore.schema.verification</name> <value>false</value> </property> <!--元数据存储授权--> <property> <name>hive.metastore.event.db.notification.api.auth</name> <value>false</value> </property> <!-- Hive 默认在HDFS 的工作目录 --> <property> <name>hive.metastore.warehouse.dir</name> <value>/user/hive/warehouse</value> </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.uris</name> <value>thrift://hadoop100:9083</value> </property>
②启动metastore:这是一个后端进程、启动之后需要再开一个shell窗口启动
hive --service metastore
开启之后就有一个RunJar的进程。
(3)使用JDBC方式访问hive:
这里为了好理解JDBC访问hive,我们必须要了解元数据服务metastore:先贴个链接
本文介绍的主要是本地模式的JDBC访问,即:
MetaStore 服务仍然和 Hive 服务运行在同一个进程中,但连接的却是另一个进程中运行的数据库,在同一台机器上或者远程机器上。此时如果客户端要访问Hive,走的过程如下图所示:
此时client通过Thrift Server来访问hive,简略图如下图所示。
接下来介绍如何配置
(1)在hive-site.xml文件中添加如下配置信息
<!-- 指定hiveserver2 连接的host --> <property> <name>hive.server2.thrift.bind.host</name> <value>hadoop100</value> </property> <!-- 指定hiveserver2 连接的端口号 --> <property> <name>hive.server2.thrift.port</name> <value>10000</value> </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
上面的代码也挺简单的,他通过服务名和端口号来查询是否有这个服务,再让它挂起或者关闭。
有时候,你的选择真的很少,继续前行吧。