背景
本文基于 Flink 1.17.0
寫此文章的目的是為了說明 Flink 堆內和堆外內存以及 內部 BinaryRowData
行處理的優化。
分析
堆內和堆外內存
跟Spark的內存管理不一樣,Flink 中的堆內和堆外一直都是存在的。
堆內內存(JVM Heap)存儲用戶對象和Flink 框架的運行時數據,而堆外內存(Off-heap Memory)包括用于網絡通信的直接內存(Direct Memory)和用于第三方庫(如RocksDB)的堆外內存(offheap Memory)。
分別可以通過 MemorySegmentFactory 的 wrap allocateUnpooledOffHeapMemory allocateOffHeapUnsafeMemory
方法來進行分配對應的堆內,直接內存以及堆外內存。無論是堆內還是堆外內存都是用 MemorySegment
來承載的。
BinaryRowData
關于該BinaryRowData的作用和Spark中一樣
- 減少GC壓力
- 不影響正常的數據操作,減少了數據存儲內存,精確計算內存的使用情況
- 減少了序列化和反序列化的的消耗
Byte大小端
在 MemorySegment
類中,也存在中大小端的判斷:
private static final boolean LITTLE_ENDIAN =(ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN);
在Flink 中,數據需要經過序列化和反序列化才能在網絡中傳輸或持久化存儲。如果數據源的字節序與Flink 運行的機器的字節序不一致,就可能出現解析錯誤。通過區分大端和小端,Flink 能夠正確地進行轉換,確保數據的一致性。