概要

マイクロサービスやサーバーレスアプリなどに代表される今日のクラウドアプリケーションは、相互に接続された多くのサービスやサービスインスタンスで構成される分散システムです。観測可能性を確保することなしに、このように複雑なシステム内の問題を解決することは困難です。OCI APM (Application Performance Monitor) サービスは、IT環境全体にわたって、エンドツーエンドの可視性と診断のための観測性を提供します。分散トランザクション・トレースを用いてUXとテクノロジー基盤を結び付け、ビジネス中心的アプローチで問題の特定と診断を自動化します。

分散システムを可視化するためにテレメトリ・トレースを使うと、アプリケーション・コードから MySQL に至るまでのシステム全体を一気通貫に計測することができます。

MySQL は Cloud Native Compute Foundation のオープンな標準である、OpenTelemetry Protocol (OTLP) に則ったテレメトリ・トレース仕様を採用しています。

本記事では、OCI APM と MySQL テレメトリ・トレースを使った MySQL のトラブルシューティングについてとりあげます。(訳者註: 元記事は MySQL Server 8.2 を元に書かれていましたが、本記事では LTS である 8.4 を元に動作を確認し、バージョン差により注意すべき点については訳者註で補足しています。)

分散トレース

分散トレース・テレメトリにより、分散システムの隅から隅へと伝播する、あらゆる処理アクションの完全なフローを視覚化できます。各アクション単位(スパンと呼ばれます)のデータには、起こりうるエラーの情報とそのタイミングが含まれています。

ウェブサイトでのユーザーアクションを例にとると:

  • ユーザーがウェブブラウザ内にあるアプリケーションUIのボタンを押すと開始。
  • リクエストがウェブサーバーに到達します。
  • リクエストによってトリガーされたアプリケーションロジックは、認証、認可、データベースからデータをフェッチして処理するミドルウェアなどのさまざまなサービスに対して、多くのAPIリクエストを発行します。
  • 最終的に結果を送信して画面上にレンダリングします。

アプリケーションスタック内のレイヤーがインストルメント化されている場合、それらはシステムの他の部分に影響を与えずに、テレメトリデータをテレメトリコレクターに直接送信します。ここで唯一必要となるレイヤー間の相互作用は、アクションがレイヤーにによって処理されるときの、テレメトリのコンテキスト(たとえば親のスパン ID のような)を伝播する機能です。最終的なトレースグラフは、コレクター/バックエンド側で組み立てられ、テレメトリコンテキスト情報を用いて、各スパンを親スパンの下に配置します。

下の画像は、ユーザーアクションを処理する各アプリケーションレイヤー間の通信を示していますが、インストルメント化された各レイヤーは、他のレイヤーとは独立に独自のテレメトリデータ(トレース)を送信します(先述のとおり、レイヤー間のテレメトリコンテキストの受け渡しは除きます)。

MySQL から OCI APM へ

MySQL テレメトリの実装

MySQL テレメトリ・トレース機能を使用すれば、MySQL サーバーとクライアントの両方でトレースを生成できます。

トレースは、COM_PING、COM_STMT_CLOSE などの非クエリコマンドを含む、実行中の MySQL プロトコルコマンドに対して生成されます。ただし、クエリ・ステートメントに対するトレースのみが、SQL コマンドとしてテキスト属性を持つ点に注意が必要です。

アプリケーションコードは、2 つの方法でインストルメント化する必要があります:

  • OpenTelemetry フレームワークを使用して独自のコードをインストルメント化し、独自のアクションに対してトレーススパンを生成(このアクションは MySQL のインストルメント化とは独立)
  • SQL クエリの実行時に、「traceparent」MySQL クエリ属性を通して親のスパン ID を渡し、下流のコード用に生成される「child」OTel スパンが、グラフ内の正しい場所に配置されるようにする

トレースは、OTLP HTTPプロトコルを使用して発行され、protobufまたはJSONペイロードフォーマットを使用するように設定できます。 トレースはDBセッションとサーバー上で実行されているSQLステートメント、およびスパンをキャプチャします。

テレメトリ・トレースは以下のツールの中に実装されています。

  • MySQL Server の テレメトリコンポーネント
  • MySQL コマンドラインツール
  • MySQL Connectors

サーバ・トレースは以下の情報をキャプチャします。

  • DB セッション
  • サーバで実行される SQL ステートメント

