Flink ステート バックエンドと RocksDB のチューニング

目次

1 状態バックエンドとは何ですか?

2 ステータスバックエンドの分類?

メモリ状態バックエンド

知らせ

FsStateBackend

該当シーン

RocksDBStateバックエンド

該当シーン

注意点

3 RocksDB の大規模な状態チューニング

ローカルの Rocks の複数のディレクトリをセットアップする

増分チェックポイントをオンにする

ブロックサイズ

ブロックキャッシュサイズ

開いているファイルの最大数

キャッシュインデックスとフィルターブロック

ヒットのフィルターを最適化

書き込みバッファサイズ

レベルベースの最大バイト数

書き込みバッファ数

マージする最小書き込みバッファ数

スレッド数(並列度)

書き込みバッチサイズ

圧縮スタイル

圧縮タイプ


1 状態バックエンドとは何ですか?

状態を保存する方法と場所を指定する

2 ステータスバックエンドの分類?

メモリ状態バックエンド

  1. 実行時に必要な状態データは、TaskManager JVM ヒープ上のメモリに保存されます

  2. チェックポイントは JobManager プロセスのメモリに保存され、同期/非同期スナップショットを選択できます。

知らせ

1) 状態は JobManager のメモリに保存され、JobManager のメモリ サイズによって制限されます。

2) 各状態のデフォルトは 5MB ですが、これは MemoryStateBackend コンストラクターを通じて調整できます。

3) 各州は Akka フレーム サイズを超えることはできません

FsStateBackend

  1. 実行時に必要な状態データは、TaskManager JVM ヒープ上のメモリに保存されます

  2. チェックポイントはファイル システム (HDFS) に保存されます

  3. 実行時に必要な状態データは、TaskManager JVM ヒープ上のメモリに保存されます

該当シーン

1) 大きな状態、長いウィンドウ、または大きなキーと値の状態を伴うステートフル処理タスク

2) 高可用性

注意点

1) 状態データは最初にタスクマネージャーのメモリに保存されます。

2) 状態サイズは TM メモリを超えることはできません

3) TM は状態データを外部ストレージに非同期で書き込みます

RocksDBStateバックエンド

  1. 組み込みローカル データベース RocksDB を使用して、フロー コンピューティング データの状態をローカル ディスクに保存します。これは、タスク マネージャーのメモリ サイズによって制限されません。

  2. チェックポイントを実行すると、RocksDB 全体に保存された状態データが、構成されたファイル システムに完全または増分的に保存されます。

  3. 少量のチェックポイント メタデータが JobManager メモリに保存されます

  4. RocksDB は、ステートがメモリによって制限されるという問題を克服すると同時に、リモート ファイル システムに永続化できるため、運用環境での使用に適しています。

該当シーン

1) 大きな状態、長いウィンドウ、または大きなキーと値の状態を伴うステートフル処理タスク

2) 高可用性

3) RocksDBStateBackend は増分チェックポイントをサポートします。増分チェックポイントは、非常に大きな状態のシナリオに非常に適しています。

注意点

1) ステートの合計サイズはディスク サイズに制限され、メモリによって制限されません。

2) RocksDBStateBackend は、状態を一元的に保存するために外部ファイル システムを構成する必要もあります

3 RocksDB の 大規模な状態チューニング

非常に大きな状態 (メモリ容量をはるかに超える) を保存する必要があるストリーム コンピューティング シナリオの場合、Flink プラットフォームで正式に実装するには、現時点では RocksDB が唯一の選択肢です。業界には、Redis やその他のサービスを状態バックエンドとして使用するソリューションもありますが、結局のところ、それらは十分に成熟しておらず、コミュニティによって拒否されています。

RocksDB は、LSM ツリー原理に基づいて実装された KV データベースです。LSM ツリーの読み取り増幅の問題は深刻であるため、ディスク パフォーマンス要件は比較的高くなります。運用環境では、RocksDB の記憶媒体として SSD を使用することを強くお勧めします。ただし、一部のクラスターは SSD ではなく、通常の機械式ハードディスクで構成されている場合があり、Flink タスクが比較的大きく、状態アクセスが頻繁である場合、機械式ハードディスクのディスク IO がパフォーマンスのボトルネックになる可能性がありますこの場合、このボトルネックをどのように解決すればよいでしょうか?

