1. 程式人生 > >從mysql向HBase+Phoenix遷移數據的心得總結

從mysql向HBase+Phoenix遷移數據的心得總結

reduce 遭遇 問題 無法識別 任務 mes rate arc 字節

* 轉載請註明出處

公司有一張大表,數據量超過3億.Leader找我讓我完成這個數據遷移的工作.

mysql -> HBase + Phoenix

1.總體方案有哪些?

  1)通過Sqoop直接從服務器(JDBC方式)抽取數據到HBase中

  因為數據量非常大,因此優先考慮用Sqoop和MR抽取。

  使用Sqoop抽取數據有一個問題,就是Phoenix插入的數據和HBase插入的數據是不同的:

  例如,使用Phoenix插入這麽一條數據:

  upsert into tb_collector_log_143 values ( ‘2018-07-02 18:34:52_c37b03789c5e43ddb800ff90c27e5a44‘,‘2182a29047f3435885fc3fb9f7212189‘,‘server‘,‘server‘,‘2018-07-02 18:34:52‘,‘2018-07-02 18:34:52‘,‘8a5381604b4443ecb1b73d362f756483‘,‘c37b03789c5e43ddb800ff90c27e5a44‘,‘0560337357604a258a19adb8cc8849c6‘,‘2018-07-02 18:34:52‘,‘1‘,‘02‘,‘117.61.15.14:45067‘,‘4da7408331794910aa3523b6a9741df5‘);

  在HBase中“2018-07-02 18:34:52”這個字段值(在phoenix中是date類型)就是字節碼“\x80\x00\x01d\x5CF\xA8\xE0“:

  2018-07-02 18:34:52_c37b03789c5e43ddb800ff90c27e5a44 column=0:OPERATER_DATE, timestamp=1541250071138, value=\x80\x00\x01d\x5CF\xA8\xE0

  因此如果直接向HBase put數據,也會出現Phoenix無法識別的問題。經過反復的驗證,發現只有Phoenix的字符串類型(varchar和char)才能保持HBase中直接存儲這個值。

  * 因此,為了讓在Phoenix中插入字符串“aaa"與在HBase中插入”aaa"等價,被插入的這個字段只能是char或者是varchar類型。 這也就意味著使用Sqoop直接從原服務器抽取數據,新的表結構只能是全字符串類型。這也就意味著原來的JDBC的查詢可能會遭遇不順,因為期望被遷移的表有int和date等字段,如果JDBC對字段類型不一致的查詢不兼容的話,這事就不太好說。

  2)通過MapReduce進行批量插入。

  如果直接跑SQL文件效率會非常低,因為是一條一條插入的,先不說導入數據的過程,即使開高並發,服務器上的數據也難以導出成sql文件。因此PASS掉導出文件的方式,只能是直接抽取。

技術分享圖片

  其他:在之前的實驗中,我曾用12W條記錄的upsert插入sql文件進行插入,結果在插入5W+行的時候發生了堆溢出。這說明使用$SQOOP/bin/psql.py xxx.sql的命令時會在Jvm跑一個進程,每個運行腳本的插入數有限制。

  因此可以考慮通過MapReduce進行批量的插入過程,但其實只需要Map任務就可以了,相當於自己寫了一個特殊的Sqoop的實例,滿足這種特殊的數據抽取需求。

2.幾個核心的點:

1)服務器上的數據怎麽導出

剛才分析過了,只能通過Sqoop或者手碼MR程序

2)數據如何導入HBase,並且使得Phoenix能夠順利識別?

一種方法是全部字段使用字符串,然後使用HBase的put

一種方法是走Phoenix進行插入,這麽插入就必須寫MR了

3. //TODO 待添加 : 優化問題 災備方案 的解決?

  

從mysql向HBase+Phoenix遷移數據的心得總結