YouzanFlinkリアルタイムタスクリソース最適化の調査と実践

FlinkのK8sizationの完了とリアルタイムクラスター移行の完了により、K8sクラスターで実行されるFlinkリアルタイムタスクがますます増えています。FlinkK8sizationは、主要なプロモーション中にリアルタイムクラスターが柔軟に拡張および縮小する機能を向上させます。主要なプロモーションをより適切に削減します。期間中のマシンの拡張と縮小のコスト。同時に、K8sには社内のメンテナンス専用チームがあるため、FlinkK8sizationは会社の運用およびメンテナンスコストをさらに削減できます。

ただし、現在のFlink K8sタスクリソースは、リアルタイムプラットフォーム上でユーザーが構成します。ユーザー自身は、リアルタイムタスク用に構成されているリソースの量についての経験が少ないため、ユーザーリソースがより多く構成されている状況があります。ただし、実際には使用できません。たとえば、Flinkタスクは、実際には4つの並行タスクによってビジネス処理のニーズを満たすことができます。その結果、ユーザーは16の並行タスクを構成します。この状況では、リアルタイムコンピューティングリソースの浪費につながり、一定の影響があります。リアルタイムクラスターリソースレベルと基盤となるマシンのコスト。この背景に基づいて、この記事では、Flinkタスクのメモリとメッセージ機能の処理の観点から、Flinkタスクのリソースの最適化について説明します。

1.Flinkコンピューティングのリソースタイプと最適化のアイデア

1.1Flinkコンピューティングリソースタイプ

Flinkタスクを実行するために必要なリソースは、次の5つのカテゴリに分類できると思います。

  1. メモリリソース
  2. ローカルディスク(またはクラウドディスク)ストレージ
  3. 依存する外部ストレージリソース。HDFS、S3など(タスクステータス/データ)、HBase、MySQL、Redisなど(データ)
  4. CPUリソース
  5. ネットワークカードリソース

現在、メモリとCPUリソースがFlinkタスクに最も使用されています。ローカルディスク、依存外部ストレージリソース、およびネットワークカードリソースは一般にボトルネックではないため、この記事では、メモリとCPUの2つの側面からFlinkについて説明します。 Flinkタスクのリソース。リアルタイムのタスクリソースが最適化されます。

1.2Flinkリアルタイムタスクリソース最適化のアイデア

Flinkのリアルタイムタスクリソース分析のアイデアについては、2つの主要なポイントがあると考えています。

  • 1つは、タスクメモリとヒープメモリの観点からリアルタイムタスクを分析することです。
  • 一方、それはリアルタイムのタスクメッセージ処理機能から始まり、ビジネス側のデータ処理要件を満たしながら、CPUリソースが可能な限り合理的に使用されることを保証します。

次に、リアルタイムタスクメモリ分析から得られた関連指標とリアルタイムタスク同時実行の合理性を組み合わせて、リアルタイムタスクリソースのプリセット値が取得されます。ビジネス側との完全な通信の後、リアルタイムタスクリソースは次のようになります。リアルタイムのタスクリソース割り当ての合理化を最終的に達成するように調整されました。目的、マシンの使用コストをより適切に削減するため。

1.2.1タスクメモリの観点

では、Flinkタスクのヒープメモリを分析する方法は?ここでは、分析のためにFlinkタスクのGCログを組み合わせます。GCログには、毎回GCヒープのさまざまな領域のメモリの変更と使用状況が含まれます。同時に、GCログによると、各フルGCの後にタスクマネージャーの残りのスペースを取得することもできます。リアルタイムタスクのGCログを取得することは、リアルタイムタスクメモリ分析の前提条件であると言えます。

GCログコンテンツ分析では、ここではオープンソースのGCビューアーツールを使用して特定の分析を実行します。各分析の後、GC関連のインジケーターを取得できます。以下は、GCビューアーを使用してGCログを分析した結果の一部です。

上記のGCログによる単一のFlinkタスクマネージャーの合計ヒープサイズ、若い世代、古い世代によって割り当てられたメモリスペース、フルGC後の古い世代の残りのサイズなどの分析はもちろんあります。他の多くのインジケーター、関連するインジケーターの定義はGithubで表示できます。

