1 配置內存
-Xloggc:<LOG_DIR>/gc.log
-XX:+PrintGCDetails
-XX:-OmitStackTraceInFastThrow
-XX:+PrintGCTimeStamps
-XX:+PrintGCDateStamps
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=20
-XX:GCLogFileSize=20M
優化GC
開發Flink應用程序時,優化DataStream的數據分區或分組操作。
2 設置並行度
算子層次
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> text = [...]
DataStream<Tuple2<String, Integer>> wordCounts = text
.flatMap(new LineSplitter())
.keyBy(0)
.timeWindow(Time.seconds(5))
.sum(1).setParallelism(5);
wordCounts.print();
env.execute("Word Count Example");
執行環境層次
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(3);
DataStream<String> text = [...]
DataStream<Tuple2<String, Integer>> wordCounts = [...]
wordCounts.print();
env.execute("Word Count Example");
客戶端層次
系統層次
3.配置進程參數
在使用yarn-session命令時,添加“-jm MEM”參數設置內存。
在使用yarn-cluster命令時,添加“-yjm MEM”參數設置內存。
在使用yarn-session命令時,添加“-n NUM”參數設置TaskManager個數。
在使用yarn-cluster命令時,添加“-yn NUM”參數設置TaskManager個數。
在使用yarn-session命令時,添加“-s NUM”參數設置SLOT數。
在使用yarn-cluster命令時,添加“-ys NUM”參數設置SLOT數。
將在使用yarn-sesion命令時,添加“-tm MEM”參數設置內存。
將在使用yarn-cluster命令時,添加“-ytm MEM”參數設置內存。
設計分區方法
隨機分區:將元素隨機地進行分區。dataStream.shuffle();
Rebalancing (Round-robin partitioning):基於round-robin對元素進行分區,使得每個分區負責均衡。對於存在數據傾斜的性能優化是很有用的。dataStream.rebalance();
Rescaling:以round-robin的形式將元素分區到下游操作的子集中。如果你想要將數據從一個源的每個並行實例中散發到一些mappers的子集中,用來分散負載,但是又不想要完全rebalance 介入(引入rebalance()),這會非常有用。dataStream.rescale();
廣播:廣播每個元素到所有分區。dataStream.broadcast();
自定義分區:使用一個用戶自定義的Partitioner對每一個元素選擇目標task,由於用戶對自己的數據更加熟悉,可以按照某個特徵進行分區,從而優化任務執行。簡單示例如下所示:
// fromElements構造簡單的Tuple2流
DataStream<Tuple2<String, Integer>> dataStream = env.fromElements(Tuple2.of("hello",1), Tuple2.of("test",2), Tuple2.of("world",100));
// 定義用於分區的key值,返回即屬於哪個partition的,該值加1就是對應的子任務的id號
Partitioner<Tuple2<String, Integer>> strPartitioner = new Partitioner<Tuple2<String, Integer>>() {
@Override
public int partition(Tuple2<String, Integer> key, int numPartitions) {
return (key.f0.length() + key.f1) % numPartitions;
}
};
// 使用Tuple2進行分區的key值
dataStream.partitionCustom(strPartitioner, new KeySelector<Tuple2<String, Integer>, Tuple2<String, Integer>>() {
@Override
public Tuple2<String, Integer> getKey(Tuple2<String, Integer> value) throws Exception {
return value;
}
}).print();
配置netty網絡通信
“taskmanager.network.netty.sendReceiveBufferSize”:默認是系統緩衝區大小(cat /proc/sys/net/ipv4/tcp _ [rw]mem) ,一般爲4MB,表示netty的發送和接收的緩衝區大小。
“taskmanager.network.netty.transport”:默認爲“nio”方式,表示netty的傳輸方式,有“nio”和“epoll”兩種方式。
解決數據傾斜
需要重新設計key,以更小粒度的key使得task大小合理化。
修改並行度。
調用rebalance操作,使數據分區均勻。
由於task在執行過程中存在數據通過網絡進行交換,數據在不同服務器之間傳遞的緩衝區超時時間可以通過setBufferTimeout進行設置。
當設置“setBufferTimeout(-1)”,會等待緩衝區滿之後纔會刷新,使其達到最大吞吐量;當設置“setBufferTimeout(0)”時,可以最小化延遲,數據一旦接收到就會刷新;當設置“setBufferTimeout”大於0時,緩衝區會在該時間之後超時,然後進行緩衝區的刷新。示例可以參考如下:env.setBufferTimeout(timeoutMillis); env.generateSequence(1,10).map(new MyMapper()).setBufferTimeout(timeoutMillis);
Checkpoint 調優
Flink 作業的問題定位
看反壓 :通常最後一個被壓高的 subTask 的下游就是 job 的瓶頸之一。
看 Checkpoint 時長 :Checkpoint 時長能在一定程度影響 job 的整體吞吐。
看核心指標 :指標是對一個任務性能精準判斷的依據,延遲指標和吞吐則是其中最爲關鍵的指標。
資源的使用率:提高資源的利用率是最終的目的。
在關注背壓的時候大家往往忽略了數據的序列化和反序列化,過程所造成的性能問題。
一些數據結構 ,比如 HashMap 和 HashSet 這種 key 需要經過 hash 計算的數據結構,在數據量大的時候使用 keyby 進行操作, 造成的性能影響是非常大的。
數據傾斜 是我們的經典問題,後面再進行展開。
如果我們的下游是 MySQL,HBase這種,我們都會進行一個批處理的操作,就是讓數據存儲到一個 buffer 裏面,在達到某些條件的時候再進行發送,這樣做的目的就是減少和外部5. 系統的交互,降低 網絡開銷 的成本。
頻繁GC ,無論是 CMS 也好,G1也好,在進行 GC 的時候,都會停止整個作業的運行,GC 時間較長還會導致 JobManager 和 TaskManager 沒有辦法準時發送心跳,此時 JobManager 就會認爲此 TaskManager 失聯,它就會另外開啓一個新的 TaskManager
窗口是一種可以把無限數據切割爲有限數據塊的手段。比如我們知道,使用滑動窗口的時候數據的重疊問題,size = 5min 雖然不屬於大窗口的範疇,可是 step = 1s 代表1秒就要進行一次數據的處理,這樣就會造成數據的重疊很高,數據量很大的問題。
本文分享自微信公衆號 - 大數據技術與架構(import_bigdata)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。