Apache Flink ブロードキャスト変数の最適化: FLIP-5によるネットワークオーバーヘッド削減のアプローチ

> 本記事は[こちらのブログ](https://www.alibabacloud.com/blog/apache-flink-broadcast-variable-optimization-flip-5s-approach-to-reducing-network-overhead_602159?spm=a2c65.11461433.0.0.4ee35355bu6s4v)を参考にしています。
> 翻訳にはアリババクラウドの[ModelStudio](https://www.alibabacloud.com/en/product/modelstudio)([Qwen](https://www.alibabacloud.com/en/solutions/generative-ai/qwen))を使用しております。

# Apache Flink® コミュニティに参加して、Flinkでのデータ配信をより効率的にする方法を学ぼう。はじめに

クラスの代表で、重要な学習資料をクラスメートに配布する必要があると想像してください。もしクラスがいくつかのグループに分かれている場合、どうしますか？各グループに1部ずつコピーを作り、グループリーダーにメンバーに配布させるか、それとも生徒全員に個別にコピーを作るでしょうか？明らかに、前者の方が紙の節約にもなり、効果的です。Flinkの初期のブロードキャスト変数配布メカニズムは、同じTaskManager（グループに相当）内にいる一部の学生がいる場合でも、各学生に1部ずつコピーを渡すようなものでした。これはネットワーク帯域を浪費するだけでなく、全体のパフォーマンスにも影響を与えます。この問題に対処するためにFLIP-5が提案されました。

## 古いアプローチの何が問題だったのか？
次の例を使って現在の問題を説明しましょう：
![_2025_04_18_11_36_22](https://yqintl.alicdn.com/5c3429997e77722d4a6fe927c28bb09cbd1015bb.png)

上記の例では、TaskManagerには複数のSlots（処理スロット）があります。ブロードキャスト変数を使用すると、これらのSlotsが同じTaskManager上に存在する場合でも、同じデータが各Slotに送られます。これにより主に以下の2つの問題が発生します：

### ネットワークトラフィックの無駄
同じTaskManager上の複数のSlotsが同一のデータのコピーを受信する。

### パフォーマンスの劣化
TaskManagerごとのSlotsの数が増えるにつれて、転送されるデータ量も比例して増加します。実験データによると、TaskManagerごとのSlotsの数が1から16に増えると、処理時間が大幅に増加します。

- 1 Slotの場合：約6.8秒
- 16 Slotsの場合：37秒以上

## FLIP-5が提案した解決策とは？

研究チームはいくつかの解決策を提案しました。最も重要なものを以下に見ていきましょう。
![_2025_04_18_11_36_42](https://yqintl.alicdn.com/dec3cd1a97973ccb4783a54b491ed55d1c34b931.png)

### 最終的な解決策：データ配信メカニズムの再設計

最終的な解決策の核心部分は、ブロードキャストデータ配信メカニズムの完全な再構築です。具体的には以下の通りです：

#### TaskManagerごとに1つのサブパーティション
各TaskManagerは、各Slot用ではなく、ブロードキャストデータを受信するために1つのサブパーティションのみ作成し使用します。これは、各クラスリーダー（サブパーティション）に1部の資料を与えるだけで、各生徒（Slot）に与えないことに似ています。

#### 実行エッジのリダイレクト
この解決策では、Flinkの実行グラフを修正し、すべての実行エッジを1つのサブパーティションにリダイレクトする必要があります。これは、複数の散らばった伝送経路を1つのメインルートに統合することに似ています。

![_2025_04_18_11_36_48](https://yqintl.alicdn.com/b5554edf7b925c4535ba655364aa31e9e74f4d05.png)

### データ共有メカニズム

- TaskManager内の1つのタスクがプライマリリーダーとして指定され、サブパーティションからデータを読み取る役割を担います。
- このタスクはデータを逆シリアル化し、TaskManagerレベルの共有メモリ領域に格納します。
- 同じTaskManager上の他のタスクは、この共有メモリ領域から直接データを読み取ることができるため、繰り返しのネットワーク転送や逆シリアル化を回避できます。
- これは、クラスリーダー（プライマリリーダー）が最初に資料を受け取り、教室（共有メモリ）にコピーを作成し、他の生徒たちが直接教室でそれを閲覧できるようにすることに似ています。

### スマートリリースメカニズム

- プライマリリーダータスクは、データ処理を完了した後にリリース信号を送信します。
- 他のタスクは、共有データを使用した後に完了信号を送信します。
- システムはすべてのタスクの状態を追跡し、すべてのタスクがデータをもう必要としないことが確認された場合にのみリソースを解放します。
- このメカニズムにより、すべてのタスクがデータの使用を終了するまでデータがクリアされることはありません。

この解決策は、顕著な改善をもたらしました：

### パフォーマンスの向上

- データ転送量とネットワーク負荷が大幅に削減されました。
- Slotsの数が増えても処理時間は安定しています。
- 実験データによると、Slotsの数を1から16に増やしても、処理時間は約6〜7秒のままでした。

### リソース利用の最適化

- データはTaskManagerごとに1回だけ送信および保存する必要があります。
- より効率的なメモリ使用により、重複したデータの保存が避けられます。
- ネットワーク接続の数が大幅に減少しました。

### 拡張性の向上

- TaskManagerあたりのSlots数が増加してもシステム性能が大幅に低下しなくなりました。
- 大規模な展開シナリオにより適しています。

## なぜこのFLIPは廃棄されたのか？

このFLIPは優れた最適化アイデアを提案しましたが、結局採用されませんでした。その主な理由は以下の通りです：

- **ネイティブイテレーションサポートの問題**：改善計画はFlinkのネイティブイテレーション機能との互換性の問題がありました。
- **実装の複雑さ**：問題を完全に解決するには、Flinkのスケジューリングシステムに大きな変更が必要でした。
- **他の優先度の高い改善点**：コミュニティは他のより緊急の問題に優先順位をつけました。

## まとめ

FLIP-5は最終的に採用されませんでしたが、それが特定した問題と提案した解決策は貴重です。これは、分散データを扱う際にデータ転送効率に特に注意を払うべきであることを思い出させてくれます。この特定の改善は実装されませんでしたが、Flinkコミュニティは他の手段を通じてブロードキャスト変数のパフォーマンスを継続的に最適化しています。これがオープンソースコミュニティの魅力であり、継続的な試みと議論を通じて最も適切な解決策を見つけることができるのです。