ここで最も重要なことは、フルGC後の老後の残りのサイズです。「Javaパフォーマンス最適化の決定的なガイド」の本のJavaヒープサイズ計算ルールに従って、フルGC後の老後の残りのサイズをに設定します。 Mの場合、正しいサイズをお勧めします。3〜4倍M、新世代は1〜1.5倍M、旧世代は2〜3倍Mです。もちろん、実際のメモリ構成では、対応するサイズを増やすことができます。交通量の急増を防ぐために、実際の状況に応じた比率。

したがって、FlinkタスクのGCログから、リアルタイムタスクの推奨ヒープメモリサイズの合計を計算できます。推奨ヒープメモリと実際のリアルタイムタスクのヒープメモリが大きすぎることがわかった場合は、ビジネス側のリアルタイムタスクを減らすことができます。メモリ構成により、マシンのメモリリソースの使用を減らすことができます。

1.2.2タスクメッセージ処理機能の観点

Flinkタスクのメッセージ処理能力の分析では、主に、リアルタイムタスクによって消費されるデータソースの入力単位時間と、それがリアルタイムタスクの各オペレーター/タスクのメッセージ処理能力と一致するかどうかを調べます。オペレーターはFlinkタスクのオペレーターであり、タスクは1つ以上のオペレーターがチェーンされた後に一緒に実行される物理キャリアです。

通常、Kafkaを内部で使用するデータソース。Kafkaトピックの単位時間入力は、Kafka Broker JMXインジケーターインターフェイスを呼び出すことで取得できます。もちろん、Flink Rest Monitoring関連のAPIを呼び出して、リアルタイムタスクを取得することもできます。すべてのKafkaソースタスク単位時間の入力が追加されます。ただし、バックプレッシャがソース側の入力に影響を与える可能性があるため、ここでは、Kafka BrokerインジケーターJMXインターフェースを直接使用して、Kafkaトピックの単位時間入力を取得します。

リアルタイムタスクのKafkaトピックの単位時間入力を取得した後、リアルタイムタスクのメッセージ処理機能がデータソース入力と一致するかどうかを判断するのは次のとおりです。リアルタイムタスクの全体的なメッセージ処理機能は、最も遅いオペレーター/タスクの影響を受けます。たとえば、Flinkタスクによって消費されるKafkaトピックの入力は20000 Record / Sですが、同時実行数が10のMapオペレーターがあります。MapオペレーターのビジネスパーティはDubboを呼び出し、Dubboインターフェイスは要求から10ミリ秒です。に戻ると、Map演算子の処理能力は1000 Record / S(1000 ms / 10 ms * 10)になるため、リアルタイムタスクの処理能力は1000 Record / Sに減少します。

メッセージレコードの処理はタスク内で流れるため、リアルタイムタスクで最も遅いタスクロジックを見つけようとしています。ソースエンドからシンクエンドまでのすべてのチェーンが確立されている場合、最も遅いオペレーターのロジックが見つかります。ソースコードレベルで、Flink Task and Operatorの単一レコードの処理時間のカスタムメトリックを追加しました。これは、Flink RestAPIを介して取得できます。Flinkタスク内のすべてのタスクをトラバースし、最も遅いタスクが処理されるJobVertex(JobGraphのポイント)にクエリを実行してから、JobVertexのすべてのタスクの合計出力を取得し、最後にKafkaトピックの単位時間と比較します。入力し、リアルタイムタスクメッセージ処理機能が妥当かどうかを判断します。

リアルタイムタスクKafkaトピックの単位時間あたりの入力がS、最も遅いタスクで表されるJobVertexの同時実行性がP、最も遅いタスクのJobVertexの単位時間あたりの出力がO、最大メッセージ処理時間であると仮定します。最も遅いタスクのが処理されます。Tである場合は、次のロジックで分析します。

  1. OがSにほぼ等しく、1秒/ T * PがSよりもはるかに大きい場合、タスクの同時実行性は低下します。
  2. OがSにほぼ等しく、1秒/ T * PがSにほぼ等しい場合、タスクの同時実行性は調整されません。
  3. OがSよりもはるかに小さく、1秒/ T * PがSよりもはるかに小さい場合、タスクの同時実行性が向上します。

