背景
最近有個需求,有一些數據會實時寫入到
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
上了。於是查看了下元數據信息
果然是在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集羣都能訪問數據了。
關注公衆號一起學習哦