實現背景:
消費Kafka數據寫入HBase時,單條處理效率太低。需要批量插入hbase,這裏自定義時間窗口countWindowAll 實現100條hbase插入一次Hbase
前面我就不寫了 直接上核心代碼
/*每10秒一個處理窗口*/
DataStream<List<Put>> putList = filterData.countWindowAll(Constants.windowCount).apply(new AllWindowFunction<String, List<Put>, GlobalWindow>() {
@Override
public void apply(GlobalWindow window, Iterable<String> message, Collector<List<Put>> out) throws Exception {
List<Put> putList=new ArrayList<Put>();
for (String value : message)
{
String rowKey=value.replace("::","_");
Put put = new Put(Bytes.toBytes(rowKey.toString()));
String[] column=value.split("::");
for (int i = 0; i < column.length; i++) {
put.addColumn(Bytes.toBytes(Constants.columnFamily),Bytes.toBytes(Constants.columnArray[i]),Bytes.toBytes(column[i]));
}
putList.add(put);
}
out.collect(putList);
}
}).setParallelism(4);
putList.addSink(new HBaseSinkFunction()).setParallelism(1);
這裏sink需要繼承Flink的RichSinkFunction接口,實現其中的三個比較重要的函數:
1.open()任務開始只調用一次
2.invoke()每接收一條記錄調用一次,多條記錄調用多次
3.close()任務關閉只調用一次
寫HBase自定義Sink爲
HBaseSinkFunction extends RichSinkFunction<List<Put>>{
@Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
HbaseUtils.connectHbase();
TableName table=TableName.valueOf(Constants.tableNameStr);
Admin admin = HbaseUtils.connection.getAdmin();
if(!admin.tableExists(table)){
HTableDescriptor tableDescriptor = new HTableDescriptor(Constants.tableNameStr);
tableDescriptor.addFamily(new HColumnDescriptor(Constants.columnFamily));
admin.createTable(tableDescriptor);
}
}
@Override
public void invoke(List<Put> putList, Context context) throws Exception {
Table table=HbaseUtils.connection.getTable(TableName.valueOf(Constants.tableNameStr));
table.put(putList);
}
@Override
public void close() throws Exception {
super.close();
HbaseUtils.closeHBaseConnect();
}
}