メタでの SQL クエリの静的分析の有効化 –

  • UPM は、実行する社内のスタンドアロン ライブラリです。 静的解析 SQL コードの作成および SQL オーサリングの強化。
  • UPM は SQL コードを入力とし、セマンティック ツリーと呼ばれるデータ構造として表現します。
  • Meta のインフラストラクチャ チームは、UPM を活用して SQL リンターを構築し、SQL コードでユーザーの間違いを見つけ、大規模なデータ系統分析を実行します。

データ ウェアハウスに対して SQL クエリを実行することは、メタの多くのエンジニアやデータ サイエンティストのワークフローにとって、定期的なデータ パイプラインの一部として、またはアドホックなデータ探索のために、分析および監視のユース ケースのために重要です。

SQL は非常に強力で、当社のエンジニアの間で非常に人気がありますが、長年にわたって次のような課題にも直面してきました。

  • 静的分析機能の必要性: Meta でのユース ケースの増加では、SQL クエリがクエリ エンジンに対して実行される前に、SQL クエリで何が起こるかをプログラムで理解する必要があります。これは、静的分析と呼ばれるタスクです。 これらのユース ケースは、パフォーマンス リンター (クエリ エンジンが自動的に実行できないクエリの最適化を提案する) やデータ系列の分析 (あるテーブルから別のテーブルへのデータの流れを追跡する) にまで及びます。 これは 2 つの理由で困難でした。まず、クエリ エンジンは SQL クエリを実行するために内部的に分析する機能を備えていますが、このクエリ分析コンポーネントは通常、クエリ エンジンのコード内に深く埋め込まれています。 拡張するのは簡単ではなく、他のインフラストラクチャ チームが使用することは意図されていません。 これに加えて、各クエリ エンジンには、独自の SQL ダイアレクトに固有の独自の分析ロジックがあります。 その結果、SQL クエリの分析を構築したいチームは、各 SQL クエリ エンジン内でゼロから再実装する必要があります。
  • 制限型システム: 最初は、固定セットのみを使用しました 組み込みの Hive データ型 (ストリング積分ブール値など) データ ウェアハウスのテーブル列を説明する. ウェアハウスがより複雑になるにつれて、このタイプのセットは不十分になりました。ユニット エラーなどの一般的なカテゴリのユーザー エラーを検出できなくなったためです (2 つのテーブル間で UNION を作成することを想像してください。どちらにも という列が含まれています)。 タイムスタンプ、しかし一方はミリ秒単位でエンコードされ、もう一方はナノ秒単位でエンコードされます)、または ID 比較エラー (2 つのテーブル間の JOIN を想像してください。 ユーザーID — しかし、実際には、これらの ID は別の機関によって発行されています。 システムなので比較できません)。

UPM の仕組み

これらの課題に対処するために、UPM (統合プログラミング モデル) を構築しました。 UPM は SQL クエリを入力として受け取り、セマンティック ツリーと呼ばれる階層的なデータ構造として表現します。

たとえば、次のクエリを UPM に渡す場合:

SELECT
COUNT(DISTINCT user_id) AS n_users
FROM login_events

UPM は次のセマンティック ツリーを返します。

SelectQuery(
 	items=[
 	SelectItem(
       	name="n_users",
       	type=upm.Integer,
       	value=CallExpression(
            	function=upm.builtin.COUNT_DISTINCT,
                arguments=[ColumnRef(name="user_id", parent=Table("login_events"))],
       	),
 	)
    ],
    parent=Table("login_events"),
)

他のツールは、次のようなさまざまなユース ケースでこのセマンティック ツリーを使用できます。

  1. 静的分析: ツールでできること 検査する セマンティック ツリーを表示し、クエリに関する診断または警告を出力します (SQL リンターなど)。
  2. クエリの書き換え: ツールでできること 変更 クエリを書き換えるためのセマンティック ツリー。
  3. クエリの実行: UPM は、プラグ可能な SQL フロント エンドとして機能できます。つまり、データベース エンジンまたはクエリ エンジンは、UPM セマンティック ツリーを直接使用して、クエリ プランを生成および実行できます。 (言葉 フロントエンド このコンテキストでは、コンパイラの世界から借用されています。 フロントエンドは、高レベルのコードを最終的に実行可能プログラムの生成に使用される中間表現に変換するコンパイラの一部です)。 または、UPM はセマンティック ツリーをターゲットの SQL 方言に (文字列として) レンダリングし直し、それをクエリ エンジンに渡すことができます。

統一された SQL 言語のフロント エンド

UPM を使用すると、SQL ユーザーに単一言語のフロント エンドを提供できるため、SQL ユーザーは単一の言語 ( プレスト SQL ダイアレクト) — ターゲット エンジンが Presto、Spark、または XStream (当社の社内ストリーム処理サービス) であるかどうか。

