The past, present and future of the Pravega Flink connector
1. Pravega と Pravega コネクタの概要
Pravega プロジェクトの名前はサンスクリット語に由来し、「良好な速度」を意味します。2016 年に始動し、Apache V2 ライセンスに基づいて GitHub でオープンソース化されました。2020 年 11 月に CNCF ファミリーに加わり、CNCF サンドボックスプロジェクトとなりました。
Pravega プロジェクトは大規模なデータフローシナリオを念頭に設計されており、従来のメッセージキューのストレージ面の課題を補完する、新しいエンタープライズレベルのストレージシステムです。ストリームの無制限かつ高性能な読み書きを維持しつつ、エラスティックスケーリングや階層化ストレージといったエンタープライズレベルの機能を追加し、企業ユーザーのコストとメンテナンス負荷の削減を支援します。同時に、ストレージ分野における長年の技術蓄積を活かし、商用ストレージ製品に支えられた永続ストレージも提供できます。
上記のアーキテクチャ図は、Pravega の代表的な読み書きのシナリオを示し、Pravega の主要な用語を紹介することで、システムアーキテクチャの理解を深めることができます。
中央部分は Pravega クラスターで、ストリームを一つの抽象システムとして捉えています。ストリームは Kafka のトピックに相当する概念とみなせます。同様に、Pravega のセグメントは Kafka のパーティションに相当するデータパーティショニングの概念であり、動的スケーリングも提供します。
セグメントにはバイナリデータフローが格納され、データフローのサイズに応じてマージや分割の操作が行われ、リソースの解放や集約が行われます。その際、セグメントはシール処理を実行して新規データの書き込みを防止し、新たに作成されたセグメントが新規データを受け取ります。
図の左側はデータ書き込みのシナリオで、追加のみの書き込みをサポートしています。ユーザーは各イベントにルーティングキーを指定してセグメントの所属を決定できます。これは Kafka の Partitioner に相当します。単一のルーティングキー上のデータは順序が保持され、読み取り時の順序が書き込み時と同一であることが保証されます。
図の右側はデータ読み取りのシナリオで、複数のリーダーがリーダーグループによって制御されています。リーダーグループはリーダー間の負荷分散を制御し、すべてのセグメントがリーダーに均等に分配されるようにします。同時に、チェックポイント機構により整合性のあるストリーム分割を形成し、データの障害復旧を保証します。「読み取り」については、バッチとストリームの両方のセマンティクスをサポートしています。ストリームシナリオではテール読み取りをサポートし、バッチシナリオでは高い同時実行性を考慮して高スループットを実現します。
2. Pravega Flink コネクタのこれまで
Pravega Flink コネクタは、Pravega が最初にサポートしたコネクタです。これは Pravega と Flink の設計思想が非常に一致しているためでもあります。両者ともバッチとストリームを統合したフローベースのシステムであり、ストレージとコンピューティングの完全なソリューションを形成できます。
1. Pravega の開発の歴史
コネクタは 2017 年から独立した GitHub プロジェクトとして運営されています。2017 年には Flink バージョン 1.3 をベースに開発を行い、Stephan Ewen を含む Flink PMC メンバーが参加して、最も基本的な Source/Sink 関数を構築しました。これにより基本的な読み書きと、後述する Pravega チェックポイントの統合がサポートされました。
2018 年の最も重要な成果の一つは、エンドツーエンドでの exactly-once セマンティクスのサポートです。当時、チームは Flink コミュニティと多くの議論を重ねました。Pravega が最初にトランザクション対応の書き込みクライアント機能を実装し、コミュニティ側もこれに協力しました。Sink 関数をベースに 2 相コミットのセマンティクスを実装し、チェックポイントベースの分散トランザクション機能を実現しました。その後、Flink は 2 相コミット API をさらに抽象化し、よく知られた TwoPhaseCommitSinkFunction インターフェイスを確立しました。このインターフェイスは Kafka コネクタにも採用されています。コミュニティではこのインターフェイスと exactly-once セマンティクスについて詳しく解説するブログ記事も公開されています。
2019 年には、バッチ読み取りや Table API のサポートなど、他の API を補完するコネクタが開発されました。
2020 年の主な注力は Flink 1.11 の統合で、FLIP-27 と FLIP-95 の新機能統合に重点が置かれました。
2. チェックポイント統合の実装
Kafka を例にとって、まず Kafka が Flink のチェックポイントをどのように統合しているかを見ていきましょう。
上の図は Kafka の代表的な読み取りアーキテクチャを示しています。Chandy-Lamport アルゴリズムに基づく Flink のチェックポイント実装では、Job Master がチェックポイントをトリガーすると、Task Executor に RPC リクエストを送信します。Task Executor はそれを受信後、自身の状態ストレージに保持している Kafka のコミットオフセットを Job Manager に返して、チェックポイントメタデータを形成します。
詳しく検討すると、いくつかの問題が見つかります。
スケーリングと動的バランスのサポートです。パーティションが調整された場合、あるいは Pravega においてパーティションが動的に拡張・縮小された場合に、マージの整合性をどのように保証するかという課題があります。
もう一つは、Task がオフセット情報を保持する必要があるため、設計全体が Kafka の内部抽象オフセットに結合してしまうという点です。
これらの課題を踏まえ、Pravega は独自に設計されたチェックポイント機構を備えています。Flink のチェックポイントとどのように統合されているかを見ていきましょう。
同じく Pravega ストリームを読み取ります。チェックポイントの開始時点で違いがあります。ここでは、Job Master は Task Executor に RPC リクエストを送るのではなく、ExternallyInducedSource インターフェイスを使って Pravega にチェックポイントリクエストを送信します。
同時に、Pravega は内部の StateSynchronizer コンポーネントを使用してすべてのリーダーを同期・協調させ、リーダー間でチェックポイントイベントを送信します。Task Executor がチェックポイントイベントを読み取ると、Pravega 全体でチェックポイントの完了がマークされ、返された Pravega チェックポイントは Job Master の状態に保存されてチェックポイントが完了します。
この実装方式は Flink にとってよりクリーンです。外部システムの実装詳細に結合せず、チェックポイント処理全体を Pravega に委譲して実装・完了させることができるからです。
3. Flink 1.11 の上位レベル機能に関する体験共有
Flink 1.11 は 2020 年の重要なリリースです。コネクタにとっては多くの課題があり、主に FLIP-27 と FLIP-95 の 2 つの FLIP の実装に集中しました。チームはこれらの新機能を統合するために多くの時間を費やし、その過程でいくつかの問題や課題に直面しました。ここでは、どのように問題を発見し解決したかを共有します。本記事では FLIP-95 を例に取り上げます。
1. FLIP-95 の統合
FLIP-95 は新しい Table API です。その動機は FLIP-27 と同様で、バッチとストリームの統合インターフェイスを実現し、同時に CDC との統合をより良くサポートすることを目的としています。冗長な設定キーの問題については、対応する FLIP-122 も提案され、設定キーの簡素化が図られています。
1.1 Pravega の旧 Table API
上の図から、Flink 1.10 以前の Pravega の Table API がわかります。図中のテーブル作成 DDL から以下の点が読み取れます。
update mode と append でバッチとストリームを区別しており、バッチとストリームデータの区別が直感的ではありません。
設定ファイルも非常に長く複雑で、読み取りストリームは connector.reader.stream-info.0 のような非常に長い設定キーを通じて設定する必要があります。
コードレベルでも DataStream API との密な結合が多く、保守が困難です。
これらの問題に対応するため、新しい API セットを実装する大きな動機が生まれ、ユーザーがテーブル抽象をより良く活用できるようになりました。全体のフレームワークを図に示します。新しいフレームワークにより、すべての設定項目は ConfigOption インターフェイスを通じて定義され、PravegaOptions クラスで一元管理されています。
1.2 Pravega の新 Table API
下の図は最新の Table API によるテーブル作成の実装で、以前と比べて大幅に簡素化されています。同時に、エンタープライズレベルのセキュリティオプションの設定、複数のストリームの指定、初期ストリームカットの設定など、機能面でも多くの最適化が施されています。
2. Flink-18641 の解決過程の体験共有
次に、Flink 1.11 の統合に関する経験をもう少し共有します。ある問題の解決過程についての話です。Flink-18641 はバージョン 1.11.0 の統合時に遭遇した問題で、アップグレード過程で単体テストにおいて CheckpointException が報告されました。以下は完全なデバッグ過程です。
まず、自らステップバイステップでブレークポイントデバッグを行いました。エラーログを確認し、関連する Pravega および Flink のソースコードを分析することで、Flink の CheckpointCoordinator に関連する問題であることを特定しました。
次に、コミュニティのコミット履歴を確認したところ、Flink 1.10 以降で CheckpointCoordinator のスレッドモデルが元のロック制御モデルから Mailbox モデルに変更されていたことがわかりました。このモデル変更により、以前は同期的に直列実行されていたロジックが誤って並列実行されるようになり、このエラーが発生していました。
この変更のプルリクエストをさらに詳しく確認し、関連するコミッターにメールで連絡を取りました。最終的に開発メーリングリストで問題を特定し、JIRA チケットを作成しました。
オープンソースコミュニティで活動する仲間の開発者向けに、以下の注意点をまとめました。
メーリングリストと JIRA を検索して、他の人が同様の質問をしていないか確認すること。
問題を完全に記述し、詳細なバージョン情報、エラーログ、再現手順を提供すること。
コミュニティメンバーからフィードバックを得た後、さらなる議論を通じて解決策を検討すること。
非中国語環境では英語が必須であること。
実際、中国の開発者であっても、メーリングリストや JIRA に加え、DingTalk グループやビデオ通話を通じて多くのコミッターと連絡を取ることができます。重要なのはコミュニケーションのプロセスです。オープンソースに取り組むとは、コミュニティと積極的に対話することで、プロジェクトの共同発展を促進できます。
4. 今後の展望
今後の大きな取り組みの一つは、Pravega スキーマレジストリの統合です。Pravega スキーマレジストリは、データスキーマとシリアル化方式を含む Pravega ストリームのメタデータを管理・保存する機能を提供します。この機能は Pravega 0.8 リリース、つまりプロジェクト初のオープンソースリリースに付属しました。今後のバージョン 0.10 では、このプロジェクトをベースに Pravega の Catalog を実装し、Flink の Table API の利用をさらに容易にする予定です。
また、Flink コミュニティの新しい動向にも注目し、コミュニティの新バージョンや新機能の積極的な統合を進めています。現在の計画には FLIP-143 と FLIP-129 が含まれています。
コミュニティでは、Docker コンテナベースの新しいテストフレームワークへの移行も徐々に進んでおり、この動向にも注目し、統合を進めています。
最後に、コミュニティの皆様には Pravega プロジェクトによりご注目いただき、Pravega コネクタと Flink の共同発展を推進していただければ幸いです。
Pravega プロジェクトの名前はサンスクリット語に由来し、「良好な速度」を意味します。2016 年に始動し、Apache V2 ライセンスに基づいて GitHub でオープンソース化されました。2020 年 11 月に CNCF ファミリーに加わり、CNCF サンドボックスプロジェクトとなりました。
Pravega プロジェクトは大規模なデータフローシナリオを念頭に設計されており、従来のメッセージキューのストレージ面の課題を補完する、新しいエンタープライズレベルのストレージシステムです。ストリームの無制限かつ高性能な読み書きを維持しつつ、エラスティックスケーリングや階層化ストレージといったエンタープライズレベルの機能を追加し、企業ユーザーのコストとメンテナンス負荷の削減を支援します。同時に、ストレージ分野における長年の技術蓄積を活かし、商用ストレージ製品に支えられた永続ストレージも提供できます。
上記のアーキテクチャ図は、Pravega の代表的な読み書きのシナリオを示し、Pravega の主要な用語を紹介することで、システムアーキテクチャの理解を深めることができます。
中央部分は Pravega クラスターで、ストリームを一つの抽象システムとして捉えています。ストリームは Kafka のトピックに相当する概念とみなせます。同様に、Pravega のセグメントは Kafka のパーティションに相当するデータパーティショニングの概念であり、動的スケーリングも提供します。
セグメントにはバイナリデータフローが格納され、データフローのサイズに応じてマージや分割の操作が行われ、リソースの解放や集約が行われます。その際、セグメントはシール処理を実行して新規データの書き込みを防止し、新たに作成されたセグメントが新規データを受け取ります。
図の左側はデータ書き込みのシナリオで、追加のみの書き込みをサポートしています。ユーザーは各イベントにルーティングキーを指定してセグメントの所属を決定できます。これは Kafka の Partitioner に相当します。単一のルーティングキー上のデータは順序が保持され、読み取り時の順序が書き込み時と同一であることが保証されます。
図の右側はデータ読み取りのシナリオで、複数のリーダーがリーダーグループによって制御されています。リーダーグループはリーダー間の負荷分散を制御し、すべてのセグメントがリーダーに均等に分配されるようにします。同時に、チェックポイント機構により整合性のあるストリーム分割を形成し、データの障害復旧を保証します。「読み取り」については、バッチとストリームの両方のセマンティクスをサポートしています。ストリームシナリオではテール読み取りをサポートし、バッチシナリオでは高い同時実行性を考慮して高スループットを実現します。
2. Pravega Flink コネクタのこれまで
Pravega Flink コネクタは、Pravega が最初にサポートしたコネクタです。これは Pravega と Flink の設計思想が非常に一致しているためでもあります。両者ともバッチとストリームを統合したフローベースのシステムであり、ストレージとコンピューティングの完全なソリューションを形成できます。
1. Pravega の開発の歴史
コネクタは 2017 年から独立した GitHub プロジェクトとして運営されています。2017 年には Flink バージョン 1.3 をベースに開発を行い、Stephan Ewen を含む Flink PMC メンバーが参加して、最も基本的な Source/Sink 関数を構築しました。これにより基本的な読み書きと、後述する Pravega チェックポイントの統合がサポートされました。
2018 年の最も重要な成果の一つは、エンドツーエンドでの exactly-once セマンティクスのサポートです。当時、チームは Flink コミュニティと多くの議論を重ねました。Pravega が最初にトランザクション対応の書き込みクライアント機能を実装し、コミュニティ側もこれに協力しました。Sink 関数をベースに 2 相コミットのセマンティクスを実装し、チェックポイントベースの分散トランザクション機能を実現しました。その後、Flink は 2 相コミット API をさらに抽象化し、よく知られた TwoPhaseCommitSinkFunction インターフェイスを確立しました。このインターフェイスは Kafka コネクタにも採用されています。コミュニティではこのインターフェイスと exactly-once セマンティクスについて詳しく解説するブログ記事も公開されています。
2019 年には、バッチ読み取りや Table API のサポートなど、他の API を補完するコネクタが開発されました。
2020 年の主な注力は Flink 1.11 の統合で、FLIP-27 と FLIP-95 の新機能統合に重点が置かれました。
2. チェックポイント統合の実装
Kafka を例にとって、まず Kafka が Flink のチェックポイントをどのように統合しているかを見ていきましょう。
上の図は Kafka の代表的な読み取りアーキテクチャを示しています。Chandy-Lamport アルゴリズムに基づく Flink のチェックポイント実装では、Job Master がチェックポイントをトリガーすると、Task Executor に RPC リクエストを送信します。Task Executor はそれを受信後、自身の状態ストレージに保持している Kafka のコミットオフセットを Job Manager に返して、チェックポイントメタデータを形成します。
詳しく検討すると、いくつかの問題が見つかります。
スケーリングと動的バランスのサポートです。パーティションが調整された場合、あるいは Pravega においてパーティションが動的に拡張・縮小された場合に、マージの整合性をどのように保証するかという課題があります。
もう一つは、Task がオフセット情報を保持する必要があるため、設計全体が Kafka の内部抽象オフセットに結合してしまうという点です。
これらの課題を踏まえ、Pravega は独自に設計されたチェックポイント機構を備えています。Flink のチェックポイントとどのように統合されているかを見ていきましょう。
同じく Pravega ストリームを読み取ります。チェックポイントの開始時点で違いがあります。ここでは、Job Master は Task Executor に RPC リクエストを送るのではなく、ExternallyInducedSource インターフェイスを使って Pravega にチェックポイントリクエストを送信します。
同時に、Pravega は内部の StateSynchronizer コンポーネントを使用してすべてのリーダーを同期・協調させ、リーダー間でチェックポイントイベントを送信します。Task Executor がチェックポイントイベントを読み取ると、Pravega 全体でチェックポイントの完了がマークされ、返された Pravega チェックポイントは Job Master の状態に保存されてチェックポイントが完了します。
この実装方式は Flink にとってよりクリーンです。外部システムの実装詳細に結合せず、チェックポイント処理全体を Pravega に委譲して実装・完了させることができるからです。
3. Flink 1.11 の上位レベル機能に関する体験共有
Flink 1.11 は 2020 年の重要なリリースです。コネクタにとっては多くの課題があり、主に FLIP-27 と FLIP-95 の 2 つの FLIP の実装に集中しました。チームはこれらの新機能を統合するために多くの時間を費やし、その過程でいくつかの問題や課題に直面しました。ここでは、どのように問題を発見し解決したかを共有します。本記事では FLIP-95 を例に取り上げます。
1. FLIP-95 の統合
FLIP-95 は新しい Table API です。その動機は FLIP-27 と同様で、バッチとストリームの統合インターフェイスを実現し、同時に CDC との統合をより良くサポートすることを目的としています。冗長な設定キーの問題については、対応する FLIP-122 も提案され、設定キーの簡素化が図られています。
1.1 Pravega の旧 Table API
上の図から、Flink 1.10 以前の Pravega の Table API がわかります。図中のテーブル作成 DDL から以下の点が読み取れます。
update mode と append でバッチとストリームを区別しており、バッチとストリームデータの区別が直感的ではありません。
設定ファイルも非常に長く複雑で、読み取りストリームは connector.reader.stream-info.0 のような非常に長い設定キーを通じて設定する必要があります。
コードレベルでも DataStream API との密な結合が多く、保守が困難です。
これらの問題に対応するため、新しい API セットを実装する大きな動機が生まれ、ユーザーがテーブル抽象をより良く活用できるようになりました。全体のフレームワークを図に示します。新しいフレームワークにより、すべての設定項目は ConfigOption インターフェイスを通じて定義され、PravegaOptions クラスで一元管理されています。
1.2 Pravega の新 Table API
下の図は最新の Table API によるテーブル作成の実装で、以前と比べて大幅に簡素化されています。同時に、エンタープライズレベルのセキュリティオプションの設定、複数のストリームの指定、初期ストリームカットの設定など、機能面でも多くの最適化が施されています。
2. Flink-18641 の解決過程の体験共有
次に、Flink 1.11 の統合に関する経験をもう少し共有します。ある問題の解決過程についての話です。Flink-18641 はバージョン 1.11.0 の統合時に遭遇した問題で、アップグレード過程で単体テストにおいて CheckpointException が報告されました。以下は完全なデバッグ過程です。
まず、自らステップバイステップでブレークポイントデバッグを行いました。エラーログを確認し、関連する Pravega および Flink のソースコードを分析することで、Flink の CheckpointCoordinator に関連する問題であることを特定しました。
次に、コミュニティのコミット履歴を確認したところ、Flink 1.10 以降で CheckpointCoordinator のスレッドモデルが元のロック制御モデルから Mailbox モデルに変更されていたことがわかりました。このモデル変更により、以前は同期的に直列実行されていたロジックが誤って並列実行されるようになり、このエラーが発生していました。
この変更のプルリクエストをさらに詳しく確認し、関連するコミッターにメールで連絡を取りました。最終的に開発メーリングリストで問題を特定し、JIRA チケットを作成しました。
オープンソースコミュニティで活動する仲間の開発者向けに、以下の注意点をまとめました。
メーリングリストと JIRA を検索して、他の人が同様の質問をしていないか確認すること。
問題を完全に記述し、詳細なバージョン情報、エラーログ、再現手順を提供すること。
コミュニティメンバーからフィードバックを得た後、さらなる議論を通じて解決策を検討すること。
非中国語環境では英語が必須であること。
実際、中国の開発者であっても、メーリングリストや JIRA に加え、DingTalk グループやビデオ通話を通じて多くのコミッターと連絡を取ることができます。重要なのはコミュニケーションのプロセスです。オープンソースに取り組むとは、コミュニティと積極的に対話することで、プロジェクトの共同発展を促進できます。
4. 今後の展望
今後の大きな取り組みの一つは、Pravega スキーマレジストリの統合です。Pravega スキーマレジストリは、データスキーマとシリアル化方式を含む Pravega ストリームのメタデータを管理・保存する機能を提供します。この機能は Pravega 0.8 リリース、つまりプロジェクト初のオープンソースリリースに付属しました。今後のバージョン 0.10 では、このプロジェクトをベースに Pravega の Catalog を実装し、Flink の Table API の利用をさらに容易にする予定です。
また、Flink コミュニティの新しい動向にも注目し、コミュニティの新バージョンや新機能の積極的な統合を進めています。現在の計画には FLIP-143 と FLIP-129 が含まれています。
コミュニティでは、Docker コンテナベースの新しいテストフレームワークへの移行も徐々に進んでおり、この動向にも注目し、統合を進めています。
最後に、コミュニティの皆様には Pravega プロジェクトによりご注目いただき、Pravega コネクタと Flink の共同発展を推進していただければ幸いです。
Related Articles
-
A detailed explanation of Hadoop core architecture HDFS
Knowledge Base Team
-
What Does IOT Mean
Knowledge Base Team
-
6 Optional Technologies for Data Storage
Knowledge Base Team
-
What Is Blockchain Technology
Knowledge Base Team
Explore More Special Offers
-
Short Message Service(SMS) & Mail Service
50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00