現在は主に1です。この状況はCPU使用率の観点からは不合理です。もちろん、期間が異なるため、リアルタイムタスクのフローが異なるため、定期的な検出タスクがあります。 -時間タスクが連続して複数回検出されるこの状況が満たされると、リソースを最適化および調整するために、プラットフォーム管理者にアラームが自動的に通知されます。
次の図は、Flinkタスクメモリとメッセージ処理機能の2つの観点からのリソースロジックの分析です。

2.メモリの観点からのFlinkの分析と実践

2.1Flinkタスクのガベージコレクターの選択

Flinkタスクは本質的にJavaタスクであるため、ガベージコレクターの選択も含まれます。ガベージコレクターを選択するには、通常、次の2つの観点から参照する必要があります。

  1. スループット、つまり、単位時間あたりのタスク実行時間/(タスク実行時間+ガベージコレクション時間)は、もちろん、GC一時停止時間を短縮するとスループットが向上するため、GC一時停止時間を短縮してもスループットが向上するわけではありません。 GC周波数。
  2. ディレイ。Javaプログラムに外部との対話が含まれる場合、遅延は外部要求の使用エクスペリエンスに影響します。

Flinkタスクは依然としてスループットに焦点を当てたJavaタスクの一種であると思うので、スループットの観点からさらに検討する必要があります。もちろん、遅延がまったく考慮されていないという意味ではありません。結局のところ、JobManager、TaskManager、およびResourceManagerの間にハートビートがあります。遅延が大きすぎると、ハートビートがタイムアウトする可能性があります。

現在、JDKバージョンは内部JDK1.8です。新世代のガベージコレクターはParallelScavengeを使用するため、旧世代のガベージコレクターはSerialOldまたはParallelOldからのみ選択できます。Flink k8sタスクの各ポッドのCPU制限は0.6〜1コアであり、最大で使用できるのは1コアのみであるため、古い時代のガベージコレクターとしてSerial Oldを使用し、マルチスレッドのガベージコレクションはシングルコア間で行われます。 。スレッドスイッチングの消費があるかもしれません。

2.2リアルタイムタスクGCログの取得

ガベージコレクターを設定したら、次のステップはFlinkタスクのGCログを取得することです。Flinkタスク構成は、通常、単一のJobManager +複数のTaskManagerです。ここでは、分析のためにTaskManagerのGCログを取得する必要があります。すべてのTaskManagerを取得する必要がありますか?ここでは、TaskManagerのYoung GCの数に従って並べ替え、上位16のTaskManagerを分析に使用します。YoungGC時間は、Flink RestAPIを介して取得できます。

Flink on YarnリアルタイムタスクのGCログは、TaskManagerのログリンクをクリックして直接表示し、HTTP経由でアクセスして、ローカルにダウンロードできます。Flink On k8sタスクのGCログは、最初にポッドによってマウントされ、k8sホストパスボリュームに基づいてマウントされたクラウドディスクに書き込まれます。内部でFilebeatを使用してログファイルの変更を監視および収集し、最終的にダウンストリームのKafkaトピックに出力します。内部にカスタムログサーバーがあり、Kafkaのログレコードを使用し、ディスクの配置と管理を自動的に実行し、外部へのログダウンロードインターフェイスを提供します。ログダウンロードインターフェイスを介して、分析が必要なTaskManagerのGCログをダウンロードできます。

2.3 GCViewerに基づいてFlinkタスクメモリを分析する

GC Viewerは、オープンソースのGCログ分析ツールです。GC Viewerを使用する前に、GC Viewerプロジェクトコードをローカルで複製し、その機能を使用するためにコンパイルおよびパッケージ化する必要があります。

リアルタイムのタスクヒープメモリを分析する場合は、最初にFlink TaskManagerログをローカルにダウンロードしてから、GCビューアを使用してログを分析します。複数のタスクマネージャーGCログ分析が遅いと思われる場合は、マルチスレッドを使用できます。上記のすべての操作は、分析結果を自動的に生成するようにコーディングできます。以下は、GCViewerによって分析されたコマンドラインです。

java -jar gcviewer-1.37-SNAPSHOT.jar gc.log summary.csv

上記のパラメーターgc.logは、タスクマネージャーのGCログファイルの名前を表し、summary.csvはログ分析の結果を表します。以下は、リアルタイムタスクに対するプラットフォームのメモリ分析の結果です。

