天天看點

如何在 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 中的讀取操作首先通路活動記憶體表(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