導語:本文細緻而全面地講解使用flume輸出數據到HBase的三種不一樣 Flume-Hbase-Sink 之間的差別性,以及技術細節。而且透徹而全面地總結了不一樣版本flume和HBase之間的兼容性問題。 爲了更加詳細說明三種不一樣hbasesink的差別性,本文在附錄附上詳細的源碼解讀。html
1、Flume 的HBaseSinks 詳細介紹
Flume 有兩大類 HBasesinks: HBaseSink (org.apache.flume.sink.hbase.HBaseSink) 和 AsyncHBaseSink (org.apache.flume.sink.hbase.AsyncHBaseSink) 。java
1.一、HBasesink
提供兩種序列化模式:正則表達式
1.1.一、SimpleHbaseEventSerializer
將整個事件event的body部分當作完整的一列寫入hbase,所以在插入HBase的時候,一個event的body只能被插入一個column;apache
1.1.二、RegexHbaseEventSerializer
根據正則表達式將event 的body拆分到不一樣的列當中,所以在插入HBase的時候,支持用戶自定義插入同一個rowkey對應的同一個columnFamily 的多個column。安全
【優勢】ide
(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。oop
【缺點】性能
性能沒有AsyncHBaseSink高。由於HBaseSink採用阻塞調用(blocking calls),而AsyncHBaseSink採用非阻塞調用(non-blocking calls)。ui
1.二、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。
2、兩大類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
3、使用flume-hbase-sink的常見錯誤總結
3.一、無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.二、低版本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 及以上版本。
4、總結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。