以下は、上のスクリーンショットのいくつかのパラメーターの説明です。

  1. RunHours、Flinkタスクの実行時間
  2. YGSize、タスクマネージャーに割り当てられた新世代ヒープメモリの最大量(メガバイト単位)
  3. YGUsePC、TaskManager新世代ヒープの最大使用率
  4. OGSize、古い時代にTaskManagerに割り当てられたヒープメモリの最大量(メガバイト単位)
  5. OGUsePC、タスクマネージャーの旧世代ヒープの最大使用率
  6. YGCoun、TaskMnager YoungGC回
  7. YGPerTime、TaskMnager Young GCの一時停止時間(秒単位)
  8. TaskMnagerの完全なGCカウントであるFGCount
  9. FGAllTime、TaskMnagerフルGCの合計時間(秒単位)
  10. 全体を通して、タスクマネージャーのスループット
  11. AVG PT(分析結果avgPromotionパラメーター)、YoungGCが旧世代に昇格するたびのオブジェクトの平均サイズ
  12. Rec Heap、推奨されるヒープサイズ
  13. RecNewHeap、推奨される新世代のヒープサイズ
  14. RecOldHeap、推奨される古いヒープサイズ

上記のメモリ分析結果のほとんどはGCViewer分析を通じて取得できますが、推奨されるヒープサイズ、推奨される若い世代のヒープサイズ、および推奨される古い世代のヒープサイズは、セクション1.2.1のメモリ最適化ルールに従って設定されます。

3.メッセージ処理の観点からのFlinkの分析と実践

3.1単位時間あたりのリアルタイムタスクKafkaトピック入力取得

Flinkタスクのメッセージ処理機能を分析するための最初のステップは、リアルタイムタスクのKafkaデータソーストピックを取得することです。現在、データソースがKafkaでない場合、分析は実行されません。Flinkタスクは、一般にFlinkJarタスクとFlinkSQLタスクの2つのカテゴリに分類されます。Flink SQLタスクは、Kafkaデータソースを取得するのが比較的簡単です。FlinkSQLコードを直接解析し、Withの背後にあるパラメーターを取得して、Sinkテーブルをフィルターで除外します。SQLCreateTableのコネクタタイプがKafkaの場合、次のようになります。特定のKafkaトピックを使用したSQLCreateTableの後のパラメーターを介して取得されます。

FlinkJarタスクのKafkaTopicデータソースは比較的面倒です。内部にリアルタイムタスク血液分析サービスがあります。PackagedProgramはFlinkJarタスク用に自動的に構築されます。PackagedProgramはFlink内のクラスです。次にPackagedProgramを使用します。 、Flinkを取得できます。JarタスクのStreamGraphには、StreamGraphにSourceとSinkのすべてのStreamNodeがあります。リフレクションを通じて、StreamNodeに特定のSource関数を取得できます。KafkaSourceSunctionの場合は、そのKafkaトピックを取得します。以下は、StreamGraphクラスのスクリーンショットです。

FlinkタスクのKafkaTopicデータソースを取得した後、次のステップは、トピックの単位時間あたりに入力されたメッセージレコードの数を取得することです。これは、Kafka Broker JMX Metricインターフェースを介して取得でき、外部から取得されます。内部Kafka管理プラットフォームによって提供されるインターフェース。

3.2Flinkメッセージ処理の最も遅いタスクを自動的に検出する

まず、ソースコードレイヤーにFlink Taskの単一レコードの処理時間のメトリックを追加しました。このメトリックは、Flink RestAPIを介して取得できます。次のステップは、Flink Rest APIを使用して、分析するFlinkタスクのすべてのタスクをトラバースすることです。Flink RestApiには次のようなインターフェイスがあります。

base_flink_web_ui_url/jobs/:jobid

このインターフェイスは、タスクのすべての頂点を取得できます。頂点は、FlinkタスクJobGraphのJobVertexとして簡単に理解できます。JobVertexは、リアルタイムタスクの実行ロジックの一部を表します。

Flinkタスクのすべての頂点を取得したら、次のステップは、単一のレコードを処理するための各頂点固有のタスクのメトリックを取得することです。次のインターフェイスを使用できます。

