Phoenix 官方提供了相應的導入和導出的方案,分別位於:html
導入:https://phoenix.apache.org/bu...java
導入、導出:https://phoenix.apache.org/pi...git
導出須要依賴 Apache Pig
相應進行實現。咱們先來聊聊如何導出吧。github
環境:HDP 3.0.0、HBase 2.0.0、Phoenix 5.0.0、Pig 0.16.0shell
Phoenix 官方提供的 Pig 方案,看似很簡單,其實仍是有不少須要注意的地方,比較官方給的都是最簡單的示例,而實際應用場景的時候,會碰到不少意想不到的問題。我在本文就講講個人實現方法和遇到的坑吧。apache
如下操做須要先安裝 Pig 環境。服務器
test.pig
app
REGISTER /usr/hdp/3.0.0.0-1634/hbase/lib/*.jar; REGISTER lib/*.jar; rows = load 'hbase://table/DOP_VISIT_INFO_V2' USING org.apache.phoenix.pig.PhoenixHBaseLoader('dev-dmp3.fengdai.org,dev-dmp4.fengdai.org,dev-dmp5.fengdai.org');
hbase://table/DOP_VISIT_INFO_V2
:是指須要備份的表,若是是全表就用 hbase://table
,後面跟表名,這裏就是 DOP_VISIT_INFO_V2
查詢的結果導出則用 hbase://query
,後面跟查詢語句。PhoenixHBaseLoader 參數
:ZooKeeper 地址。執行語句:函數
pig -x mapreduce test.pig
相應的導出的數據是存儲在 HDFS 上,須要留意一下腳本執行完之後相應的日誌中會有體現。grunt
REGISTER /usr/hdp/3.0.0.0-1634/hbase/lib/*.jar; REGISTER lib/*.jar; rows = load 'hbase://table/DOP_VISIT_INFO_V2' USING org.apache.phoenix.pig.PhoenixHBaseLoader('dev-dmp3.fengdai.org,dev-dmp4.fengdai.org,dev-dmp5.fengdai.org'); STORE rows INTO 'dop_visit_info_v2.csv' USING PigStorage(',');
STORE rows INTO 'dop_visit_info_v2.csv' USING PigStorage(',')
:導出到 HDFS 的文件路徑和數據存儲格式,這裏就是存放 dop_visit_info_v2.csv
目錄下,這裏千萬注意,這是一個文件夾,而不是一個 csv
文件,起初,我也很單純的覺得,Too Young,使用逗號進行分隔。
REGISTER /usr/hdp/3.0.0.0-1634/hbase/lib/*.jar; REGISTER lib/*.jar; rows = load 'hbase://query/select * DOP_VISIT_INFO_V2 where age >18' USING org.apache.phoenix.pig.PhoenixHBaseLoader('dev-dmp3.fengdai.org,dev-dmp4.fengdai.org,dev-dmp5.fengdai.org');
注意: 使用query語句指定的導出方式存在很大的限制,好比說不能指定 GROUP BY , LIMIT , ORDER BY , DISTINCT
;同時也沒法指定使用聚合函數,如 count,sum
等。
數據存儲在 HDFS 下哦。
hdfs dfs -cat '/dop_visit_info_v2.csv/part-m-00000'
Phoenix 支持使用 Pig StoreFunc 實現 bulk upload
數據導入。
REGISTER /usr/hdp/3.0.0.0-1634/hbase/lib/*.jar; REGISTER lib/*.jar; A = load 'gejx.csv' USING PigStorage(',') as (ID:chararray, DOP_VISIT_VISITID:chararray); STORE A into 'hbase://GEJX_TEST' using org.apache.phoenix.pig.PhoenixHBaseStorage('dev-dmp3.fengdai.org,dev-dmp4.fengdai.org,dev-dmp5.fengdai.org','-batchSize 100');
gejx.csv
:導出的數據存儲路徑hbase://GEJX_TEST
:導入的表-batchSize 100
:upsert 批量條數ID:chararray, DOP_VISIT_VISITID:chararray
:字段名稱與類型映射關係,這裏的字段名是屬於 GEJX_TEST 表中的字段,也就是目標持久化的表名USING PigStorage(',')
:可選,若是是使用上方 CSV 導出方式,則須要加上注意: 表須要提早建立哦,不然,會報表不存在。
Pig 數據類型默認是 chararray,經常使用數據類型爲:int、long、float、double、chararray、bytearray、map、tuple、bag。
詳細查看 pig 數據類型 。
若是 Phoenix 表中存在 null 值,經過 Pig 方式導入導出數據會存在 null 變成了空字符串。
在使用 https://phoenix.apache.org/bu... 中 MR 方式時,因爲 HDP 環境開啓了 Kerberos 模式,一直遇到了認證的問題,後來發現支持 -D
的語法,不過這裏須要注意的是必定要放在 hadoop jar 參數命令以前,不然會報沒有這個命令的錯誤。
hadoop jar /usr/hdp/3.0.0.0-1634/phoenix/phoenix-5.0.0.3.0.0.0-1634-client.jar org.apache.phoenix.mapreduce.CsvBulkLoadTool -Dhbase.master.kerberos.principal=hbase/_HOST@DEV.ORG -Dhbase.regionserver.kerberos.principal=hbase/_HOST@DEV.ORG -Dhadoop.security.authentication=kerberos -Dhbase.security.authentication=kerberos -Dphoenix.schema.isNamespaceMappingEnabled=true -Dphoenix.schema.mapSystemTablesToNamespace=false -Dphoenix.queryserver.withRemoteUserExtractor=true --table GEJX_TEST --input /user/dmpadmin/gejx.csv -z dev-dmp3.fengdai.org,dev-dmp4.fengdai.org,dev-dmp5.fengdai.org:/hbase-secure
phoenix-5.0.0.3.0.0.0-1634-client.jar
該包是存放在 Phoenix 安裝目錄下的,並非 lib 目錄。
以上的方式導入和導出是相互割裂的,而有一種場景在生產上也碰到的不少,就是表與表之間的數據同步,好比,如今有兩張表 A 表和 B 表,表部分字段同樣,字段名稱不同,如今須要將 A 表中的數據同步到 B 表,咱們也能夠經過 Pig 方式實現。
REGISTER /usr/hdp/3.0.0.0-1634/hbase/lib/*.jar; REGISTER lib/*.jar; A = load 'hbase://query/select * from GEJX' USING org.apache.phoenix.pig.PhoenixHBaseLoader('dev-dmp3.fengdai.org,dev-dmp4.fengdai.org,dev-dmp5.fengdai.org'); STORE A into 'hbase://GEJX_TEST' using org.apache.phoenix.pig.PhoenixHBaseStorage('dev-dmp3.fengdai.org,dev-dmp4.fengdai.org,dev-dmp5.fengdai.org','-batchSize 100');
將導入和導出放在一塊兒進行操做,batchSize 能夠根據實際狀況進行相應的調整。
Zookeeper 端口配置
zk1:2181,zk2:2181,zk3:2181
開啓 Keberos 模塊的場景下,須要提早在 Pig 所在服務器下進行 kinit 操做
org.apache.pig.PigServer - exception during parsing: Error during parsing. null Failed to parse: null
通常是語法錯誤致使的。
ERROR org.apache.pig.tools.grunt.GruntParser - ERROR 0: java.io.IOException: java.lang.RuntimeException: java.lang.Integer cannot be coerced to TINYINT
這個問題就沒法解決了,目標表的不能使用 TINYINT 類型。