MySQL でテレメトリ・トレースを生成するには、テレメトリを有効にし、アプリケーションスタック、クライアント、Connectors、そして最下流に MySQL Serverからスパンを渡します。

デモサーバーのセットアップ

このデモでは、OCI (Oracle Cloud Infastructure) 上にデプロイされた MySQL Server インスタンスを使用し、OCI APM (Application Performance Monitoring) にテレメトリ・データを送信します。

デモには2つのオプションがあります。

  • オプション 1 – 最もシンプルな事例 – OCI APM にトレースを直接送付
  • オプション 2 – よりカスタマイズしやすい事例 – 同じ OCI インスタンス上で動作する opentelemetry-collector を使用してトレースを収集し、OCI APM バックエンドに送付

Telemetry クライアントプラグインがロードされている MySQL クライアントと、 Telemetry コンポーネントがロードされているMySQL サーバーの両方でインストルメント化を行い、サーバーでのトレースがクライアントでのトレースの子になるように、テレメトリ・コンテキストがどう伝搬されるかを示します。

1. MySQL server のインストールと開始

OCIインスタンスにMySQL Server 8.2.0以降(Enterprise Edition)をインストールします。

2. MySQL コンポーネントのインストール

クライアントを使用してMySQL Server に接続し、以下を実行します:

mysql> INSTALL COMPONENT ‘file://component_telemetry’;

テレメトリ・トレースのデフォルト設定は、以下の SQL で確認できます。

mysql> SHOW VARIABLES LIKE ‘%telemetry%’;

出力結果はこうなります。

+----------------------------------------------------------+----------------------------------+
| Variable_name                                            | Value                            |
+----------------------------------------------------------+----------------------------------+
| telemetry.metrics_enabled                                | ON                               |
| telemetry.metrics_reader_frequency_1                     | 10                               |
| telemetry.metrics_reader_frequency_2                     | 60                               |
| telemetry.metrics_reader_frequency_3                     | 0                                |
| telemetry.otel_bsp_max_export_batch_size                 | 512                              |
| telemetry.otel_bsp_max_queue_size                        | 2048                             |
| telemetry.otel_bsp_schedule_delay                        | 5000                             |
| telemetry.otel_exporter_otlp_metrics_certificates        |                                  |
| telemetry.otel_exporter_otlp_metrics_cipher              |                                  |
| telemetry.otel_exporter_otlp_metrics_cipher_suite        |                                  |
| telemetry.otel_exporter_otlp_metrics_client_certificates |                                  |
| telemetry.otel_exporter_otlp_metrics_client_key          |                                  |
| telemetry.otel_exporter_otlp_metrics_compression         | none                             |
| telemetry.otel_exporter_otlp_metrics_endpoint            | http://localhost:4318/v1/metrics |
| telemetry.otel_exporter_otlp_metrics_headers             |                                  |
| telemetry.otel_exporter_otlp_metrics_max_tls             |                                  |
| telemetry.otel_exporter_otlp_metrics_min_tls             |                                  |
| telemetry.otel_exporter_otlp_metrics_protocol            | http/protobuf                    |
| telemetry.otel_exporter_otlp_metrics_timeout             | 10000                            |
| telemetry.otel_exporter_otlp_traces_certificates         |                                  |
| telemetry.otel_exporter_otlp_traces_cipher               |                                  |
| telemetry.otel_exporter_otlp_traces_cipher_suite         |                                  |
| telemetry.otel_exporter_otlp_traces_client_certificates  |                                  |
| telemetry.otel_exporter_otlp_traces_client_key           |                                  |
| telemetry.otel_exporter_otlp_traces_compression          | none                             |
| telemetry.otel_exporter_otlp_traces_endpoint             | http://localhost:4318/v1/traces  |
| telemetry.otel_exporter_otlp_traces_headers              |                                  |
| telemetry.otel_exporter_otlp_traces_max_tls              |                                  |
| telemetry.otel_exporter_otlp_traces_min_tls              |                                  |
| telemetry.otel_exporter_otlp_traces_protocol             | http/protobuf                    |
| telemetry.otel_exporter_otlp_traces_timeout              | 10000                            |
| telemetry.otel_log_level                                 | info                             |
| telemetry.otel_resource_attributes                       |                                  |
| telemetry.query_text_enabled                             | ON                               |
| telemetry.trace_enabled                                  | ON                               |
+----------------------------------------------------------+----------------------------------+
35 rows in set (0.00 sec)

