はじめに
Oracle Database 23ai(21c) には、多機能なメッセージ・キューイング・システムであるAdvanced Queuing(AQ)と、高スループットのメッセージ交換を可能にするTransactional Event Queues(TxEventQ)という無償で使用できる機能があります。
今回は、この機能を使うにあたり、パフォーマンス監視を行うTxEventQ Monitorシステムを構築してみたいと思います。TxEventQの詳細はこちらのドキュメントや以下のQiita記事を参照してください。
コンポーネントとしては、以下の3つです。
-
Oracle Database Observability Exporter: Oracle Database用のPrometheusエクスポータ。データベースに接続し、メトリックを問い合せて、メトリックをPrometheus様式のメトリックに書式化します。
-
Prometheus: 監視システムおよび時系列データベース。Oracle DBエクスポータから収集したメトリックを時系列形式で管理します。
-
Grafana: 分析およびインタラクティブな視覚化プラットフォーム。データ・ソースとしてPrometheusを指定します。
ドキュメントはこちらです。
環境情報
監視フレームワークを構築する仮想マシンの情報
- シェイプ: VM.Standard.E4.Flex
- イメージ: Oracle Linux 8.8
- Docker: 24.0.7
- Docker Compose: 2.21.0
監視対象のOracle Database
- Oracle Database 23.3(OCIのBaseDB)
監視用データベース・ユーザーの作成
今回はOCI上に23ai(23.3)のBaseDBを作成し、そのうえにpdb23ai
というPDBを作成しています。これを監視対象のPDBとし、その中に監視用のデータベース・ユーザーmonitor
を作成しています。
-
SYSでユーザー作成
SELECT_CATALOG_ROLE
を付与することで、Prometheusで収集するメトリックのディレクトリなどの参照権限が与えられます。create user monitor identified by Welcome12345#; grant connect, resource, DBA, SELECT_CATALOG_ROLE, unlimited tablespace to monitor;
-
TxEventQ関連のロール付与
grant execute on dbms_aq to monitor; grant execute on dbms_aqadm to monitor; grant execute on dbms_aqin to monitor; grant execute on dbms_aqjms_internal to monitor; grant execute on dbms_teqk to monitor; grant execute on DBMS_RESOURCE_MANAGER to monitor; grant select on sys.aq$_queue_shards to monitor; grant select on user_queue_partition_assignment_table to monitor;
-
仮想マシンからSQL*Plusで
monitor
でpdb23aiに接続できるか確認(簡易接続)sqlplus monitor/Welcome12345#@xxxx:1521/pdb23ai.xxxx.vcn1.oraclevcn.com SQL*Plus: Release 21.0.0.0.0 - Production on Tue Nov 14 06:26:35 2023 Version 21.9.0.0.0 Copyright (c) 1982, 2022, Oracle. All rights reserved. Last Successful login time: Tue Nov 14 2023 06:26:23 +00:00 Connected to: Oracle Database 23c Enterprise Edition Release 23.0.0.0.0 - Production Version 23.3.0.23.09
Oracle Database Observability Exporter の設定
Oracle Database Observability Exporterは、Oracle Container Registryからダウンロードできるコンテナ・イメージを使って、ローカルコンテナ内で利用できます。なお認証やライセンスの提示/承認は必要ありません。
ちなみに、このOracle Container Registryには、Autonomous DatabaseのFreeイメージや、Oracle Transaction Manager for Microservices (MicroTx)のイメージもあります。
-
作業用ディレクトリの作成
mkdir -p monitoring/exporter cd monitoring/exporter
-
カスタムメトリックの設定ファイル
txeventq-metrics.toml
の作成
今回はデフォルトのメトリック以外にも、TxEventQ用のメトリックを収集したいので、tomlファイルを作成し、それを利用したDocker Imageを作成します。txeventq-metrics.toml[[metric]] context = "ownership" metricsdesc = { inst_id = "Owner instance of the current queues." } request = ''' SELECT inst_id FROM gv$persistent_queues WHERE ROWNUM < 2 ''' [[metric]] context = "teq" metricsdesc = { curr_inst_id = "ID of current instance" } request = "SELECT instance_number AS curr_inst_id FROM v$instance" [[metric]] context = "teq" labels = ["inst_id"] metricsdesc = { total_queues = "Total number of queues"} request = ''' SELECT inst_id, COUNT(*) AS total_queues FROM ( SELECT DISTINCT t1.inst_id, t2.queue_name FROM gv$aq_sharded_subscriber_stat t1 JOIN gv$persistent_queues t2 ON t1.queue_id = t2.queue_id ) GROUP BY inst_id ''' [[metric]] context = "teq" labels = ["inst_id"] metricsdesc = { total_subscribers = "Total number of subscribers"} request = ''' SELECT inst_id, COUNT(*) AS total_subscribers FROM ( SELECT DISTINCT inst_id, subscriber_id FROM gv$aq_sharded_subscriber_stat ) GROUP BY inst_id ''' [[metric]] context = "teq" labels = ["inst_id", "queue_name", "subscriber_name"] metricsdesc = { enqueued_msgs = "Total enqueued messages.", dequeued_msgs = "Total dequeued messages.", remained_msgs = "Total remained messages.", time_since_last_dequeue = "Time since last dequeue.", estd_time_to_drain_no_enq = "Estimated time to drain if no enqueue.", message_latency_1 = "Message latency for last 5 mins.", message_latency_2 = "Message latency for last 1 hour.", message_latency_3 = "Message latency for last 5 hours."} request = ''' SELECT DISTINCT t1.inst_id, t1.queue_id, t2.queue_name, t1.subscriber_id AS subscriber_name, t1.enqueued_msgs, t1.dequeued_msgs, t1.remained_msgs, t1.time_since_last_dequeue, t1.estd_time_to_drain_no_enq, t1.message_latency_1, t1.message_latency_2, t1.message_latency_3 FROM ( SELECT inst_id, queue_id, subscriber_id, SUM(enqueued_msgs) AS enqueued_msgs, SUM(dequeued_msgs) AS dequeued_msgs, SUM(enqueued_msgs - dequeued_msgs) AS remained_msgs, MIN(time_since_last_dequeue) AS time_since_last_dequeue, MAX(estd_time_to_drain_no_enq) AS estd_time_to_drain_no_enq, AVG(10) AS message_latency_1, AVG(20) AS message_latency_2, AVG(30) AS message_latency_3 FROM gv$aq_sharded_subscriber_stat GROUP BY queue_id, subscriber_id, inst_id ) t1 JOIN gv$persistent_queues t2 ON t1.queue_id = t2.queue_id '''
Dockerfile
FROM container-registry.oracle.com/database/observability-exporter:1.1.0 COPY txeventq-metrics.toml / ENTRYPOINT ["/oracledb_exporter", "--custom.metrics", "/txeventq-metrics.toml"]
-
ビルド
docker build -t txeventq_exporter:1.0 .
docker images REPOSITORY TAG IMAGE ID CREATED SIZE txeventq_exporter 1.0 8169e80d23bb 12 minutes ago 709MB
-
テスト実行
docker run -it --rm --name exporter -e DB_USERNAME=MONITOR -e DB_PASSWORD=Welcome12345# -e DB_CONNECT_STRING=xxxx:1521/pdb23ai.xxxx.vcn1.oraclevcn.com -p 9161:9161 txeventq_exporter:1.0
-
ローカル(http://localhost:9161/metrics) で確認
# HELP oracledb_up Whether the Oracle database server is up. # TYPE oracledb_up gauge oracledb_up 1
たくさんメトリックが取られていますが、その中の1つ、
oracledb_up
が1となっていれば、DBサーバーに接続できていることになります。
Prometheusの設定
-
作業用ディレクトリの作成
mkdir -p monitoring/prometheus cd monitoring/prometheus
-
Prometheusの設定ファイル
prometheus.yaml
作成prometheus.yamlglobal: scrape_interval: 15s scrape_timeout: 10s evaluation_interval: 15s scrape_configs: - job_name: prometheus honor_timestamps: true scrape_interval: 15s scrape_timeout: 10s metrics_path: /metrics static_configs: - targets: - localhost:9090 - job_name: oracle-exporter scrape_interval: 15s scrape_timeout: 10s metrics_path: /metrics static_configs: - targets: - exporter:9161
-
Prometheusの公式イメージのpull
docker pull prom/prometheus:v2.47.2
Grafanaの設定
-
作業用ディレクトリの作成
mkdir monitoring/grafana
-
datasource.yamlの設定
mkdir monitoring/grafana/datasources
datasource.yamlapiVersion: 1 datasources: - name: Prometheus type: prometheus url: http://prometheus:9090 isDefault: true access: proxy editable: true
-
dashboardの設定
今回はDBインスタンスの監視用とTxEventQの監視用の2つの作成済みダッシュボードを使います。dashboards
ディレクトリに、2つのjsonファイルoracledb.json
とtxeventq.json
、それから設定ファイルdashboard.yaml
を作成します。なお、oracledb.jsonはこちら、txeventq.jsonはこちらを使用します。mkdir monitoring/grafana/dashboards
dashboard.yamlapiVersion: 1 providers: - name: "Dashboard provider" orgId: 1 type: file disableDeletion: false updateIntervalSeconds: 10 allowUiUpdates: false options: path: /var/lib/grafana/dashboards foldersFromFilesStructure: true
-
Grafanaの公式イメージのpull
docker pull grafana/grafana:10.2.1
docker composeの設定
今回、実行はdocker composeを使いました。monitoring
ディレクトリに以下のdocker-compose.yml
ファイルを作成します。
services:
prometheus:
image: prom/prometheus:v2.47.2
container_name: prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yaml'
ports:
- 9090:9090
restart: unless-stopped
volumes:
- ./prometheus:/etc/prometheus
- prom_data:/prometheus
grafana:
image: grafana/grafana:10.2.1
container_name: grafana
ports:
- 3000:3000
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=grafana
volumes:
- ./grafana/datasources:/etc/grafana/provisioning/datasources
- ./grafana/dashboards:/var/lib/grafana/dashboards
- ./grafana/datasources/datasource.yaml:/etc/grafana/provisioning/datasources/datasource.yaml
- ./grafana/dashboards/dashboard.yaml:/etc/grafana/provisioning/dashboards/main.yaml
exporter:
image: txeventq_exporter:1.0
container_name: exporter
ports:
- 9161:9161
environment:
- DB_USERNAME=monitor
- DB_PASSWORD=Welcome12345#
- DB_CONNECT_STRING=xxxx.vcn1.oraclevcn.com:1521/pdb23ai.xxxx.vcn1.oraclevcn.com
volumes:
- ./exporter:/exporter
volumes:
prom_data:
※DBの接続文字列DB_CONNECT_STRING
は適宜修正してください。
最終的なディレクトリ構造はこちらになります。
[opc@devinsrd monitoring]$ tree
.
├── docker-compose.yml
├── exporter
│ ├── Dockerfile
│ └── txeventq-metrics.toml
├── grafana
│ ├── dashboards
│ │ ├── dashboard.yaml
│ │ ├── oracledb.json
│ │ └── txeventq.json
│ └── datasources
│ └── datasource.yaml
└── prometheus
└── prometheus.yaml
docker composeを実行します。
docker compose up -d
[+] Running 5/5
✔ Network monitoring_default Created 0.2s
✔ Volume "monitoring_prom_data" Created 0.0s
✔ Container prometheus Started 0.1s
✔ Container grafana Started 0.1s
✔ Container exporter Started 0.1s
ローカル(http://localhost:3000)で確認します。
ログインして、Dashboardを確認すると、Oracledb
とTxEventQ Monitor
の2つがあります。
Oracledb
の方では、以下のようなメトリックがビジュアライズされています。
- データベースのステータス
- アクティブなセッション数(Background、user)
- 実行数
- 待機時間
続いて、TxEventQの監視をしてみます。まだキューを作成していないので、以下で作成しておきます。
declare
subscriber sys.aq$_agent;
begin
-- トピック(キュー表の作成)
dbms_aqadm.create_transactional_event_queue(
queue_name => 'my_topic',
multiple_consumers => true -- pub/subトピックの作成
);
-- トピックの開始
dbms_aqadm.start_queue(
queue_name => 'my_topic'
);
-- サブスクライバの登録
dbms_aqadm.add_subscriber(
queue_name => 'my_topic',
subscriber => sys.aq$_agent(
'my_subscriber', -- サブスクライバ名
null, -- 通知に使用されるメールアドレス
0 -- プロトコル
),
rule => 'correlation = ''my_subscriber'''
);
end;
/
作成に失敗する場合は、権限を確認してください。なお、dbms_aqadm.create_transactional_event_queue
はOracle Database 21c、23aiでのみ使用可能です。
キュー表を作成できたので、以下でキュー表にメッセージを送信(エンキュー)してみます。
declare
enqueue_options dbms_aq.enqueue_options_t;
message_properties dbms_aq.message_properties_t;
message_handle raw(16);
message SYS.AQ$_JMS_TEXT_MESSAGE;
begin
-- メッセージ・ペイロードの作成
message := SYS.AQ$_JMS_TEXT_MESSAGE.construct;
message.set_text('{"orderid": 12345, "username": "Jessica Smith"}');
-- コンシューマ名の登録
message_properties.correlation := 'my_subscriber';
-- メッセージのエンキュー
dbms_aq.enqueue(
queue_name => 'my_topic',
enqueue_options => enqueue_options,
message_properties => message_properties,
payload => message,
msgid => message_handle);
-- トランザクションのコミット
commit;
end;
/
エンキューができたので、Grafana側で確認します。DashboardのTxEventQ Monitor
を確認してみます。
以下のようなメトリックが確認できます。
- TxEventQのステータス
- キュー表(トピック)の数
- サブスクライバの数
- エンキュー/デキュー率(性能指標)
- エンキュー/デキューされたメッセージ数
また、以下のように各トピックやサブスクライバに限定したメトリックも取得できます。
おわりに
今回はOracle Transactional Event Queuesの監視を、Oracle Database Observability Exporter + Prometheus + Grafanaで行ってみました。Oracle Databaseの監視には、Enterprise Manager(EM)や、クラウドではDatabase Managementといったサービスを使用できますが、特定のキューに関するメトリック監視を行う場合には、このようなOSSツールを組み合わせて行うことができます。