概要
マイクロサービスやサーバーレスアプリなどに代表される今日のクラウドアプリケーションは、相互に接続された多くのサービスやサービスインスタンスで構成される分散システムです。観測可能性を確保することなしに、このように複雑なシステム内の問題を解決することは困難です。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 テレメトリの実装
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 に接続し、以下を実行します:
テレメトリ・トレースのデフォルト設定は、以下の SQL で確認できます。
出力結果はこうなります。
+----------------------------------------------------------+----------------------------------+ | 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 ドメインに入って、データ・キーに入ります。そこの設定にあるデータ・アップロード・エンドポイントと 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としてログインします。
例(データキーは無効なサンプルです):
4.1.b エンドポイントの設定
例(エンドポイントは無効なサンプルです):
(訳者註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 -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 など) にローカルにインストールします。その後、設定を行ってください。
注1: YAML のフォーマットは非常に特殊なので注意を払ってください。例えば、タブ文字などは使用しないでください。
注2: この例では太字の設定項目に注意してください。
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 の開始
# サービスではなくコマンドとして実行するならば、サービスを止めて以下を実行
# $ sudo /usr/bin/otelcol –config=/etc/otelcol/config.yaml
5. テレメトリ・クライアント・プラグインを有効化してクエリーを実行
クライアント・テレメトリ・プラグインをロードした状態で、mysql クライアントを起動します。
必要に応じて、プラグイン・ディレクトリのパスを実行者のインストール環境に合わせて調整してください。
起動した 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 からアンインストールするには、以下を実行します。
分析
ここまでの設定で、OCI APM コンソールを使って、アプリケーションから MySQL データベースまで、アプリケーション・スタックのトラブルシューティングができるようになりました。

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