(訳者註: MySQL Server 8.4 での結果ですので、テレメトリ・トレース関連の設定だけではなく、メトリックに関する設定も表示されています。)

3. OCI APM のセットアップ

OCI コンソールにログインして、「監視および管理」-「アプリケーション・パフォーマンス・モニタリング」-「管理」に進みます。

APMの管理にアクセス

APMドメインを作成します。

APM ドメインの追加

APM ドメインに入って、データ・キーに入ります。そこの設定にあるデータ・アップロード・エンドポイントと private_datakey を用います。

データ・キーの取得

4. OCI APMへデータをプッシュ

選びうるオプションとして、トレースは以下のどちらかの方法で送信できます。

  • OCI APMエンドポイントへの直接送信
  • OpenTelemetry コレクタ経由 – これを選択すると、OpenTelemetry コレクタが提供できる追加のカスタマイズを利用できます。例えば、パイプラインを用いて複数のトレース・コンシューマにトレース情報を送信できます。

どちらかを選択してください。 参考: https://dev.mysql.com/doc/refman/8.2/en/telemetry-trace-install.html

4.1 オプション 1 – OCI APM への直接的なトレースの書き込み

4.1.a データキーの設定

mysql のレガシークライアント、またはmysqlsh(sqlモード)を使用し、root/adminとしてログインします。

> set persist_only telemetry.otel_exporter_otlp_traces_headers=’Authorization=dataKey <プライベートキー文字列>’;

例(データキーは無効なサンプルです):

> set persist_only otel-exporter-otlp-traces-headers = “Authorization=dataKey ###########################

4.1.b エンドポイントの設定

> set persist_only telemetry.otel_exporter_otlp_traces_endpoint=<APM エンドポイント>

例(エンドポイントは無効なサンプルです):

> set persist_only telemetry.otel_exporter_otlp_traces_endpoint=’https://################.apm-agt.ap-tokyo-1.oci.oraclecloud.com/20200101/opentelemetry/private/v1/traces‘;