複数のハードドライブを使用して負荷を分散する

RocksDB はメモリとディスクを使用してデータを保存するため、ステータスが比較的大きい場合、ディスク容量も比較的大きくなります。RocksDB への読み取りリクエストが頻繁に発生すると、ディスク IO が Flink タスクのボトルネックになります。

タスクマネージャーに 3 つのスロットが含まれている場合、単一サーバー上の 3 つの並列度により、ディスクへの読み取りと書き込みが頻繁に行われ、同じディスク IO に対して 3 つの並列度が互いに競合し、必然的に 3 つのスロットが発生します。並列度が高くなると、スループットが低下します。

幸いなことに、Flink の state.backend.rocksdb.localdir パラメータでは複数のディレクトリを指定できます。一般に、ビッグ データ サーバーは多くのハードディスクをマウントします。リソースの競合を減らすために、同じタスク マネージャーの 3 つのスロットが異なるハードディスクを使用することが予想されます。具体的な構成は以下の通り

  • ローカルの Rocks の複数のディレクトリをセットアップする

state.backend.rocksdb.localdir: /data1/flink/rocksdb,/data2/flink/rocksdb,/data3/flink/rocksdb,/data4/flink/rocksdb,/data5/flink/rocksdb,/data6/flink/rocksdb,/data7/flink/rocksdb,/data8/flink/rocksdb,/data9/flink/rocksdb,/data10/flink/rocksdb,/data11/flink/rocksdb,/data12/flink/rocksdb

注: 必ず複数の異なるディスク上にディレクトリを構成してください。単一のディスク上に複数のディレクトリを構成しないでください。ここで複数のディレクトリを構成する目的は、複数のディスクが圧力を共有できるようにすることです。

以下に示すのは、テスト中のディスクの IO 使用率です。3 つの大きな状態演算子の並列処理が 3 台のディスクに対応していることがわかります。これら 3 台のディスクの平均 IO 使用率は約 45% のままで、最も高い IO が使用されています。使用率はほぼ 100% ですが、他のディスクの平均 IO 使用率は比較的低いです。RocksDB を状態バックエンドとして使用し、大きな状態の読み取りが頻繁に行われる場合、ディスク IO パフォーマンスの消費が実際に比較的大きくなることがわかります。

  • 増分チェックポイントをオンにする

state.backend.incremental 开启增量检查点,默认false。或代码中指定new EmbededRocksDBStateBackend(true)

  • ブロックサイズ

state.backend.rocksdb.block.blocksize のデフォルト値は 4KB です。運用環境を 16 ~ 32KB に調整することをお勧めします。読み取りおよび書き込みのパフォーマンスを向上させるためにブロック サイズを増やす必要がある場合は、必ずブロック サイズを増やしてください。ブロック キャッシュ サイズも比較できるため、優れた読み取りおよび書き込みパフォーマンスが得られます。メモリがすでに不足している場合は、ブロック キャッシュ サイズを増やし続けることはお勧めできません。そうしないと、OOM のリスクが発生します (コンテナ環境で使用されるメモリの総量が制限されている場合、これはより明白になります)。ブロック サイズを増やした後は、書き込みパフォーマンスが許容できるかどうかに注意しながら、ブロック サイズを適切に減らしてスループットを向上させることができます。

  • ブロックキャッシュサイズ

state.backend.rocksdb.block.cache-size  RocksDB全体でブロックキャッシュを共有します データ読み込み時のメモリのキャッシュサイズ パラメータが大きいほどデータ読み込み時のキャッシュヒット率が高くなります デフォルトのサイズは8MBです通常はメモリが豊富な場合に使用されますが、64~256MB に設定することをお勧めします。

state.backend.rocksdb.metrics.metrics.block-cache-usage 監視インジケーターを開始して、ブロック キャッシュの使用状況をリアルタイムで観察し、対象を絞った最適化を行うこと   ができます。

  • 開いているファイルの最大数

