場景描述
現有大量CSV格式的數據記錄存儲在HDFS中,須要批量索引到Hbase以便於數據查詢。限於Hbase的主鍵索引以及使用Hbase API的諸多不方便,最後採用了Phoenix+Hbase的技術架構。基於此方案數據的索引可經過Phoenix的SQL API、Spark RDD插件、以及Phoenix提供的批量加載工具」 CsvBulkLoadTool」來實現數據寫入,因爲HDFS原始數據和Phoenix表並不是一一對應關係且Phoenix表字段使用了組合值,這裏不考慮使用CsvBulkLoadTool。
如下優化不在考慮數據類型.重點比較表[索引]是否分區、表分區數、RDD分區數網絡
基礎環境架構
建立表:
create table if not exists "mytable" ("id" VARCHAR NOT NULL PRIMARY KEY,...);
建立索引:
create index table_index on "mytable"("data"."ts","data"."imsi","data"."cid") SALT_BUCKETS=120;
數據寫入方式:
Spark中使用Phoenix SQL API ,爲避免一批提交的數據過大而提交失敗,代碼中控制了每批次提交的記錄數.
因爲以前使用批處理的時候沒有指定每批次的數據寫入大小,發現服務啓動以後長時間掛起,Hbase寫入阻塞Phoenix不能鏈接重啓集羣后恢復,懷疑是否因爲大批量的提交引發,這裏僅測試在表未分區的狀況下每批次提交數據大小對寫入的性能影響。下表記錄了在特定場景下批次大小對Phoenix寫入的影響
總結:
這裏不與非批處理進行比較,理論上大量數據的批量寫入優於逐條寫入。
PhoenixSQL批量寫入中每次提交的數據量對寫入性能有很大影響,批次大小若不控制容易引發Hbase集羣&Phoenix環境異常,可經過測試尋找最佳批次大小。
猜想:
Phoenix表未分區的狀況下全部數據先被寫入一個節點隨着數據量的增長RegionServer進行Region拆分,此過程伴隨大量的IO操做且對寫入有極大影響,使用Phoenix對錶進行預分區是否可避免。以前在網絡上見有文章代表Phoenix SQL批量寫入每批次總數最好不要超過30萬,當前最優寫入爲5000*5節點=25萬/批次,認爲可靠。工具
基於上述猜想第二版中對Phoenix表和索引同時進行預分區,且尋找是否分區數對寫入性能有影響。
建立表:
create table if not exists "mytable" ("id" VARCHAR NOT NULL PRIMARY KEY,...)SALT_BUCKETS=120;
建立索引:
create index table_index on "mytable"("data"."ts","data"."imsi","data"."cid") SALT_BUCKETS=120;
總結:
對錶和索引進行分區對寫入性能有極大的影響[索引也是表],Spark RDD的分區數對寫入性能影響很小,表分區數和批次大小對寫入性能影響很大,並不是是線性關係,可經過測試尋找一個最佳的表分區數和批次大小。
猜想:
表分區數彷佛在全部RegionServer的CPU核心數之和左右擁有更強的寫入性能。經過Spark RDD寫入是否擁有更強的寫入能力。性能
因爲於第二版採用不一樣的邏輯寫入,這裏僅於第二版中最佳的寫入性能進行比較測試
基於第二版的結論第三版中設定Spark分區數爲5,表及索引分區數爲120測試Spark RDD提供的Phoenix寫入API測試優化
結論:
目前沒有以爲Spark RDD寫入有什麼明顯的優點,這裏也沒有進行進一步的優化.
總結
使用Phoenix+Hbase進行大量數據寫入的場景下[這裏定義了二級索引]可以使用SQL+批處理的方式進行寫入,須要適當控制每批次提交的數據量避免Phoenix過載拒絕寫入。同時可預先對錶進行分區以加快寫入速率,分區數在Hbase節點的 總的CPU 核心數做爲宜,Spark全部節點的批次總和控制在30萬左右比較靠譜。插件