(訳者註1: telemetry.otel_exporter_otlp_traces_endpoint にセットすべき URL の値は、https://################.apm-agt.ap-tokyo-1.oci.oraclecloud.com/20200101/opentelemetry/private/v1/traces までですが、OCI の UI で表示される/コピーできるデータ・アップロード・エンドポイントの値は、https://################.apm-agt.ap-tokyo-1.oci.oraclecloud.com までのドメイン部分のみである点に注意してください。セットする値には、ドメインの後に /20200101/opentelemetry/private/v1/traces を手動で加える必要があります。)

(訳者註2: MySQL Server の OpenTelemetry 機能では、トレースとメトリックのエンドポイントは個別に設定します。トレースを通知するエンドポイント設定は上記のとおり telemetry.otel_exporter_otlp_traces_endpoint ですが、メトリックについては telemetry.otel_exporter_otlp_metrics_endpoint になります。またセットすべき値は、OCI APM の場合 https://################.apm-agt.ap-tokyo-1.oci.oraclecloud.com/20200101/opentelemetry/private/v1/metrics になります。)

4.2 オプション 2 – トレースをOpenTelemetry Collector に書き込み、Collector は OCI APM にパイプ

4.2.a 用いる環境での OpenTelemetry Collector パッケージを検索してダウンロードし、インストール

例えば Linux の場合だと、以下のようになります。

$ sudo yum update
$ sudo yum -y install wget systemctl
$ wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.109.0/otelcol_0.109.0_linux_amd64.rpm
$ sudo rpm -ivh otelcol_0.109.0_linux_amd64.rpm

(訳者註: OpenTelemetry サイトのドキュメント)を元に、元記事のコマンド内容を書き換えています。)

4.2.b ローカルの OpenTelemetry Collector の設定(オプション)

※この記事の例では OpenTelemetry Collector がローカル環境で走っているため、MySQL Server の設定はデフォルトのまま手を付けません。

オープンな OpenTelemetry Collector を Linux オペレーティングシステム (Oracle Linux など) にローカルにインストールします。その後、設定を行ってください。

$ sudo vi /etc/otelcol/config.yaml 

注1: YAML のフォーマットは非常に特殊なので注意を払ってください。例えば、タブ文字などは使用しないでください。

注2: この例では太字の設定項目に注意してください。

extensions:
  health_check:
  pprof:
    endpoint: 0.0.0.0:1777
  zpages:
    endpoint: 0.0.0.0:55679

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

  opencensus:
    endpoint: 0.0.0.0:55678

  # Collect own metrics
  prometheus:
    config:
      scrape_configs:
      – job_name: ‘otel-collector’
        scrape_interval: 10s
        static_configs:
        – targets: [‘0.0.0.0:8888’]

  jaeger:
    protocols:
      grpc:
        endpoint: 0.0.0.0:14250
      thrift_binary:
        endpoint: 0.0.0.0:6832
      thrift_compact:
        endpoint: 0.0.0.0:6831
      thrift_http:
        endpoint: 0.0.0.0:14268

  zipkin:
    endpoint: 0.0.0.0:9411

processors:
  batch:

exporters:
  debug:
    verbosity: detailed
  otlphttp:
    endpoint: “https://################.apm-agt.ap-tokyo-1.oci.oraclecloud.com/20200101/opentelemetry/private”
    headers: {Authorization: “dataKey ###########################”}


service:

  pipelines:

    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlphttp]

    metrics:
      receivers: [otlp, opencensus, prometheus]
      processors: [batch]
      exporters: [debug]

    logs:
      receivers: [otlp]
      processors: [batch]
      exporters: [debug]
  extensions: [health_check, pprof, zpages]

(訳者註: exporters.otlphttp.endpoint にセットすべき URL の値は、 MySQL Server での設定と異なり、トレースとメトリックで共通の値を設定するため、/v1/traces や /v1/metrics といった部分を除いた、https://################.apm-agt.ap-tokyo-1.oci.oraclecloud.com/20200101/opentelemetry/private までを設定します。)

4.2.c OpenTelemetry Collector の開始

$ systemctl restart otelcol

# サービスではなくコマンドとして実行するならば、サービスを止めて以下を実行
# $ sudo /usr/bin/otelcol –config=/etc/otelcol/config.yaml

5. テレメトリ・クライアント・プラグインを有効化してクエリーを実行

クライアント・テレメトリ・プラグインをロードした状態で、mysql クライアントを起動します。

必要に応じて、プラグイン・ディレクトリのパスを実行者のインストール環境に合わせて調整してください。

$ mysql -uroot -p -h 127.0.0.1 –port=3306 –plugin_dir=/usr/local/mysql/lib/plugin –telemetry-client

起動した mysql クライアントで、テスト用の SQL(何でも構いません)を実行してみてください。

6. OCI APM コンソールでのトレースの観察

OCI APM コンソールにアクセスし、APM ドメインを選択して、アプリケーション、MySQL Connectors、クライアント、MySQL Server から送信されたトレースを確認します。

トレース・エクスプローラ

7. 有効化 / 無効化

テレメトリ・トレースの実行は、多くの場合、インタラクションの観測可能性を向上させるために有効にします。ただし、追加するごとにオーバーヘッドが発生する可能性がある点には留意してください。

サンプリングレベルなどを設定するには、OpenTelemetry Collector を使用した様々な手法があります。

MySQL クライアント:

コマンドラインスイッチ –telemetry_client 、あるいは設定オプション telemetry-client=ON |OFF で有効/無効にできます。

MySQL Server:

以下のシステム変数で、テレメトリのオン・オフを切り替えられます。  

  • set persist telemetry.trace_enabled=’OFF’;
  • set persist telemetry.trace_enabled=’ON’;

Connectors:

各 Connector は、各言語の OpenTelemetry 対応ライブラリで有効/無効を切り替えられます。

8. アンインストール

テレメトリ・コンポーネントを MySQL Server からアンインストールするには、以下を実行します。

> UNINSTALL COMPONENT ‘file://component_telemetry’;

 

分析

ここまでの設定で、OCI APM コンソールを使って、アプリケーションから MySQL データベースまで、アプリケーション・スタックのトラブルシューティングができるようになりました。

OCI APM でのトレースビューとトポロジー

まとめ

複雑な分散システムの運用を成功させる鍵は、観測可能性です。OCI APM と MySQL テレメトリ・トレーシングを使用することで、MySQL データベース・インスタンスを統合し、アプリケーション・スタック全体で高度な観測可能性を提供できます。

その他のリソース