Flume-Hbase-Sink針對不同版本flume與HBase的適配研究與經驗總結

導語:本文細緻而全面地講解使用flume輸出數據到HBase的三種不同 Flume-Hbase-Sink 之間的差異性,以及技術細節。並且透徹而全面地總結了不同版本flume和HBase之間的兼容性問題。 爲了更加詳細說明三種不同hbasesink的差異性,本文在附錄附上詳細的源碼解讀。

一、Flume 的HBaseSinks 詳細介紹
Flume 有兩大類 HBasesinks: HBaseSink (org.apache.flume.sink.hbase.HBaseSink) 和 AsyncHBaseSink (org.apache.flume.sink.hbase.AsyncHBaseSink) 。

1.1、HBasesink
提供兩種序列化模式:

1.1.1、SimpleHbaseEventSerializer
將整個事件event的body部分當做完整的一列寫入hbase,因此在插入HBase的時候,一個event的body只能被插入一個column;

1.1.2、RegexHbaseEventSerializer
根據正則表達式將event 的body拆分到不同的列當中,因此在插入HBase的時候,支持用戶自定義插入同一個rowkey對應的同一個columnFamily 的多個column。

【優點】

(a) 安全性較高:支持secure HBase clusters (FLUME-1626) ,支持往secure hbase寫數據(hbase可以開啓kerberos校驗);

(b) 支持0.96及以上版本的HBase 的IPC通信----- the new HBase IPC which was introduced in HBase 0.96 and up。

【缺點】

性能沒有AsyncHBaseSink高。因爲HBaseSink採用阻塞調用(blocking calls),而AsyncHBaseSink採用非阻塞調用(non-blocking calls)。

1.2、AsyncHBaseSink
目前只提供一種序列化模式:SimpleAsyncHbaseEventSerializer:

將整個事件event的body部分當做完整的一列寫入hbase,因此在插入HBase的時候,一個event的body只能被插入一個column。

【優點】

AsyncHBaseSink採用非阻塞調用(non-blocking calls),因此,性能比HBaseSink高;

【缺點】

(a) 不支持secure HBase clusters (FLUME-1626),不支持往secure hbase寫數據;

(b) 不支持0.96及以上版本的HBase 的IPC通信----- the new HBase IPC which was introduced in HBase 0.96 and up。

二、兩大類HBasesinks的詳細用法
2.1 HBasesink--SimpleHbaseEventSerializer
2.2 HBasesink--RegexHbaseEventSerializer
如下是展示如何使用 HBasesink--RegexHbaseEventSerializer(使用正則匹配切割event,然後存入HBase表的多個列):
2.3 AsyncHBaseSink--SimpleAsyncHbaseEventSerializer
如果讀者感興趣,可以仔細閱讀Apache flume官網,上面有一些更加詳細的信息:

http://archive.cloudera.com/cdh/3/flume-ng/FlumeUserGuide.html

三、使用flume-hbase-sink的常見錯誤總結
3.1、無HBase讀寫權限
如果提交./flume-ng 任務的用戶沒有HBase的讀寫權限,那麼就會出現無權限讀寫HBase:

[ERROR - org.apache.flume.lifecycle.LifecycleSupervisor$MonitorRunnable.run(LifecycleSupervisor.java:253)]Unable to start SinkRunner: { policy:org.apache.flume.sink.DefaultSinkProcessor@f46fdc1 counterGroup:{ name:null counters:{} } } - Exception follows.
org.apache.flume.FlumeException: Could not start sink. Table or column family does not exist in Hbase (Permission denied).

【解決方法】

需要爲用戶賦予HBase讀寫權限,或者超級管理員權限。

3.2、低版本flume使用錯誤的序列化模式,導致與HBase版本接口不匹配
本文作者使用 flume-1.6.0 的RegexHbaseEventSerializer(屬於 HBasesink)對HBase-1.1.3 和 HBase-1.2.1進行插入數據,出現以下錯誤:

2016-12-22 12:14:50 ERROR [SinkRunner-PollingRunner-DefaultSinkProcessor] (org.apache.flume.sink.hbase.HBaseSink.process:351)  - Failed to commit transaction.Transaction rolled back.
java.lang.NoSuchMethodError: org.apache.hadoop.hbase.client.Put.setWriteToWAL(Z)V
    at org.apache.flume.sink.hbase.HBaseSink$3.run(HBaseSink.java:377)
    at org.apache.flume.sink.hbase.HBaseSink$3.run(HBaseSink.java:372)
    at org.apache.flume.auth.SimpleAuthenticator.execute(SimpleAuthenticator.java:50)
    at org.apache.flume.sink.hbase.HBaseSink.putEventsAndCommit(HBaseSink.java:372)
    at org.apache.flume.sink.hbase.HBaseSink.process(HBaseSink.java:342)
    at org.apache.flume.sink.DefaultSinkProcessor.process(DefaultSinkProcessor.java:68)
    at org.apache.flume.SinkRunner$PollingRunner.run(SinkRunner.java:147)
    at java.lang.Thread.run(Thread.java:745)

錯誤信息提示:

java.lang.NoSuchMethodError: org.apache.hadoop.hbase.client.Put.setWriteToWAL(Z)V

查看源碼,SimpleHbaseEventSerializer和 RegexHbaseEventSerializer的getActions函數產生的是put對象實例,也就是org.apache.hadoop.hbase.client.Put實例(想要了解更詳細的內容,可以閱讀本文的【附錄:源碼解讀】章節)。org.apache.hadoop.hbase.client.Put裏的確包含setWriteToWAL(boolean write)這個函數。新版本的hbase(0.98以上版本),setWriteToWAL(boolean write)方法改變了返回值,從void 變成了 Mutation。而flume-1.6.0以及以下版本,無法適配setWriteToWAL(boolean write)的改變,從而導致出錯。

與SimpleHbaseEventSerializer和 RegexHbaseEventSerializer不同的是,SimpleAsyncHbaseEventSerializer的getActions函數不是產生put實例,而是生成PutRequest實例。而PutRequest實例是可以與任意版本的HBase接口適配的。

想要了解更詳細的內容,可以閱讀本文的【附錄:源碼解讀】章節。

【解決方法】

(1) 如果不改變flume的版本,那麼需要將HBase降級到0.98 及以下版本;

(2) 如果不改變HBase版本,需要將flume升級到 1.7.0 及以上版本。

四、總結flume與HBase版本適配問題&&用戶自定義HBase 的column
總結:經過上述解讀,以及作者本人驗證,有以下幾條經驗總結:

4.1 flume與HBase版本適配問題
4.1.1 對於HBasesink
(a) 對於Flume-1.6.0 及以下版本:HBasesink目前只支持往 HBase-0.98 版本及以下版本寫入數據,當HBase超過0.98版本,1.6.0 及以下版本的Flume則不支持往HBase寫入數據;

(b) 對於Flume-1.7.0 及以上版本:HBasesink目前支持往0.98及以上版本的HBase寫入數據(當然也支持往0.98及以下版本的HBase寫入數據);

4.1.2 對於AsyncHBaseSink
(a) 支持所有版本的HBase寫入數據。

(b) 不支持0.96及以上版本的HBase 的IPC通信方式------ the new HBase IPC which was introduced in HBase 0.96 and up。

4.2 flume-hbase-sink支持用戶自定義HBase的column
4.2.1 對於HBasesink
(a)序列化模式SimpleHbaseEventSerializer

將整個事件event的body部分當做完整的一列寫入hbase,因此在插入HBase的時候,一個event的body只能被插入一個column;

(b) 序列化模式RegexHbaseEventSerializer

根據正則表達式將event body拆分到不同的列當中,因此在插入HBase的時候,支持用戶自定義插入同一個rowkey對應的同一個columnFamily 的多個column。

4.2.2 對於AsyncHBaseSink
目前只提供一種序列化模式:SimpleAsyncHbaseEventSerializer:

將整個事件event的body部分當做完整的一列寫入hbase,因此在插入HBase的時候,一個event的body只能被插入一個column。

轉載自:https://cloud.tencent.com/developer/article/1025430

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章