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

從mysql向HBase+Phoenix遷移資料的心得總結

* 轉載請註明出處

公司有一張大表,資料量超過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  待新增 : 優化問題  災備方案 的解決?