Sqlcommenter のご紹介: オープンソース ORM の自動インストルメンテーション ライブラリ
Google Cloud Japan Team
※この投稿は米国時間 2021 年 1 月 29 日に、Google Cloud blog に投稿されたものの抄訳です。
オブジェクト リレーショナル マッピング(ORM)を使用すると、任意のプログラム言語のアプリケーション コードと自然に統合される、オブジェクト指向の枠組みを使用したクエリを容易に作成できるようになります。多くのフルスタック開発者は、自身のアプリケーションでデータベース コードを記述するために ORM ツールに頼っていますが、その場合 SQL ステートメントは ORM ライブラリによって生成されるため、アプリケーション開発者にとって、どのアプリケーション コードがスロークエリにつながっているかを把握することがより難しくなる可能性があります。次の例は、2 行の Django アプリケーション コードが、ORM ライブラリによって 1 つの SQL ステートメントに変換される場合のコード スニペットを示したものです。
Sqlcommenter のご紹介
本日は Sqlcommenter をご紹介します。Sqlcommenter は、ORM ライブラリと、想定しているデータベースの性能との間のギャップを解決するオープンソース ライブラリです。Sqlcommenter を使用すると、アプリケーション開発者がどのアプリケーション コードがスロークエリを生成しているかを視覚的に把握できるようになります。またアプリケーションのトレースが、データベースのクエリプランにマッピングされます。
Sqlcommenter は、ORM を通じて、クエリを実行するコードに関する情報を含むコメントを用いて実行前の SQL ステートメントを補足することができるオープンソース ライブラリです。これにより、スロークエリとソースコードの関係性を容易に示すことができ、バックエンド データベースのパフォーマンスを理解できるようになります。つまり Sqlcommenter により、クライアント側アプリケーションの状態と、データベースのパフォーマンスに対するその影響についてのオブザーバビリティを得られることになります。アプリケーション開発者が ORM を使用してアプリケーションの Sqlcommenter を有効にするには、アプリケーション コードに若干の変更を加える必要があります。Sqlcommenter で得られるオブザーバビリティ情報は、スロークエリのログを使用してアプリケーション開発者が直接使用することも、アプリケーション ベースのモニタリングを行うため Cloud SQL Insights などの他のプロダクトまたはツールに統合することも可能です。
Sqlcommenter の使用を開始する
Sqlcommenter は、Python、Java、Node.js、Ruby の各言語で使用でき、Django、Sqlalchemy、Hibernate、Knex、Sequelize、Rails の ORM をサポートしています。Django で Sqlcommenter を有効にする方法の例を確認して、Django アプリケーションのパフォーマンス分析に Sqlcommenter がどのように役立つかを見ていきましょう。
Python のインストール
Django 向け Sqlcommenter ミドルウェアは、pip3 コマンドを使用してインストールできます。
Django 向け Sqlcommenter を有効にする
Django アプリケーションで Sqlcommenter を有効にするには、MIDDLEWARE セクションに google.cloud.sqlcommenter.django.middleware.SqlCommenter が含まれるように、settings.py ファイルを編集します。
ORM 情報でスロークエリ ログを補足する
PostgreSQL や MySQL のようなデータベースによって提供されるスロークエリ ログは、実行速度の遅いクエリの特定やトラブルシューティングに役立ちます。たとえば PostgreSQL では、log_min_duration_statement のデータベース フラグを設定でき、log_min_duration_statement で指定された値以上の期間のクエリが PostgreSQL によってログに記録されます。
ORM のアプリケーション タグでスロークエリ ログを補足すると、Sqlcommenter を通じて、どのアプリケーション コードがスロークエリに関係しているかを判断できるようになります。有効な Django 向け Sqlcommenter を含む Django アプリケーションで使用される PostgreSQL データベースから得られたクエリログの一例を以下に示します。
このログでは、UPDATE ステートメントが実行されていることを確認できます。SQL ステートメントの最後には、SQL スタイルのコメントが、key=value ペアの形式で追加されています。そのキーはアプリケーション タグと呼ばれます。このコメントは、Django の ORM で生成された SQL クエリに Sqlcommenter によって追加されます。
このコメントからわかるように、Sqlcommenter はコントローラについての情報を提供しており、ここではクエリを送信するコントローラ メソッドである「assign_order」がそれに該当します。Django の場合、MVC パターンのコントローラは、Django アプリケーションのビューにマッピングされます。また Django のこのビューが呼び出されたルートについての情報も提供され、どのビューメソッドがこのクエリを作成したかについて、アプリケーション開発者が直ちに把握できます。このクエリには 400 ミリ秒かかっているため、「assign_order」ビューメソッドによって作成されたこのクエリの負荷が大きい理由がわかります。
OpenTelemetry 統合で ORM をトレースする
Sqlcommenter を使用すると、アプリケーション トレースとデータベースのクエリプランに相関性を持たせて、OpenCensus と OpenTelemetry のトレース コンテキスト情報がデータベースにプロパゲートされるようにすることができます。
次の例は、Sequelize ORM 向け Sqlcommenter によって追加された SQL コメントを含むクエリログを示したものです。
このクエリログの例では、コメントの一部として traceparent タグを確認できます。traceparent アプリケーション タグは W3C トレース コンテキストに基づいており、これによりトレース ID とスパン ID でトレース コンテキストを伝播する基準が定義されます。traceparent アプリケーション タグは、コンテキスト情報を利用して Sqlcommenter によって作成されます。アプリケーションのクエリログとトレース情報を使用すれば、そのトレース情報と特定のクエリを関連付けることができます。コンテキスト情報とトレース情報のプロパゲートに関する詳細は、OpenTelemetry の仕様でご確認いただけます。
Sqlcommenter を利用した、Cloud SQL Insights でのアプリケーション ベース モニタリング
開発者が Cloud SQL 上のクエリ パフォーマンスの問題を迅速に把握して解決するサポートのために最近リリースされた Cloud SQL Insights が、Sqlcommenter とどのように統合されたかについて確認していきましょう。Cloud SQL Insights を使用すると、Cloud SQL データベースに対するクエリ パフォーマンスの問題を検出・診断することができます。セルフサービス方式で直観的にわかりやすく、単なる検出機能を超えた、パフォーマンスの問題の根本原因の特定に役立つ診断情報が提供されます。
アプリケーション レベルでパフォーマンスをモニタリングでき、モデル、ビュー、コントローラ、ルート、ユーザー、ホストによるアプリケーション スタック全体で、問題のあるクエリの元をトレースすることができます。Cloud SQL Insights は、アプリケーションによって送信された上位のアプリケーション タグ(コントローラ、ルートなど)を特定するために、Sqlcommenter から送信された情報を使用します。
前述の Django アプリケーションに接続された Cloud SQL インスタンスの Insights ダッシュボードの例を次に示します。スクリーンショットの表で示されているとおり、上位のコントローラやルートのアプリケーション タグだけでなく、アプリケーション タグのその他の指標も提供されます。こうしたアプリケーション タグは Django アプリケーションで有効にされた Sqlcommenter によって生成され、Cloud SQL や PostgreSQL で上位のアプリケーション タグを特定するために利用されます。この情報は Cloud SQL Insights ダッシュボードに表示され、Cloud Monitoring にもエクスポートされます。
前述の「assign_order」コントローラは、データベースの負荷の一因となっているトップタグの一つとして、ルート「demo/assign_order」と一緒に表示されます。Insights を使用する場合の詳細については、Cloud SQL Insights のドキュメントをご参照ください。
Cloud SQL Insights でエンドツーエンドのトレースを使用する
traceparent とクエリログを使用する際の問題の 1 つは、クエリプランとアプリケーション トレースの視覚化が難しいことです。Cloud SQL Insights を使用すると、SQL コメントの traceparent コンテキスト情報とともにクエリプランが Cloud Trace として生成されます。トレース ID はアプリケーションによって作成され、親スパン ID は SQL コメントとしてデータベースに送られるため、アプリケーションからデータベースへのエンドツーエンドのトレースが可能になります。エンドツーエンドのトレースは、Cloud Trace ダッシュボードでスパンとして、クエリプランとともに視覚化することができます。次の例は、NodeJS Express Sqlcommenter ライブラリのクエリプランのトレーススパン、および OpenTelemetry のアプリケーションのトレーススパンを示したものです。
この情報を使用すると、アプリケーション コードによって作成されたクエリを把握し、アプリケーションのパフォーマンスの問題を診断するためにアプリケーションのトレースとクエリプランを関連付けることができます。
これらのトレースには、Cloud SQL Insights で、トップタグの表の項目を選択することでアクセスできます。
まとめ
アプリケーション開発者は Sqlcommenter を通じて、ORM ツールを用いて、データベースに影響を与えるアプリケーション コード内のパフォーマンスの問題を診断できます。Sqlcommenter を Cloud SQL Insights と統合することで、データベースの負荷の一因となっているトップのアプリケーション タグを視覚化し、エンドツーエンドのアプリケーションの問題をトレースすることができます。Sqlcommenter をサポートする言語と ORM の詳細について、または本プロジェクトをサポートしていただける場合は、 Sqlcommenter github リポをご覧ください。
-ソフトウェア エンジニア Bala Chandrasekeran