Flink實戰之寫Hive效能問題

優優我心發表於2020-11-27

上一篇中寫了Kafka to Hive的樣例,在實際測試過程中,發現效能比較差。

問題1

我使用的是Flink1.11.1版本,這個版本有個效能上的問題,見FLINK-19121。該問題已經在1.11.3版本中修復,
在HiveTableSink中沿用了FileSystemTableSink的TableRollingPolicy,再該policy中每條資料都會呼叫

@Override
		public boolean shouldRollOnEvent(
				PartFileInfo<String> partFileState,
				RowData element) throws IOException {
			return partFileState.getSize() > rollingFileSize;
		}

在PartFileInfo對應Hivesink的實現是HadoopPathBasedPartFileWriter,最終會呼叫

@Override
			public long getSize() throws IOException {
				return fs.getFileStatus(inProgressPath).getLen();
			}

每次都會取請求HDFS來獲取檔案的大小,這就使得很大的開銷花費在和HDFS互動上,同時對HDFS造成了很大的IO壓力。

問題2

將上面的bug修復之後進行測試,發現寫資料的速度仍然要落後kafka生產速度,任務執行30分鐘後就已經達到3分鐘的落後,持續執行下去落後將越來越大。
官網有這樣一個配置引數table.exec.hive.fallback-mapred-writer
預設是false 使用MR writer
設為true則使用flink native writer,即StreamingFileSink的BulkWriter。
所以將該引數設為false之後進行測試,寫入速度基本和生產速度一致了。
既然MR writer相比BulkWriter效能差很多,為什麼不預設使用BulkWriter主要有兩個原因:

  1. 支援的資料型別沒有MR writer的全
  2. BulkWriter 支援parquet和orc,但只支援orc的最新版本,寫入低版本有相容性問題

相關文章