0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Prometheus + Grafana で Oracle Transactional Event Queues の監視を行う

Last updated at Posted at 2023-11-15

はじめに

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を指定します。

ドキュメントはこちらです。

image.png

環境情報

監視フレームワークを構築する仮想マシンの情報

  • シェイプ: 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を作成しています。

  1. SYSでユーザー作成
    SELECT_CATALOG_ROLEを付与することで、Prometheusで収集するメトリックのディレクトリなどの参照権限が与えられます。

    create user monitor identified by Welcome12345#;
    grant connect, resource, DBA, SELECT_CATALOG_ROLE, unlimited tablespace to monitor; 
    
  2. 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;
    
  3. 仮想マシンから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)のイメージもあります。

  1. 作業用ディレクトリの作成

    mkdir -p monitoring/exporter
    cd monitoring/exporter
    
  2. カスタムメトリックの設定ファイル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"]
    
  3. ビルド

    docker build -t txeventq_exporter:1.0 .
    
    docker images
    REPOSITORY          TAG       IMAGE ID       CREATED          SIZE
    txeventq_exporter   1.0       8169e80d23bb   12 minutes ago   709MB
    
  4. テスト実行

    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
    
  5. ローカル(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の設定

  1. 作業用ディレクトリの作成

    mkdir -p monitoring/prometheus
    cd monitoring/prometheus
    
  2. Prometheusの設定ファイルprometheus.yaml作成

    prometheus.yaml
    global:
      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
    
  3. Prometheusの公式イメージのpull

    docker pull prom/prometheus:v2.47.2
    

Grafanaの設定

  1. 作業用ディレクトリの作成

    mkdir monitoring/grafana
    
  2. datasource.yamlの設定

    mkdir monitoring/grafana/datasources
    
    datasource.yaml
    apiVersion: 1
    
    datasources:
    - name: Prometheus
      type: prometheus
      url: http://prometheus:9090
      isDefault: true
      access: proxy
      editable: true
    
  3. dashboardの設定
    今回はDBインスタンスの監視用とTxEventQの監視用の2つの作成済みダッシュボードを使います。dashboardsディレクトリに、2つのjsonファイルoracledb.jsontxeventq.json、それから設定ファイルdashboard.yamlを作成します。なお、oracledb.jsonはこちら、txeventq.jsonはこちらを使用します。

    mkdir monitoring/grafana/dashboards
    
    dashboard.yaml
    apiVersion: 1
    
    providers:
      - name: "Dashboard provider"
        orgId: 1
        type: file
        disableDeletion: false
        updateIntervalSeconds: 10
        allowUiUpdates: false
        options:
          path: /var/lib/grafana/dashboards
          foldersFromFilesStructure: true
    
  4. Grafanaの公式イメージのpull

    docker pull grafana/grafana:10.2.1
    

docker composeの設定

今回、実行はdocker composeを使いました。monitoringディレクトリに以下のdocker-compose.ymlファイルを作成します。

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)で確認します。

image.png

ログインして、Dashboardを確認すると、OracledbTxEventQ Monitorの2つがあります。
image.png
Oracledbの方では、以下のようなメトリックがビジュアライズされています。

  • データベースのステータス
  • アクティブなセッション数(Background、user)
  • 実行数
  • 待機時間

image.png

続いて、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のステータス
  • キュー表(トピック)の数
  • サブスクライバの数
  • エンキュー/デキュー率(性能指標)
  • エンキュー/デキューされたメッセージ数

image.png

また、以下のように各トピックやサブスクライバに限定したメトリックも取得できます。

image.png

おわりに

今回はOracle Transactional Event Queuesの監視を、Oracle Database Observability Exporter + Prometheus + Grafanaで行ってみました。Oracle Databaseの監視には、Enterprise Manager(EM)や、クラウドではDatabase Managementといったサービスを使用できますが、特定のキューに関するメトリック監視を行う場合には、このようなOSSツールを組み合わせて行うことができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?