パラメータstate.backend.rocksdb.files.open は 、RocksSB が開くことができるファイル ハンドルの最大数を決定します。デフォルト値は 5000 です。-1 (無制限) に変更することをお勧めします。このパラメータが小さすぎる場合は、インデックスとフィルターブロックが表示されます。メモリにロードできない問題により、読み取りパフォーマンスが大幅に低下します。cache_index_and_filter_blocksはfalse に設定されます。

  • キャッシュインデックスとフィルターブロック

cache_index_and_filter_blocks(blockBasedTableConfig.setCacheIndexAndFilterBlocks)、デフォルトは false で、インデックスとフィルター ブロックはメモリにキャッシュされませんが、使用されない場合はロードされ、キックアウトされることを示します。true に設定すると、これらのインデックスとフィルターをバックアップ用にブロック キャッシュに配置できることを意味します。これにより、ローカル データ アクセスの効率が向上します (ディスク アクセスなしで、キーがあるかどうか、およびキーがどこにあるかを知ることができます)。ただし、このオプションが有効な場合は、pin_I0_filter_and_index_blocks_in_cache (blockBasedTableConfig.pinL0FilterAndIndexBlocksinCache) パラメーターも true に設定する必要があります。そうしないと、オペレーティング システムのページング操作によりパフォーマンスのジッターが発生する可能性があります。

このパラメータでは、ブロック キャッシュの合計サイズが制限されていることに注意することが重要で、インデックスとフィルターを入れることが許可されている場合、データを保存するスペースが少なくなります。したがって、キーにローカル ホットスポットがある場合にのみ、これら 2 つのパラメータをオンにすることをお勧めします (一部のキーは頻繁にアクセスされ、他のキーはほとんどアクセスされません)。比較的ランダムな分布を持つキーの場合、このパラメータは逆効果になる可能性さえあります (ランダムキーを使用すると、読み取りパフォーマンスが大幅に低下します)

  • ヒットのフィルターを最適化

optimize_filters_for_hits パラメータ (columnFamilyOptions.setOptimizeFiltersForHits) が true に設定されている場合、RocksDB は L0 のブルーム フィルターを生成しません。ドキュメントによると、フィルター ストレージのオーバーヘッドの 90% を削減でき、メモリ使用量の削減に有益です。ただし、このパラメーターは、ローカル ホットスポットがあるシナリオ、またはキャッシュ ミスがめったに発生しないことが確実なシナリオにのみ適用できます。それ以外の場合、キャッシュ ミスが頻繁に発生し、読み取りパフォーマンスが低下します。

キャッシュやフィルターなどのメモリ使用量については、Flink の state.backend.rocksdb.metrics.estimate-table-readers-mem 監視インジケーターを通じて推定できます。

  • 書き込みバッファサイズ

state.backend.rocksdb.writebuffer.size のデフォルト サイズは 64MB ですが、一般的に、Writer Buffer が大きいほど書き込み増幅効果が小さくなるため、書き込みパフォーマンスも向上します。

  • レベルベースの最大バイト数

state.backend.rocksdb.compaction.level.max-size-level-base.書き込みバッファ サイズを増やす場合は、必ず L1 層のサイズしきい値 (max_bytes_for_level_base) を増やすようにしてください。非常に大きな影響を及ぼします。このパラメータが小さすぎる場合、各レイヤに保存される SST ファイルの数が非常に少なくなり、レベルが多くなり、検索が困難になります。このパラメータが大きすぎる場合、各レイヤにファイルが多すぎます。コンパクションなどの処理が行われるため、時間がかかり、Write Stall現象が発生しやすくなり、書き込みが中断される可能性があります。

  • 書き込みバッファ数

Flink の state.backend.rocksdb.writebuffer.count パラメータ ( columnFamilyOptions.setMaxWriteBufferNumberを通じて設定することもできます) は、メモリ内に保持できる MemTable の最大数を制御できます。この数を超えると、ディスクにフラッシュされます。 by フラッシュしてSST.ドキュメントになります。

