從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 待添加 : 優化問題 災備方案 的解決?
從mysql向HBase+Phoenix遷移數據的心得總結