大數據

如何在 Flink 中規劃 RocksDB 內存容量?

作者:Stefan Richter
翻譯:毛家琦
校對:胡爭

本文描述了一些配置選項,這些選項將幫助您有效地管理規劃 Apache Flink 中 RocksDB state backend 的內存大小。在前面的文章[1]中,我們描述了 Flink 中支持的可選 state backend 選項,本文將介紹跟 Flink 相關的一些 RocksDB 操作,並討論一些提高資源利用率的重要配置。

Tips:從 Flink 1.10 開始,Flink 自動管理 RocksDB 的內存,詳細介紹如下:

https://ci.apache.org/projects/flink/flink-docs-release-1.10/ops/state/state_backends.html#memory-management

RocksDB 的狀態後端

在深入瞭解配置參數之前,先回顧一下在 Apache Flink 中如何使用 RocksDB 來進行狀態管理。當選擇 RocksDB 作為狀態後端時,狀態將作為序列化字節串存在於堆外內存(off-heap) 存儲或本地磁盤中。

RocksDB 是一個以日誌合併樹( LSM 樹)作為索引結構的 KV 存儲引擎。當用於在 Flink 中存儲 kv 狀態時,鍵由 的序列化字節串組成,而值由狀態的序列化字節組成。每次註冊 kv 狀態時,它都會映射到列族(column-family)(類似於傳統數據庫中的表),並將鍵值對以字節串存儲在 RocksDB 中。這意味著每次讀寫(READ or WRITE)操作都必須對數據進行反序列化或者序列化,與 Flink 內置的 in-memory 狀態後端相比,會有一些性能開銷。

使用 RocksDB 作為狀態後端有許多優點:

  • 不受 Java 垃圾回收的影響,與 heap 對象相比,它的內存開銷更低,並且是目前唯一支持增量檢查點(incremental checkpointing)的選項。
  • 使用 RocksDB,狀態大小僅受限於本地可用的磁盤空間大小,這很適合 state 特別大的 Flink 作業。

下面的圖表將進一步闡明 RocksDB 的基本讀寫操作。

RocksDB 的一次寫入操作將把數據寫入到內存的 MemTable 中。當 MemTable 寫滿時,它將成為 READ ONLY MemTable,並被一個新申請的 MemTable 替換。只讀 MemTable 被後臺線程週期性地刷新到磁盤中,生成按鍵排序的只讀文件,這便是所謂的 SSTables。這些 SSTable 是不可變的,通過後臺的多路歸併實現進一步的整合。如前所述,對於 RocksDB,每個註冊狀態都是一個列族,這意味著每個狀態都包含自己的 MemTables 和 SSTables 集。

rocksdb.jpeg

RocksDB 中的讀取操作首先訪問活動內存表(Active Memory Table)來反饋查詢。如果找到待查詢的 key,則讀取操作將由新到舊依次訪問,直到找到待查詢的 key 為止。如果在任何 MemTable 中都找不到目標 key,那麼 READ 操作將訪問 SSTables,再次從最新的開始。SSTables 文件可以:

  1. 優先去 RocksDB 的 BlockCache 讀取;
  2. 如果 BlockCache 沒有的話,就去讀操作系統的文件,這些文件塊又可能被操作系統緩存了;
  3. 最差的情況就是去本地磁盤讀取;
  4. SST 級別的 bloom filter 策略可以避免大量的磁盤訪問。

## 管理 RocksDB 內存的 3 種配置

現在,我們理解了 Flink 和 Rocksdb 的協作機制,接下來看看可以更有效地管理 RocksDB 內存大小的配置選項有哪些?請注意,下面的選項並不詳盡,因為您可以使用 Apache Flink 1.6 中引入的 state TTL(Time To Live)功能來規劃 Flink 應用程序的狀態大小。

以下三種配置可以有效幫助您管理 Rocksdb 的內存開銷:

1.block_cache_size 的配置

此配置最終將控制內存中緩存的最大未壓縮塊數。隨著塊數的不斷增加,內存大小也會增加。因此,通過預先配置,您可以保持固定的內存消耗水平。

2.write_buffer_size 的配置

這種配置控制著 RocksDB 中 MemTable 的最大值。活躍 MemTables 和只讀的 MemTables 最終會影響 RocksDB 中的內存大小,所以提前調整可能會在以後為您避免一些麻煩。

3.max_write_buffer_number 的配置

在 RocksDB 將 MemTables 導出到磁盤上的 SSTable 之前,此配置決定並控制著內存中保留的 MemTables 的最大數量。這實際上是內存中“只讀內存表“的最大數量。

除了上面提到的資源之外,您還可以選擇配置索引和 bloom 過濾器,它們將消耗額外的內存空間, Table 級別的 Cache 也是一樣。

在這裡,Table 緩存不僅會額外佔用 RocksDB 的內存,還會佔用 SST 文件的打開文件描述符,(在默認情況下設置的大小是不受限制的),如果配置不正確,可能會影響操作系統的設置。

我們剛剛給您指導了一些使用配置選項,這些配置有助於高效管理 RocksDB 作為 Flink statebackend 的內存大小。有關更多配置選項,我們建議查看 RocksDB 優化指南[2]或 Apache Flink 文檔。

參考資料:

[1] https://www.ververica.com/blog/stateful-stream-processing-apache-flink-state-backends
[2] https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide

原文鏈接:https://www.ververica.com/blog/manage-rocksdb-memory-size-apache-flink

Leave a Reply

Your email address will not be published. Required fields are marked *