文章目录

背景

最近有个需求,有一些数据会实时写入到 ​​hbase​​​,但是又需要在 ​​hive​​​ 中计算这些数据,最后把结果同步到 ​​mysql​​​。如果对于 ​​hbase​​​ 与​​hive​​​ 在同一个集群,是很简单的操作,直接在 ​​hive​​​ 中创建一个 ​​hbase​​​ 的外部映射表就好了。但是我这边有些不一致,我们这边 ​​hbase​​​ 和 ​​hive​​ 在两个不同的集群,需要了一些额外的操作

开启白名单限制

由于 ​​hbase​​​ 集群与 ​​hive​​​ 集群的网络被限制,所以需要把 ​​hive​​​ 集群的节点全部加入到 ​​regionServer​​​ 以及 ​​zk​​​ 节点的白名单列表,或者修改安全组,使得 ​​hive​​​ 能够访问 ​​hbase​​ 的每个节点。

打通hive集群与hbase集群的连接

对于不在同一集群的 ​​hive​​​ 与 ​​hbase​​​,需要在 ​​hive​​​ 中设置 ​​hbase​​​ 的 ​​zk​​ 集群地址。

set hbase.zookeeper.quorum=zk001:2181,zk002:2181,zk003:2181
Tip:首先要使用 hive 命令进入 hive shell

创建hbase映射表

然后创建 ​​hbase​​ 映射表

hive> set hbase.zookeeper.quorum=zk001:2181,zk002:2181,zk003:2181;
hive> create external table bi_ods.sucx_test (id string,name string,age string)
> stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
> with serdeproperties ("hbase.columns.mapping" = ":key,cf1:name,cf1:age")
> tblproperties ("hbase.table.name" = "sucx_test");

进行简单查询

hive> select * from bi_ods.sucx_test;
OK
1 sucx 10
2 sucx1 15
Time taken: 4.631 seconds, Fetched: 2 row(s)

绝大部分到这一步就结束了,但是我这边还是有点问题。首先解释下,我们这边的所有数据都是存储在oss和s3上,然后我们使用的是emr集群,emr集群只做计算,同一时间可能会启动多个emr集群来进行计算。假设我有A、B两个emr集群,刚刚我执行的所有操作都是在A集群之上,当我用B集群访问bi_ods.sucx_test数据的时候发现,竟然连接到了A集群的hdfs,由于网络隔离,查询失败。

> select * from bi_ods.sucx_test;
FAILED: SemanticException Unable to determine if hdfs://emr-header-1.cluster-75160:9000/user/hive/warehouse/bi_ods.db/sucx_test is encrypted: java.lang.IllegalArgumentException: java.net.UnknownHostException: emr-header-1.cluster-75160

这个时候怀疑映射表的 ​​location​​​ 是不是落到A集群的​​hdfs​​ 上了。于是查看了下元数据信息

hive访问不在同一集群的hbase表数据_hadoop


果然是在A集群的本地,然后看了看建表语句也确实是外部表

查看该表在A集群的hdfs信息

[hadoop@emr-worker-1 ~]$ hadoop fs -ls /user/hive/warehouse/bi_ods.db/ | grep sucx_test
drwxr-x--x - hadoop hadoop 0 2019-09-25 11:31 /user/hive/warehouse/bi_ods.db/sucx_test
[hadoop@emr-worker-1 ~]$ hadoop fs -ls /user/hive/warehouse/bi_ods.db/sucx_test
[hadoop@emr-worker-1 ~]$

只是个空文件夹,说明数据还是存在外部的。
于是先删除表,尝试着建表时增加
location 配置

hive> create external table bi_ods.sucx_test (id string,name string,age string)
> stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
> with serdeproperties ("hbase.columns.mapping" = ":key,cf1:name,cf1:age")
> tblproperties ("hbase.table.name" = "sucx_test")
> location 'oss://bigdata/bi/bi_ods.db/sucx_test';
FAILED: ParseException line 5:0 missing EOF at 'location' near ')'

无法解析。。

​hive-site.xml​​​ 有个选项 ​​hive.metastore.warehouse.dir​​​ 配置,表示数据的存放位置,默认是 ​​/user/hive/warehouse​​​ ,如果把这个配置修改为oss路径就好了,可是如果修改这个配置,需要重启集群,放弃了。想到 ​​hive database​​​ 也有个 ​​location​​​ 配置,会不会是这个 ​​bi_ods​​​ 库默认创建的 ​​location​​ 是在本地

hive> show create database bi_ods;
OK
CREATE DATABASE `bi_ods`
LOCATION
'hdfs://emr-header-1.cluster-75160:9000/user/hive/warehouse/bi_ods.db'
Time taken: 0.282 seconds, Fetched: 3 row(s)
hive>

果然,于是修改了这个 ​​bi_ods​​​ 的 ​​location​​,重新创建映射表,A、B集群都能访问数据了。

关注公众号一起学习哦

hive访问不在同一集群的hbase表数据_hive访问hbase数据_02