2016年以降、MeituanDadianケータリング技術チームはOLAPエンジンとしてApacheKylinの使用を開始しましたが、ビジネスの急速な発展に伴い、構築レベルとクエリレベルで効率の問題が発生しています。そのため、技術チームは原則の解釈から始め、次にプロセスをレイヤーごとに解体し、ポイントツーフェイスの実装ルートを作成しました。この記事では、業界のより多くの技術チームがデータ出力の効率を向上させるのに役立つことを期待して、いくつかの経験と経験を要約しています。
バックグラウンド
販売事業は、大規模で複数の分野があり、需要が密集していることが特徴です。美団から店舗へのケータリングDynaSky販売システム(以下「青田」という)は、販売データサポートの主要なキャリアとして、幅広い範囲をカバーするだけでなく、非常に複雑な技術シナリオ(複数組織レベルのデータ表示)にも直面しています。および認証では、インジケーターの3分の1以上を正確に重複排除する必要があり、ピーククエリは数万レベルに達しました)。このようなビジネスの背景の下で、アナリストが迅速な意思決定を行うのを支援するための安定した効率的なOLAPエンジンを構築することが、Dangqingtianの中心的な目標になっています。
Apache Kylinは、Hadoopビッグデータプラットフォームに基づくオープンソースのOLAPエンジンであり、多次元キューブ事前計算テクノロジーを使用し、時間のスペースを使用してクエリ速度を1秒未満のレベルに上げ、データ分析の効率を大幅に向上させます。 。便利で柔軟なクエリ機能をもたらします。技術とビジネスの一致度に基づいて、Kinteは2016年にOLAPエンジンとしてKylinを採用しました。その後、このシステムはデータ分析システムを効果的にサポートしました。
2020年、Meituanのレストラン事業は急速に発展し、そのデータ指標も急速に増加しました。Kylinをベースにしたこのシステムは、構築とクエリの両方で深刻な効率の問題を抱えており、データの分析と意思決定に影響を与え、ユーザーエクスペリエンスの最適化に大きな障害をもたらします。約半年後、技術チームは、寸法調整、モデル設計、リソース適応などを含む一連の最適化の反復をKylinで実行し、販売パフォーマンスデータのSLAを90%から99.99%に向上させました。この実際の戦闘に基づいて、「原理の解釈」、「プロセスの分解」、「実装ルート」をカバーする一連の技術ソリューションを寄託しました。これらの経験と要約が、業界のより多くの技術チームがデータ出力とビジネスの意思決定の効率を改善するのに役立つことが期待されています。
問題と目標
プラットフォームとマーチャントをつなぐ架け橋としての販売には、店舗への販売と電話による訪問という2つのビジネスモデルが含まれます。これは、戦争ゾーンと人間の組織構造によってレベルごとに管理されます。すべての分析は、2つの組織レベルで表示する必要があります。 。一貫性のある指標とタイムリーなデータ出力の要件の下で、Kylinの事前計算のアイデアを組み合わせてデータアーキテクチャを設計しました。以下に示すように:
次元の組み合わせを計算するためのKylinの式は、2 ^ N(Nは次元の数)です。次元の組み合わせの数を減らすために、次元の剪定の公式な方法が提供されています。ただし、ケータリングビジネスの特殊性により、シングルタスクのカット不可能な組み合わせの数は依然として1000以上に上ります。需要の反復と人員および劇場組織の変化のコンテキストでは、すべての履歴データに戻る必要があります。これは、多くのリソースと超高額の建設時間を消費します。事業部門に基づくアーキテクチャ設計は、データ出力の分離とインジケーターキャリバーの一貫性を大幅に確保できますが、Kylinの構築に大きなプレッシャーをかけ、その結果、多くのリソースを占有し、長い時間を要します。 。上記のビジネス状況に基づいて、KylinのMOLAPモードに存在する問題を次のように要約しました。
-
効率の問題を解決するのが難しい(実装原理):構築プロセスには多くのステップがあり、ステップは強く関連しています。問題の外観だけでは問題の根本原因を特定することは困難であり、効果的に解決することはできません。 。
-
構築エンジンは繰り返されません(構築プロセス):MapReduceは、履歴タスクの構築エンジンとして引き続き使用され、構築がより効率的なSparkへの切り替えはありません。
-
不当なリソース使用率(構築プロセス):リソースの浪費、リソースの待機、およびデフォルトのプラットフォームの動的リソース適応方法。これにより、小さなタスクが大量のリソースに適用され、不当なデータのセグメンテーション、および多数の小さなファイルが発生します。リソースの浪費と多数のタスク待機。
-
コアタスクに時間がかかる(実装ルート):DynaSkyの販売トランザクションパフォーマンスデータインジケーターのソーステーブルには、大量のデータ、多数のディメンションの組み合わせ、および高い拡張率が含まれているため、1日あたりの構築時間が長くなります。 2時間以上。
-
SLAの品質が標準に達していない(実装ルート):SLAの全体的な達成率が期待された目標に達していません。
問題を注意深く分析し、効率向上の大きな目標を決定した後、Kylinの建設プロセスを分類し、建設プロセスの効率を向上させることができるコアリンクを分解しました。「原理解釈」と「解体の層」を通じて、「ポイントから表面」とは、双方向の削減という目標を達成することを意味します。具体的な定量目標を下図に示します。
最適化の前提-原則の解釈
効率向上のための難しい位置決めと帰属の問題を解決するために、事前計算のアイデアとレイヤーごとのアルゴリズムを含む、Kylinの構築原理を解釈しました。
事前計算
ディメンションに従ってすべての可能なディメンションを組み合わせ、多次元分析で使用できるインジケーターを事前に計算し、計算結果をキューブとして保存します。4つのディメンションがあるとします。このキューブ(直方体と呼ばれる)の各ノードは、これら4つのディメンションの異なる組み合わせです。各組み合わせは、分析用のディメンションのセット(グループ化など)を定義し、インジケーターの集計結果はに保存されます。各直方体。クエリを実行すると、SQLに従って対応する直方体が見つかり、インジケーターの値を読み取ってから戻ります。以下に示すように:
レイヤー別アルゴリズム
N次元キューブは、1つのN次元サブキューブ、N(N-1)次元サブキューブ、N *(N-1)/ 2(N-2)次元サブキューブ、... N 1サブキューブは0次元のサブキューブで構成され、合計2 ^ N個のサブキューブがあります。レイヤーバイレイヤーアルゴリズムでは、次元数がレイヤーごとに削減されます。各レイヤーの計算(元のデータから集計された最初のレイヤーを除く)は、前のレイヤーの計算結果に基づいて計算されます。 。
例:group by [A、B]の結果は、group by [A、B、C]の結果に基づくことができます。これは、Cを削除することで集計でき、繰り返しの計算を減らすことができます。0次元の直方体の場合が計算され、キューブ全体の計算が完了します。以下に示すように:
プロセス分析-レイヤーごとの解体
Kylinの基本原理を理解した後、「エンジン選択」、「データ読み取り」、「辞書構築」、「階層化構築」、「ファイル変換」の5つのリンクで最適化の方向性を固定し、その後、それぞれを改良しました。ステージの問題、アイデア、目標を達成し、コンピューティングリソースを削減しながら、最終的に時間消費の削減を達成しました。詳細を以下の表に示します。
エンジンの選択を構築する
現在、ビルドエンジンを徐々にSparkに切り替えています。Kinteは、早くも2016年にKylinをOLAPエンジンとして使用しています。履歴タスクは切り替えられておらず、MapReduce用に最適化されているのはパラメーターのみです。実際、2017年にKylinの公式ウェブサイトはSparkをビルドエンジンとして有効にし(公式ウェブサイトはSparkビルドエンジンを有効にします)、構築効率はMapReduceの1〜3倍であり、Cubeを介して切り替えることもできます次の図に示すように、設計オプション:
ソースデータの読み取り
Kylinは、Hiveのソースデータを外部テーブルの形式で読み取ります。テーブル内のデータファイル(HDFSに格納されている)は、次のサブタスクの入力として使用されます。このプロセスでは、小さなファイルに問題がある可能性があります。現在、Kylinのアップストリームデータワイドテーブル内のファイル数は比較的合理的であり、アップストリームでマージを設定する必要はありません。強制的にマージすると、アップストリームソーステーブルデータの処理時間が長くなります。
プロジェクト要件の場合、履歴データを更新したり、ディメンションの組み合わせを増やしたりする場合は、すべてのデータを再構築する必要があります。通常、月次構造を使用して履歴を更新します。ロードされたパーティションに小さいファイルが多すぎるため、このプロセスが遅くなります。Kylinレベルで構成ファイルを書き直し、小さなファイルをマージし、マップの数を減らし、読み取り効率を効果的に向上させます。
ソーステーブル内の小さなファイルを組み合わせる:Hiveソーステーブル内の小さなファイルの数を組み合わせて、各ジョブの並列タスク数を制御します。調整パラメーターを次の表に示します。
Kylinレベルのパラメータの書き換え:マップ読み取りプロセスのファイルサイズを設定します。調整パラメーターを次の表に示します。
辞書を作成する
Kylinは、Hiveテーブルに表示されるディメンション値を計算し、ディメンションディクショナリを作成し、ディメンション値をコードにマッピングし、統計を保存および保存してHBaseストレージリソースを保存します。寸法の各組み合わせは、直方体と呼ばれます。理論的には、N次元の立方体には2 ^ N次元の組み合わせがあります。
組み合わせ数量ビュー
ディメンションの組み合わせを削除した後、実際に計算されたディメンションの組み合わせを計算するのは困難です。実行ログから特定のディメンションの組み合わせの数を確認できます(スクリーンショットは、ファクトの一意の列を抽出するステップの最後のリデュースのログです。テーブル)。以下に示すように:
グローバル辞書の依存関係
DynaSkyには、正確な重複排除を必要とする多くのビジネスシナリオがあります。複数のグローバルディクショナリ列がある場合、列の依存関係を設定できます。たとえば、「ストア数」と「オンラインストア数」のデータインジケータが同時にある場合、列の依存関係を設定して、超高ベース寸法の計算を減らすことができます。以下に示すように:
リソース割り当ての計算
インジケーターに複数の正確な重複排除インジケーターがある場合、コンピューティングリソースを適切に増やして、高ベースのディメンション構築の効率を向上させることができます。パラメータ設定を次の表に示します。
層状構造
このプロセスはKylinの構築の中核です。Sparkエンジンを切り替えた後、デフォルトではレイヤーごとのアルゴリズムのみが使用され、自動選択(レイヤーごとのアルゴリズム、高速アルゴリズム)は使用されません。使用されなくなりました。By-layerレイヤーバイレイヤーアルゴリズムを実装するプロセスでは、Sparkは最下部の直方体から最上位の直方体を計算するまでレイヤーごとに計算します(グループ化せずにクエリを実行するのと同じです)。結果データはメモリにキャッシュされます。 、各データ読み取りプロセスをスキップし、上位層のキャッシュされたデータに直接依存するため、実行効率が大幅に向上します。Spark実行プロセスの具体的な内容は次のとおりです。
仕事の段階
ジョブ数はBy-layerアルゴリズムツリーのレイヤー数であり、Sparkは各レイヤーの結果データをジョブとして出力します。以下に示すように:
ステージ
各ジョブは2つのステージステージに対応し、上位レイヤーのキャッシュデータの読み取りと、レイヤーの計算後の結果データのキャッシュに分けられます。以下に示すように:
タスクの並列処理の設定
Kylinは、各レイヤーの直方体の組み合わせデータのサイズを推定します(次元の剪定を使用して、次元の組み合わせの数を減らし、直方体の組み合わせデータのサイズを減らし、構築効率を向上させることができます。この記事では詳しく説明しません)。分割データのパラメータ値タスクの並列処理を計算します。次のように計算されます。
-
タスク数の計算式:Min(MapSize / cut-mb、MaxPartition); Max(MapSize / cut-mb、MinPartition)
-
MapSize:各レイヤーに対して作成された直方体の組み合わせサイズ。つまり、各レイヤーの次元の組み合わせのサイズに関するKylinの推定値。
-
cut-mb:データサイズを分割し、並列タスクタスクの数を制御します。これはkylin.engine.spark.rdd-partition-cut-mbパラメーターで設定できます。
-
MaxPartition:kylin.engine.spark.max-partitionパラメーターで設定できる最大パーティション。
-
MinPartition:最小パーティション。kylin.engine.spark.min-partitionパラメーターで設定できます。
-
-
出力ファイル数の計算:各タスクタスクは、実行の完了後に結果データを圧縮し、ファイル変換プロセスの入力としてHDFSに書き込みます。ファイル数は、タスクタスクの出力ファイル数の要約です。
リソースアプリケーションの計算
プラットフォームはデフォルトでコンピューティングリソースを動的に適用します。単一のExecutorの計算能力には、1つの論理CPU(以下、CPUと呼びます)、6GBのオンヒープメモリ、および1GBのオフヒープメモリが含まれます。次のように計算されます。
-
CPU = kylin.engine.spark-conf.spark.executor.cores *実際に申請されたエグゼキューターの数。
-
メモリ=(kylin.engine.spark-conf.spark.executor.memory + spark.yarn.executor.memoryOverhead)*適用されたエグゼキュータの実際の数。
-
単一のエグゼキュータの実行機能= kylin.engine.spark-conf.spark.executor.memory / kylin.engine.spark-conf.spark.executor.cores、つまり、1つのCPUの実行中に要求されたメモリサイズ。
-
エグゼキュータの最大数= kylin.engine.spark-conf.spark.dynamicAllocation.maxExecutors、プラットフォームのデフォルトは動的アプリケーションであり、このパラメータはアプリケーションの最大数を制限します。
十分なリソースの場合、単一のStage Stage Application 1000並列タスクの場合、10007000GBのメモリとCPUを実現するためにリソースを適用する必要がありますCPU:1*1000=1000;内存:(6+1)*1000=7000GB
。
リソースの合理化と適応
By-layerレイヤーバイレイヤーアルゴリズムの特性と実際の実行プロセスにおけるSparkの圧縮メカニズムにより、実際に実行されたタスクタスクによってロードされるパーティションデータはパラメータ設定値よりもはるかに小さく、結果として超タスクの高度な並列処理、大量のリソースの使用、および多数の小さなファイルの生成は、ダウンストリームのファイル変換プロセスに影響を与えます。したがって、データの合理的なセグメンテーションが最適化の重要なポイントになります。Kylinを介してログを作成することにより、各レベルで結合された直方体データの推定サイズとパーティションの数(ステージステージで実際に生成されたタスクの数に等しい)を表示できます。以下に示すように:
Spark UIと組み合わせると、実際の実行ステータスを表示し、メモリアプリケーションを調整し、実行に必要なリソースを満たすことができるため、リソースの浪費を減らすことができます。
1.リソースアプリケーション全体の最小値は、ステージのTop1レベルとTop2レベルでキャッシュされたデータの合計よりも大きく、すべてのキャッシュされたデータがメモリ内にあることを確認します。以下に示すように:
計算式:ステージステージのTop1レベルとTop2レベルのキャッシュデータの合計<kylin.engine.spark-conf.spark.executor.memory * kylin.engine.spark-conf.spark.memory.fraction * spark。 memory.storageFraction * maxエグゼキュータの数
2. 1つのタスクに必要な実際のメモリとCPU(1つのCPUがタスクの実行に使用される)は、1つのエグゼキュータの実行容量よりも少なくなります。以下に示すように:
計算式:単一のタスクに必要な実際のメモリ<kylin.engine.spark-conf.spark.executor.memory * kylin.engine.spark-conf.spark.memory.fraction * spark.memory.st・orageFraction / kylin。エンジン.spark-conf.spark.executor.cores。パラメータの説明を次の表に示します。
ファイル変換
Kylinは、ビルドされたCuboidファイルをHTable形式のHfileファイルに変換し、BulkLoadを介してファイルをHTableに関連付けます。これにより、HBaseの負荷が大幅に軽減されます。このプロセスはMapReduceタスクによって完了し、マップの数は階層構築フェーズの出力ファイルの数です。ログは次のとおりです。
この段階で、リソースの浪費を回避するために、実際の入力データファイルサイズ(MapReduceログで表示可能)に基づいてコンピューティングリソースを合理的に申請できます。
計算式:マップステージリソースapplication = kylin.job.mr.config.override.mapreduce.map.memory.mb *階層構築ステージの出力ファイルの数。特定のパラメーターを次の表に示します。
実装ルート-ポイントからサーフェスへ
トレーディングパイロットプラクティス
Kylinの原則の解釈と建設プロセスのレイヤーごとの分解を通じて、パイロットプラクティスの販売トランザクションのコアタスクを選択します。以下に示すように:
実際の結果の比較
販売取引のコアタスクの最適化を実践し、リソースの実際の使用量と調整前後の実行時間を比較して、最終的に双方向の削減という目標を達成します。以下に示すように:
アチーブメント表示
リソースの全体的な状況
DynaSkyには現在20以上のKylinタスクがあります。半年の継続的な最適化と反復の後、Kylinリソースキューの月間平均CU使用量および保留中のタスクCU使用量と比較して、リソース消費量は同じタスクで大幅に削減されました。以下に示すように:
SLA全体の達成率
ポイントからサーフェスへの全体的な最適化の後、DynaSkyは2020年6月に100%のSLA達成率に達しました。以下に示すように:
見通し
Apache Kylinは、2015年11月にApacheFoundationのトッププロジェクトに正式になりました。オープンソースからトップレベルのApacheプロジェクトになるまでにたった13か月しかかかりませんでした。また、中国のチームがApacheに完全に貢献した最初のトップレベルプロジェクトでもありました。
現在、Meituanは比較的安定したV2.0バージョンを採用しています。4年近くの使用と蓄積の後、レストランとケータリングの技術チームは、クエリのパフォーマンスと構築効率の最適化において多くの経験を蓄積してきました。この記事では、主にSparkResourceの適応方法。Kylinが2020年7月にV3.1バージョンを正式にリリースし、ビルドエンジンとしてFlinkを導入し、Flinkを統合して、データ読み取りフェーズ、辞書構築フェーズ、階層化構築フェーズなどのコアプロセスを構築したことは注目に値します。ファイル変換フェーズでは、上記の4つの部分が全体の構築時間の95%以上を占めました。このバージョンのアップグレードにより、Kylinの建設効率も大幅に向上しました。詳細については、Flink Cube BuildEngineを参照してください。
MapReduceからSpark、そして今日のFlinkまで、Kylinのビルドエンジンのアップグレードプロセスを振り返ると、ビルドツールの反復は常により優れたメインストリームエンジンに近づいており、Kylinコミュニティには多くのアクティブで優れたコード貢献者がいます。また、Kylinのエコロジーを拡大し、新しい機能を追加することも、学ぶ価値があります。最後に、Meituanの店舗向けケータリング技術チームは、ApacheKylinプロジェクトチームに改めて感謝の意を表しました。
著者について
Yue Qingは、レストランのR&Dセンターのエンジニアとして2019年にMeituanに入社しました。
- - - - - 終わり - - - - -
求人
Meituan to the storeビジネスグループ宿泊チケットデータインテリジェンスグループは、供給、制御、選択、販売など、10万レベルのQPS処理、10億レベルのデータ分析、完全なビジネスクローズドループなど、あらゆる面でビジネス競争力を強化するために、小規模なパートナーを誠実に採用しています、現在Massive HCです。興味のある方は、hezhiming @ meituan.comまでメールをお送りください。できるだけ早くご連絡いたします。
多分あなたはまだ見たいです