Hive高可用配置
在hive的商用上没有集群一说,而且它本身也不是数据库,只是hadoop的数据sql化工具,但是hive可以配置高可用,通常业内对元数据服务会开5个,而HS2服务开3个,来保证hive服务的高可用
配置方式也很简单,你只需在原有的hive-site.xml文件上,配置如下信息即可
<!--启用hiveserver2高可用-->
<property>
<name>hive.server2.support.dynamic.service.discovery</name>
<value>true</value>
</property>
<!--hiveserver2高可用向zookeeper注册的信息路径名-->
<property>
<name>hive.server2.zookeeper.namespace</name>
<value>hiveserver2_zk</value>
</property>
<!--zookeeper集群-->
<property>
<name>hive.zookeeper.quorum</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<!--hive访问zookeeper集群的端口号-->
<property>
<name>hive.zookeeper.client.port</name>
<value>2181</value>
</property>
<!--HS2高可用的服务节点,可以具体节点改这个配置也可以改成4个0-->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>node2</value>
</property>
<!--配置metastore高可用,所有HS2服务节点统一设置即可-->
<property>
<name>hive.metastore.uris</name>
<value>thrift://node2:9083,thrift://node3:9083</value>
</property>
随后将hive整体同步到高可用服务对应的节点上,并在对应的节点上,使用下面的命令启动对应的服务
/opt/hive313/bin/hive --service metastore &
/opt/hive313/bin/hive --service hiveserver2 &
随后进入zkCli里面确保配置文件里面写的的zk节点已经注册
验证连接,此时连接的jdbc路径就要变一种格式了,原来单一hive节点用如下简单的格式即可
/opt/hive-3.1.3/bin/beeline -u jdbc:hive2://node2:10000
当然上面这个命令还是能用的,只是但和直接访问一个namenode的9000端口一样,是直接访问一个定死的服务,而高可用的连接路径需要使用如下格式
jdbc:hive2://node1:2181,node2:2181,node3:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2_zk;user=root;password=123456
上面这个格式你可以简写成如下格式,前提是你的zk用的就是2181端口,后面的用户名和密码看情况携带
jdbc:hive2://node1,node2,node3/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2_zk root 123456
但是!!!!坑爹的来了,有三个天坑!!!!你要知道
第一个天坑!!beeline要连接高可用的HS2,不能用-u参数了,必须进去之后操作
就是说下面这个命令不能用了
/opt/hive-3.1.3/bin/beeline -u
你需要进入beeline
[root@node3 ~]# /opt/hive313/bin/beeline
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/hive313/lib/log4j-slf4j-impl-2.17.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/opt/hadoop323/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
Beeline version 3.1.3 by Apache Hive
----------------------------》进入bee后用!connect 方式才能连接
beeline> !connect jdbc:hive2://node1,node2,node3/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2_zk
Connecting to jdbc:hive2://node1,node2,node3/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2_zk
Enter username for jdbc:hive2://node1,node2,node3/: 12345
Enter password for jdbc:hive2://node1,node2,node3/: *****
24/11/30 17:18:43 [main]: INFO jdbc.HiveConnection: Connected to node3:10000
Connected to: Apache Hive (version 3.1.3)
Driver: Hive JDBC (version 3.1.3)
Transaction isolation: TRANSACTION_REPEATABLE_READ
0: jdbc:hive2://node1,node2,node3/> show tables;
INFO : Compiling command(queryId=root_20241130172336_02962b8a-b8cd-4b10-bd3d-4eee69993b74): show tables
INFO : Concurrency mode is disabled, not creating a lock manager
INFO : Semantic Analysis Completed (retrial = false)
INFO : Returning Hive schema: Schema(fieldSchemas:[FieldSchema(name:tab_name, type:string, comment:from deserializer)], properties:null)
INFO : Completed compiling command(queryId=root_20241130172336_02962b8a-b8cd-4b10-bd3d-4eee69993b74); Time taken: 0.585 seconds
INFO : Concurrency mode is disabled, not creating a lock manager
INFO : Executing command(queryId=root_20241130172336_02962b8a-b8cd-4b10-bd3d-4eee69993b74): show tables
INFO : Starting task [Stage-0:DDL] in serial mode
INFO : Completed executing command(queryId=root_20241130172336_02962b8a-b8cd-4b10-bd3d-4eee69993b74); Time taken: 0.03 seconds
INFO : OK
INFO : Concurrency mode is disabled, not creating a lock manager
+-----------+
| tab_name |
+-----------+
| t |
+-----------+
1 row selected (0.814 seconds)
0: jdbc:hive2://node1,node2,node3/>
第二个天坑!!!!无论你后面是用Java的JDBC连接还是其他的方式,连接路径中zk集群地址后面的/
不能少!!必须是jdbc:hive2://zk集群/;。。。。
格式,即使你指定连接的库也要在末尾有一个斜杠jdbc:hive2://zk集群/default-----就是这里末尾的斜杠------>>/<<-----------------;。。。。
第三个天坑!!!高可用连接和Tez不兼容,这就导致你要是用高可用连接那就不能把任务跑在Tez引擎上面,不然会发生guava包掉包的问题。格外的要说一下这个掉包的问题,如果看过我分享的hadoop测试集群3.x搭建方式的朋友,应该都知道hadoop3.x和hive3.x搭配的时候,需要将hadoop的guava包替换给hive,因为hive3.x自带的guava包版本较低,使得启动的时候报错,而在这个基础上再配置一个本身和hive不是完全兼容的tez时,需要从源码开始编译,并且手动强制的在hive-env.sh中将guava包声明给hive,就是为了解决任务跑在tez上面会掉guava包,从而导致任务刚启动就会报java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V
的错误,而当你以高可用的方式连接HS2,并且任务跑在tez上,你会发现,任务能正常起来,但是在reduce阶段,guava包就掉了,这个问题我在工作中和产品线上的rd去聊过,他们当时二次封装的时候也发现了这个问题,但是没解决方法,最后默认hive还时用MR,底层逻辑判断了一下,如果用户的提交参数带了tez引擎,那么跑任务用的HS2连接用的是当前服务中存活的单一服务连接方式,至于这个存活节点列表是写了一套寻址的逻辑,导致任务的日志里面,会出现WARE级别的ipc相关的寻址信息,每次用户用的时候都会很疑惑这是个报错吗?前段时间干脆下线了对用户直接开放的hive任务类型,实在需要才以白名单的方式提供,来减少维护成本,真的能笑死。