このパラメータのデフォルト値は 2 です。メカニカル ディスクの場合、メモリが十分に大きい場合は、メモリを約 5 に増やして MemTable のサイズを減らし、フラッシュ操作中の書き込み停止の可能性を減らすことができます。

  • マージする最小書き込みバッファ数

Flink の state.backend.rocksdb.writebuffer.number-to-merge パラメータ ( columnFamilyOptions.setMinWriteBufferNumberToMerge ) は、書き込みバッファのマージの最小しきい値を決定します。デフォルト値は 1 です。機械式ハードディスクの場合は、頻繁なマージ操作を避けるために適切に増やすことができます. 書き込み一時停止が原因です。

弊社のチューニング経験によると、このパラメータを小さく調整しても大きく調整してもパフォーマンスの低下が生じることが多く、その最適値は中間値 (3 など) に近い値になります。

MemTable が占有する推定メモリ サイズ インジケーターについては、リアルタイム監視のためにFlink のstate.backend.rocksdb.metrics.cur-size-all-mem-tablesパラメーターを有効にすることができます。

  • スレッド数(並列度)

state.backend.rocksdb.thread.num このパラメータを使用すると、ユーザーはバックグラウンドのコンパクションおよびフラッシュ操作の最大スレッド数を増やすことができます。デフォルトでは、フラッシュ操作は高優先度のキューに入れられ、コンパクション操作は低優先度のキューに入れられます。

バックグラウンド スレッドのデフォルトの数は 1 ですが、メカニカル ハード ディスクのユーザーはこれを 4 またはその他の大きな値に変更できます。

バックグラウンドのすべてのスレッドが圧縮操作を実行しており、この時点で突然多くの書き込みリクエストが発生すると、書き込み停止 (Write Stall) が発生します。書き込み一時停止は、ログまたは監視インジケーターを通じて検出できます。

  • 書き込みバッチサイズ

state.backend.rocksdb.write-batch-size パラメータを使用すると、バッチ書き込み中に RocksDB が占有するメモリの最大量を指定できます。デフォルトは 2m です。0 に設定すると、タスクの量に応じて自動的に調整されます。このパラメータに特別な要件がない場合は、調整する必要はありません。

  • 圧縮スタイル

state.backend.rocksdb.compaction.style パラメータ (ColumnFamilyOptions の setCompactionStyle メソッド) を使用すると、ユーザーは圧縮の構成を調整できます。デフォルト値は LEVEL (よりバランスの取れた) ですが、UNIVERSAL または FIFO に変更することもできます。

デフォルトの LEVEL モードと比較すると、UNIVERSAL は階層型の一種であり、書き込み増幅効果を減らすことができますが、副作用としてスペース増幅と読み取り増幅効果が増加するため、大規模な書き込みとまれな読み取りにのみ適しています。同時に十分なディスク容量があること。

FIFO は先入れ先出しアルゴリズムであり、期限切れの古いデータをバッチで削除できるため、RocksDB が時系列データベースとして使用されるシナリオに適しています。

  • 圧縮タイプ

ColumnFamilyOptions クラスは、Block の圧縮アルゴリズムを指定できる setCompressionType メソッドを提供します。

RocksDB は、非圧縮、Snappy、ZLib、BZlib2、LZ4、LZ4HC、Xpress、ZSTD などの複数の圧縮アルゴリズムのサポートを提供します。ただし、これを有効にする前に、対応する圧縮アルゴリズム ライブラリがインストールされているかどうかを確認する必要があることに注意してください。システムにインストールされていないと、正しく機能しない可能性があります。

パフォーマンスを追求する場合は、圧縮をオフにすることができます (NO_COMPRESSION)。それ以外の場合は、LZ4 アルゴリズムを使用し、その後に Snappy アルゴリズムを使用することをお勧めします。圧縮を有効にした後、ReadOptions の verify_checksums オプションをオフにして読み取り速度を向上させることができます (ただし、ディスクの不良ブロックの影響を受ける可能性があります)。

 

おすすめ

転載: blog.csdn.net/qq_24186017/article/details/127177554