この統合は、データ インフラストラクチャ チームにとっても有益です。この統合のおかげで、SQL 静的分析または書き換えツールを所有するチームは、解析、分析、または異なる SQL クエリ エンジンとの統合について心配することなく、UPM セマンティック ツリーを標準の相互運用形式として使用できます。および SQL ダイアレクト。 似ている、よく似ている ヴェロックス プラグ可能として機能することができます 実行エンジン データ管理システムの場合、UPM はプラグ可能なものとして機能できます フロントエンド言語 データ管理システムの場合、チームは独自の SQL フロント エンドを維持する労力を節約できます。

強化された型チェック

UPM により、強化された型チェックを提供することもできます SQLクエリの。

私たちの倉庫では、各テーブルの列には、次のような固定リストから「物理」タイプが割り当てられています。 積分ストリング. さらに、各列はオプションのユーザー定義型を持つことができます。 ディスク上でのデータのエンコード方法には影響しませんが、このタイプはセマンティック情報 (Email、TimestampMilliseconds、UserID など) を提供できます。 UPM は、これらのユーザー定義型を利用して、SQL クエリの静的型チェックを改善できます。

たとえば、SQL クエリの作成者は、異なるログイン イベントに関する情報を含む 2 つのテーブルのデータを UNION したい場合があります。

右側のクエリでは、作成者はテーブルからミリ秒単位でタイムスタンプを結合しようとしています user_login_events_mobile テーブルからのナノ秒単位のタイムスタンプ付き user_login_events_desktop — 2 つの列が同じ名前であるため、理解できる間違いです。 ただし、テーブルのスキーマにはユーザー定義型の注釈が付けられているため、クエリがクエリ エンジンに到達する前に UPM のタイプチェッカーがエラーを検出します。 次に、コード エディターで作成者に通知します。 このチェックがなければ、クエリは正常に完了し、作成者はずっと後になるまで間違いに気付かなかった可能性があります。

列レベルのデータ系統

データ リネージ (データがウェアハウス内で消費面に至るまでの流れを理解すること) は、データ インフラストラクチャの基礎となる部分です。 これにより、データ品質に関する質問に答えることができます (たとえば、「このデータは正しくないようです。データはどこから来たのですか?」、「このテーブルのデータは破損しています。影響を受けた下流のデータ資産はどれですか?」)。 また、データのリファクタリングにも役立ちます (「このテーブルを削除しても安全ですか? まだ依存している人はいますか?」)。

これらの重要な質問に答えるために、当社のデータ リネージ チームは、UPM セマンティック ツリーを入力として受け取るクエリ分析ツールを構築しました。 このツールは、繰り返されるすべての SQL クエリを調べて、ウェアハウス全体にわたって列レベルのデータ系列グラフを作成します。 たとえば、次のクエリがあるとします。

INSERT INTO user_logins_daily_agg
SELECT
   DATE(login_timestamp) AS day,
   COUNT(DISTINCT user_id) AS n_users
FROM user_login_events
GROUP BY 1

UPM を利用した列系統分析では、次のエッジが推測されます。

[{
   from: “user_login_events.login_timestamp”,
   to: “user_login_daily_agg.day”,
   transform: “DATE”
},
{
   from: “user_login_events.user_id”,
   to: “user_logins_daily_agg.n_user”,
   transform: “COUNT_DISTINCT”
}]  

データ ウェアハウスに対して毎日実行されるすべてのクエリについてこの情報をまとめることで、ツールは完全な列レベルのデータ系列グラフのグローバル ビューを表示します。

UPM の次のステップ

Meta で UPM の可能性を最大限に引き出し続けるため、さらにエキサイティングな仕事を楽しみにしています。 最終的には、すべてのメタ ウェアハウス テーブルにユーザー定義の型やその他のメタデータで注釈が付けられ、強化された型チェックがすべてのオーサリング サーフェスで厳密に適用されることを願っています。 Hive ウェアハウスのほとんどのテーブルは既にユーザー定義型を利用していますが、既存の SQL パイプラインの移行を容易にするために、より厳格な型チェック ルールを徐々に展開しています。

私たちはすでに UPM を Meta の開発者が SQL を記述するメイン サーフェスに統合しています。私たちの長期的な目標は、UPM を Meta の統合 SQL フロント エンドにすることです。つまり、すべてのクエリ エンジンに深く統合し、単一の SQL ダイアレクトを開発者に公開します。 また、この統一された SQL ダイアレクトのエルゴノミクスを反復する予定です (たとえば、 選択する 句と次のような構文構造をサポートすることによって SELECT * EXCEPT <一部の列>、一部の SQL ダイアレクトには既に存在します)、最終的には人々がクエリを作成する際の抽象化のレベルを上げます。

Leave a Comment

Your email address will not be published. Required fields are marked *