New RelicではDatabase 360のNRDOTを用いてデータベースを監視できます。今回はNRDOTとAPMを連携し、PostgreSQLのクエリや待機イベントを発行元アプリと関連付ける設定と確認方法を紹介します。
はじめに
問題発生時やエラー、パフォーマンス解析をする際に、データベースの情報を事前に取得しておくことはとても大事です。APMからは遅延したトランザクションからSQLの実行時間や処理の内容は分かりますが、データベース内のSQL間の相関やロックなどの詳細な情報は見えません。そのため、データベース視点の情報を常に取得し、過去情報から効率的に解析することができる状態を作ることが重要です。
New Relicでは、Database 360というデータベースの詳細な情報を可視化して分析することができる機能があります。導入にはNRDOT(New Relic Distribution of OpenTelemetry Collector)というNew RelicがサポートするOpenTelemetryコンポーネントのディストリビューションの機能を利用する必要があります。この機能を利用することで、データベースのコネクション数、遅いクエリのExplain実行計画はもちろんのこと、デッドロックやロックタイプの情報、Wait Events、リアルタイムのセッション数の情報を取得することができます。
また、このSQLは一旦どこのアプリケーションから発行されたのか?を設定で紐づける機能がオプションとして存在し、アプリケーションとデータベースが多対1となっている場合、データベース視点からSQLとアプリケーションを紐付けた解析をより行いやすくなります。
今回は、PostgreSQLに対しNRDOT(New Relic Distribution of OpenTelemetry)を利用している時に、データベースに発行されたクエリをアプリケーションと紐づけることで、どういう情報が見えるかを確認します。
他にもPostgreSQL監視にはOHI(On Host Integration)を利用して観測することができますが、今回はNRDOTを利用しています。
無料のアカウントで試してみよう!
New Relic フリープランで始めるオブザーバビリティ!
前提条件
アプリケーション側
NRDOTとAPMの紐付けには、アプリケーションはJavaまたは.NETが必須となります。Javaを利用する際は、New RelicのJava Agentはバージョン9.1.0以降が必須となります。
今回はTomcat9上で、JavaのOpenJDK 17を利用し、APMはNew Relic Java Agent 9.4.0を利用しています。
データベース側
NRDOTを利用したデータベース監視は、PostgreSQLの場合バージョン14以降が必須となり、導入時にpg_stat_statementsの拡張機能を利用する必要があります。導入方法はセルフホスト型PostgreSQLとRDS PostgreSQLで異なります。
NRDOTの設定方法はそれぞれセルフホスト型PostgreSQL、RDS PostgreSQLをご参照ください。
今回はセルフホスト型PostgreSQLでバージョン16.15を利用しています。
設定方法
アプリケーション側にはAPM、データベース側にはNRDOTは既に導入済みを前提とします。
NRDOTとAPMの紐付けの設定手順として、APMとNRDOTの設定ファイルの2つを変更する必要があります。
Database service identification with NRDOTを元に導入していきます。
そもそも何をやって紐づけているのか
結論から言うと、アプリケーションからデータベースへクエリを発行する際に、APMがSQLの先頭にコメントを追加することで、New Relic側でどこのアプリケーションからきたSQLかを判断しています。
例えば、以下のようなSQLがあったとします。
SELECT REAL_NAME, FAKE_NAME
FROM USER_NAME
WHERE NAMEID = ?;
APM側に紐付けのための設定を入れると、APMがデータベースにクエリを送る際に、計装対象として認識した全てのクエリに対して、アプリケーションのEntity GUIDをnr_service_guidとしてコメントが自動で付与されるため、以下のように変換された後にPostgreSQLにクエリが送られます。
/*nr_service_guid="SAMPLEDESUNANKAKONNNAKANJINIFUYOSAREMASU123456789AAA"*/
SELECT REAL_NAME, FAKE_NAME
FROM USER_NAME
WHERE NAMEID = ?;
実際にデータベース側で実行されるクエリはコメント付きのものが実行されます。その時に、発行元のアプリケーションのnr_service_guidをNRDOTがPostgreSQLから読み取り、New Relicへ送りアプリケーションのEntity GUIDとクエリの紐付けを行っています。
注意ポイント:
pg_hint_planのヒントコメントを使ってSQLチューニングを行っている場合、NRDOTとAPMの紐付けの機能を利用するとクエリの先頭にコメントが付与されるため、正しくヒント句が使われなくなる可能性があります。事前に十分に検証してください。
アプリケーション設定
Java Agentの設定ファイル(newrelic.yml)のtransaction_tracerセクションに対して、sql_metadata_commentsのプロパティを追加します。
参考に、設定時のファイルパスは以下でした。
/opt/newrelic/newrelic.yml
以下のように設定ファイルに追加します。
transaction_tracer:
sql_metadata_comments:
enabled: true
ドキュメントでは以下を追加するように見えて勘違いしてコメントが付与されず悩みました(1敗)。
transaction_tracer:
sql_metadata_comments: nr_service_guid
enable: true側の設定をした後、Tomcatを再起動すると完了です。(JVMプロセスを再起動してください。)
sudo systemctl restart tomcat
データベース設定
NRDOTの設定ファイル(postgresql-config.yaml)のtop_query_collectionとquery_sample_collectionセクションに対して、allowed_comment_keysのプロパティを追加します。参考に、設定時のファイルパスは以下でした。
/etc/nrdot-collector/postgresql-config.yaml
以下のように設定ファイルに追加します。
top_query_collection:
allowed_comment_keys: [nr_service_guid]
query_sample_collection:
allowed_comment_keys: [nr_service_guid]
その後NRDOT Collectorを再起動すると完了です。
sudo systemctl restart nrdot-collector
設定後の確認
NRDOTとAPMを連携した時に効果的な画面に絞って説明します。
(補足として、NRDOTを導入した場合は、対象のデータベースのエンティティはDatabaseから確認できます。)
画面上の項目名は環境差があるため、基本機能はIntroduction to PostgreSQL monitoring with NRDOTで確認してください。
データベースに収集されたクエリと発行元アプリケーションがわかる(Query performance -> Query samples)
Query Sampleとは、一定間隔で収集したセッションやクエリの情報を確認できます。今回は収集間隔を15秒、収集クエリの取得上限を1000行に設定しています。(この機能はすべてのSQLの実行履歴を網羅的に記録するものではありません。)
今回紹介したAPMとの関連付けをしていない場合、以下のようにAPM列はUninstrumentedと表示され、データベースからこのSQLがどのアプリケーションから発行されているか分かりません。
本記事で紹介した設定を導入することで、以下のようにUninstrumentedがAPMのアプリケーション名に変わり、どこから発行されたSQLかわかるため、実際に実行されている遅いSQLやWaitイベントなどがわかります。(SQLの先頭に?と追加されているのは、APMに付与されたコメントがNRDOTの難読化処理で置換されたものです。)
長時間継続している接続や、他SQLにブロックされているアプリケーションがわかる(Sessions)
Sessionsでは、そのデータベースへの接続(セッション)の状態を確認できます。コネクションプールを使っている場合は長時間セッションでもすぐに異常とは判断しませんが、何かしらの理由で長時間開いているセッションや、そのセッションが別のセッションにブロックされているかを絞り込めます。
本記事で紹介した設定を導入することで、どのセッションがどこのアプリケーションから接続されているかわかります。そのため、複数アプリケーションが同じデータベースを利用しているときに、何かしらロック競合などが発生した際、どこのアプリケーション同士が競合しているかが把握しやすくなります。
セッションの詳細を開くと、どのセッションIDがブロックしていたか、またそれはなぜブロックされていたかの詳細な情報がわかります。
待機イベントと関連するアプリケーションがわかる(Wait events)
Wait eventsとは、SQLやセッションが処理中に何を待っているのかを確認できます。SQLの処理時間が長い場合でもインデックスや書き方が悪いから遅いだけではなく、ロック解除を待っている、ディスクIO待ち、WAL関連処理などなどいろいろ原因があります。
本記事で紹介した設定を導入することで、待ちが発生しているSQLやセッションを、そのアプリケーションと関連付けて確認できるため、どこのアプリケーション側の調査に繋げやすくなります。
おわりに
NRDOTとAPMを連携し、データベースに発行されたクエリをアプリケーションと紐づけることで、どういう情報が見えるかを確認しました。長時間接続やブロックしているプロセスを見つけ、発行元のアプリケーションと紐づけることで、データベース側で見つけた問題をアプリケーション側の調査につなげやすくなります。
ぜひデータベース観測を取り入れたシステム作りライフを送っていきましょう。






