Hive简介
Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射成一张数据库表,并提供类SQL(HQL)查询功能,适用于离线的批量数据计算
Hive本身不存储和计算数据,它完全依赖于HDFS和MapReduce,它的表其实就是一个Hadoop的目录/文件(默认存放在Hive工作目录中)
Hive设计目的是让SQL技能良好,但Java技能较弱的分析师可以查询海量数据
Hive本质就是一个SQL解析引擎,它将SQL语句转译成M/R Job然后在Hadoop执行
Hive架构
Hive的执行原理
Hive 的核心是驱动引擎Driver, 驱动引擎由四部分组成:
解释器:将 HiveSQL 语句转换为抽象语法树(AST)
编译器:将语法树编译为逻辑执行计划
优化器:对逻辑执行计划进行优化
执行器:调用底层的运行框架执行逻辑执行计划
HQL 通过命令行或者客户端提交,Driver 组件对其进行词法分析,语法分析,编译,优化,最后生成逻辑执行计划。生成的逻辑执行计划存储在 HDFS 中,并随后由MapReduce 调用执行
Hive搭建模式
hive有三种搭建模式:内嵌模式,本地模式,远程模式
元数据:描述数据的数据,这里指存储在 Hive 中的数据的描述信息。元数据存储在关系型数据库中。
Hive 中的元数据通常包括:表的名字,表的列和分区及其属性,表的属性(内部表和 外部表),表的数据所在目录
内嵌模式:hive将源数据存储在HDFS中,而元数据默认存储在hive自带的数据库Derby中。但是Derby不支持多用户同时访问,所以这种模式仅供测试使用。
本地模式:使用mysql数据库替代Derby来存储元数据,以解决多用户并发访问问题
远程模式:以本地模式为基础,mysql数据库所在的节点提供metastore service服务,其他节点可以连接该服务来获取元数据信息
- 这里我们搭建一个远程模式,首先因为hive依赖于hadoop,所以需要先搭建好hadoop环境
- 搭建好hadoop环境后,随机选择一个节点作为 hive 远程模式的服务端,即mysql安装在该节点上,在该节点上首先安装mysql,然后配置hive,到这里这就是一个本地模式,最后开启metastore服务
- 服务端开启服务后,对客户端进行配置,仅配置hive即可
mysql在线安装
在线安装mysql数据库
yum install -y mysql-server
开启mysql服务
Service mysqld start
设置开机启动
chkconfig mysqld on
安装完毕数据库是没有密码的,输入以下命令进入mysql,提示输入密码时直接回车就ok
mysql -uroot -p
进入mysql后,设定权限,修改密码
修改root权限:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123' WITH GRANT OPTION;
刷新:
flush privileges;
这里我们再添加一个新用户用来操作数据库,毕竟root权限太高
添加用户:
CREATE USER 'hive'@'%' IDENTIFIED BY '123';
授权用户:这里给hive用户操作hive_meta数据库的权限
grant all privileges on hive_meta.* to hive@"%" identified by '123';
刷新:
flush privileges;
设置完成后,我们为hive用户创建数据库 hive_mata,然后查看一下数据库
mysql> create database if not exists hive_mata;
Query OK, 1 row affected (0.04 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hive_meta |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)
然后使用mysql数据库
mysql> use mysql;
进入mysql数据库后,查看表
mysql> show tables;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| ...... |
|...... |
| user |
+---------------------------+
23 rows in set (0.00 sec)
在其中有张user表,存储着数据库用户的信息,这里可能会出现权限冲突问题,所以我们将多余用户信息删除
mysql> delete from user where Host != '%';
删除成功后查看表中信息,仅保留 root 和 hive 任意节点登录的权限即可(%代表任意)
mysql> select Host,User,Password from user;
+------+------+-------------------------------------------+
| Host | User | Password |
+------+------+-------------------------------------------+
| % | root | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
| % | hive | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
+------+------+-------------------------------------------+
2 rows in set (0.00 sec)
退出mysql,使用hive登录,登录成功则配置ok
mysql -uhive -p123
hive配置
服务端
-
下载hive安装包,这里使用的是hive-1.2.1
下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/hive/ -
解压,进入conf目录,复制一份hive-default.xml.template,重命名为hive-site.xml
-
修改hive-site.xml,将 configuration 标签中的内容全部删除,用以下内容替换
<property>
<name>hive.metastore.warehouse.dir</name> <!-- hive工作目录 -->
<value>/user/hive_localmysql/warehouse</value>
</property>
<property>
<name>hive.metastore.local</name> <!-- 是否是本地模式,即hive和mysql是否在同一节点 -->
<value>true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name> <!-- 连接mysql的URL -->
<value>jdbc:mysql://localhost/hive_meta?createDatabaseIfNotExist=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name> <!-- 连接mysql的驱动 -->
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name> <!-- 连接的用户名,使用上面创建的hive用户 -->
<value>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name> <!-- 连接的用户的密码 -->
<value>123</value>
</property>
- 配置hive的环境变量。在~/.bashrc中配置
export HIVE_HOME=/opt/zgl/hive-1.2.1
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin:$PATH
- 将mysql的连接驱动包放到 hive 的 lib 目录下,这里使用的是mysql-connector-java-5.1.32-bin.jar
驱动包可以到mysql官网下载,下载地址:https://dev.mysql.com/downloads/connector/j/ - 将hive lib下的 jline 的jar包拷到 hadoop的 share/hadoop/yarn/lib 中(这里因为hadoop内的 jline 的jar包过时了,我们令其和 hive 中的版本保持一致)
- 启动HDFS和YARN,在命令行输入hive即可进入hive shell,在这里便可以对hive进行操作。
- 服务端启动metastore服务(启动后台运行)
hive --service metastore >> /tmp/meta.log 2>&1 &
客户端
1> 选一台节点作为客户端来连接metastore服务,配置步骤与服务端几乎相同,只有hive-xite.xml中的内容不同
<property>
<name>hive.metastore.local</name> <!-- 是否是本地模式,即hive和mysql是否在同一节点 -->
<value>false</value>
</property>
<property>
<name>hive.metastore.uris</name> <!-- 连接的服务的 uri -->
<value>thrift://node04:9083</value> <!-- 通过 thrift 协议连接,连接的服务端的 IP 和端口号 -->
</property>
2> 在客户端直接 hive 即可进入hive shell。这里的数据库存放的是源数据,默认只有一个default
hive> show databases;
OK
default
myhive
Time taken: 4.601 seconds, Fetched: 2 row(s)
hive的连接方式
CLI
上面直接输入hive进入 hive shell 的方法即为CLI连接方式 ,是hive默认的命令行访问模式,但因为其登录无验证而导致安全性较低,beeline便由此而生。
Beeline
Beeline 是 HiveServer2 支持的一个新的命令行Shell,它是基于SQLLine CLI 的JDBC客户端。同时支持嵌入模式和远程模式。
在嵌入模式中,它运行一个嵌入的Hive(类似旧的Hive CLI),而远程模式是通过 Thrift 连接一个分离的 HiveServer2 进程
远程HiveServer2 模式是Hive产品使用的推荐模式,它更加安全并且不需要直接为用户对HDFS/metastore进行赋权,它使用 Thrift 通信协议。
beeline默认链接hiveserver2的时候,不需要用户名 密码,所以默认方式也是不安全,我们可以设置hiveserver2用户名、密码。
1> 首先在hive-site.xml中进行配置
<property>
<name>hive.server2.authentication</name> <!-- 设置认证方式为自定义 -->
<value>CUSTOM</value>
</property>
<property>
<name>hive.jdbc_passwd.auth.root</name> <!-- 设置连接的用户名和密码 -->
<value>123</value> <!-- 考虑到权限问题,这里的用户最好使用root -->
</property>
<property>
<name>hive.server2.custom.authentication.class</name> <!-- 设置自定义的认证类 -->
<value>com.hoe.hive.authoriz.UserPasswdAuth</value>
</property>
2> 然后自定义认证类
// 实现 PasswdAuthenticationProvider 接口
public class UserPasswdAuth implements PasswdAuthenticationProvider {
Logger logger = LoggerFactory.getLogger(UserPasswdAuth.class);
private static final String USER_PASSWD_AUTH_PREFIX = "hive.jdbc_passwd.auth.%s";
private Configuration conf = null;
@Override
public void Authenticate(String userName, String passwd) throws AuthenticationException {
logger.info("user: " + userName + " try login.");
// 读取配置文件信息,检查输入的用户名和密码是否和hive-site.xml中配置的一致,一致则成功登录
String passwdConf = getConf().get(String.format(USER_PASSWD_AUTH_PREFIX, userName));
if (passwdConf == null) {
String message = "沒有發現密碼 " + userName;
logger.info(message);
throw new AuthenticationException(message);
}
if (!passwd.equals(passwdConf)) {
String message = "用戶名密碼不匹配 " + userName;
throw new AuthenticationException(message);
}
}
public Configuration getConf() {
if (conf == null) {
this.conf = new Configuration(new HiveConf());
}
return conf;
}
public void setConf(Configuration conf) {
this.conf = conf;
}
}
3> 将认证类打成jar包放到 hive 的 lib 目录下
4> 在服务端开启HiveServer2 模式(后台运行)
hiveserver2 >> /tmp/beeline.log 2>&1 &
5> 在客户端进行连接
[root@client ~]# beeline
Beeline version 1.2.1 by Apache Hive
//进入beeline shell,连接服务器端的服务,默认端口为10000
beeline> !connect jdbc:hive2://node04:10000
Connecting to jdbc:hive2://node04:10000
//提示输入用户名和密码
Enter username for jdbc:hive2://node04:10000: root
Enter password for jdbc:hive2://node04:10000: ***
Connected to: Apache Hive (version 1.2.1)
Driver: Hive JDBC (version 1.2.1)
Transaction isolation: TRANSACTION_REPEATABLE_READ
//连接成功
0: jdbc:hive2://node04:10000>
也可以这样来连接
[root@node01 ~]# beeline -u jdbc:hive2://node04:10000 -nroot -p123
6> 连接成功后可以进行操作,例如显示数据库
0: jdbc:hive2://client:10000> show databases;
+----------------+--+
| database_name |
+----------------+--+
| default |
| myhive |
+----------------+--+
2 rows selected (1.452 seconds)
JDBC
JDBC与 beeline 一样使用 ThriftServer,它提供在客户端通过编码来操作 hive
服务端启动 hiveserver2 后,在java代码中通过jdbc访问默认端口10000进行连接、访问
public class ConnectHive {
public static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) {
try {
Class.forName(driverName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 连接服务端
String url = "jdbc:hive2://192.168.22.115:10000";
String userName = "root";
String passwd = "123";
Connection conn = null;
try {
conn = DriverManager.getConnection(url, userName, passwd);
//使用 hive 进行操作
Statement statement = conn.createStatement();
String sql = "select * from myhive.logtbl limit 10";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println(resultSet.getString(1) + "-" + resultSet.getString(2));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
WEB UI
1> 下载源码包 apache-hive-*-src.tar.gz,这里使用 apache-hive-1.2.1-src.tar.gz
下载地址:http://archive.apache.org/dist/hive/
2> 解压,将hwi/web/*里面所有的文件打成war包
cd apache-hive-1.2.1-src/hwi/web
jar -cvf hive-hwi.war *
3> 将hwi war包放到 hive的 lib 目录下
4> 复制tools.jar(在jdk的lib目录下)到 hive的 lib 目录下
5> 修改hive-site.xml
<property>
<name>hive.hwi.listen.host</name>
<value>0.0.0.0</value>
<description>监听的地址</description>
</property>
<property>
<name>hive.hwi.listen.port</name>
<value>9999</value>
<description>监听的端口号</description>
</property>
<property>
<name>hive.hwi.war.file</name>
<value>lib/hive-hwi-1.2.1.war</value>
<description>war 包所在的地址</description>
</property>
6> 启动hwi服务
hive --service hwi >> /tmp/hwi.log 2>&1 &
7> 浏览器访问http://192.168.23.135:9999/hwi/
8> 登录后点击 Create Session 创建一个会话,便可开始使用hive进行操作
9> 执行完毕到指定文件查看
[root@client ~]# cat /tmp/hive01
default
myhive