上記のRestAPIリンクメトリックの後に?get =(特定のメトリック)を追加する必要があります。たとえば、metrics?get = 0.Filter.numRecordsOut、0は頂点タスクのIDを意味し、Filter.numRecordsOutは特定のメトリック名。内部的にtaskOneRecordDealTimeを使用して単一レコードのタスク処理時間メトリックを表し、次に0.taskOneRecordDealTimeを使用してタスクの単一レコード処理時間インジケーターを取得します。上記のインターフェースは、複数のインデックスクエリをサポートしています。つまり、取得後にコンマを使用して区切ります。

Flinkメッセージ処理の最も遅いタスクの最終的な自動検出全体的な手順は次のとおりです。

  1. リアルタイムタスクのすべての頂点を取得する
  2. 各頂点をトラバースしてから、この頂点のすべての同時タスクのtaskOneRecordDealTimeを取得し、最大値を記録します
  3. すべての頂点単一レコード処理メトリックの最大値が比較され、処理時間が最も遅い頂点が検出されます。

以下は、Flinkリアルタイムタスクのリアルタイムプラットフォーム分析の結果です。

第四に、YouzanFlinkリアルタイムタスクリソース最適化の実践

Flinkタスクのメモリおよびメッセージ処理機能を分析する方法ができたので、次のステップは、リアルタイムプラットフォームに特定のプラクティスを実装することです。当社のリアルタイムプラットフォームは、実行中のすべてのFlinkタスクを毎日定期的にスキャンします。タスクメモリに関しては、リアルタイムタスクGCログを組み合わせて、メモリ最適化ルールに従ってFlinkタスクの推奨ヒープメモリサイズを計算し、それらを実際に割り当てられたFlinkタスク。2つのヒープメモリの差が大きすぎる場合、Flinkタスクのメモリ構成が無駄になっていると考えられ、プラットフォーム管理者に最適化するように警告します。

アラームプロンプトを受信した後、プラットフォーム管理者は、リアルタイムタスクメッセージ機能が妥当かどうかも判断します。メッセージ処理が最も遅いVertex(リアルタイムロジックの特定の部分)である場合、メッセージレコード数の合計単位時間あたりにすべてのタスクによって処理されるのは、リアルタイムタスクとほぼ同じです。単位時間あたりに消費されるKafkaトピックの入力ですが、Vertexと単一のメッセージ処理メトリックの同時実行により、によって処理されるメッセージレコードの数が計算されます。単位時間あたりの頂点は、Kafkaトピックの単位入力よりもはるかに大きいため、Flinkタスクは同時実行度を適切に減らすことができると考えられます。具体的な調整は、事業者側との連絡後に調整されます。Flinkタスクのリソース最適化操作プロセス全体は次のとおりです。

五数要約

現在、Youzanリアルタイムコンピューティングプラットフォームは、Flinkタスクリソース最適化の調査の第一歩を踏み出しました。最適化できるリアルタイムタスクは自動化によって発見され、プラットフォーム管理者が分析に介入して、Flinkタスクのリソースを調整できるかどうかを最終的に判断します。リアルタイムのタスクリソース最適化のリンク全体では、後半も人的要因が必要であるため、現時点では自動化だけでは不十分です。将来的には、Flinkタスクリソースの最適化を完全に自動化する予定です。リアルタイムタスク履歴のさまざまな期間でのリソース使用量を組み合わせて、リアルタイムタスクのリソース構成を自動的に推測および調整して、目的を達成します。リアルタイムクラスター全体のリソース使用率を改善します。

同時に、将来的には、メタデータプラットフォームで学生と協力して、リアルタイムタスクでのリソース最適化の可能性をより多くの側面から分析します。彼らは元のオフラインタスクリソースで多くの最適化の経験を蓄積しており、また、将来的に参照して学習することもできます。リアルタイムのタスクリソースの最適化に適用されます。

もちろん、最も理想的なのは、リアルタイムタスクのリソース使用量が自動的かつ柔軟にそれ自体で拡大および縮小できることです。この点についてコミュニティの学生から聞いたことがあるので、私と話し合うこともできます。

著者+シェンレイ

元のリンク

この記事はAlibabaCloudのオリジナルのコンテンツであり、許可なく複製することはできません。

おすすめ

転載: blog.csdn.net/weixin_43970890/article/details/114063765