使用Prometheus + Grafana监控Oracle Transactional Event Queues

首先

在Oracle Database 23c(21c)中,有两个免费可用的功能,一个是功能强大的消息队列系统Advanced Queuing(AQ),另一个是可以实现高吞吐量消息交换的Transactional Event Queues(TxEventQ)。本次我们想要构建一个用于监控性能的TxEventQ Monitor系统来使用这些功能。有关TxEventQ的详细信息,请参考此处的文档或以下的Qiita文章。

 

组件包括以下三个部分。

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数据库

    Oracle Database 23.3(OCIのBaseDB)

创建监视用数据库用户

这次我们在OCI上创建了一个23c(23.3)的BaseDB,并在其上面创建了一个名为pdb23c的PDB。我们将其作为监视对象的PDB,并在其中创建了一个名为monitor的数据库用户用于监视。

    1. 使用SYS创建用户

 

    1. 通过授予SELECT_CATALOG_ROLE角色,您可以获得在Prometheus中收集度量的目录等参考权限。

 

    1. create user monitor identified by Welcome12345#;

 

    1. 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连接到pdb23c进行监测(简易连接)
sqlplus monitor/Welcome12345#@xxxx:1521/pdb23c.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.

上次成功登录时间: Tue Nov 14 2023 06:26:23 +00:00

已连接到:
Oracle Database 23c Enterprise Edition Release 23.0.0.0.0 – Production
Version 23.3.0.23.09

Oracle数据库可观察性导出器的设置。

Oracle数据库可观测性导出程序可使用可从Oracle容器注册表下载的容器映像在本地容器中使用。不需要进行身份验证或许可证明/批准。

顺便说一下,这个Oracle容器注册表中还包含了Autonomous Database的免费映像以及适用于微服务的Oracle交易管理器(MicroTx)的映像。

    1. 创建作业目录

 

    1. mkdir -p monitoring/exporter

 

    1. cd monitoring/exporter

创建自定义指标配置文件txeventq-metrics.toml
这次除了默认的指标之外,我们还想收集TxEventQ的指标,所以我们需要创建一个toml文件,并使用该文件来创建Docker镜像。

txeventq-metrics.toml
[[metric]]
context = “ownership”
metricsdesc = { inst_id = “当前队列的所有者实例ID。” }
request = ”’
SELECT
inst_id
FROM
gv$persistent_queues
WHERE
ROWNUM < 2
”’
[[metric]]
context = “teq”
metricsdesc = { curr_inst_id = “当前实例的ID” }
request = “SELECT instance_number AS curr_inst_id FROM v$instance”

[[metric]]
context = “teq”
labels = [“inst_id”]
metricsdesc = { total_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 = “订阅者的总数” }
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 = “入队消息的总数。”, dequeued_msgs = “出队消息的总数。”, remained_msgs = “剩余消息的总数。”, time_since_last_dequeue = “自上次出队以来的时间。”, estd_time_to_drain_no_enq = “如果没有入队,排空的预计时间。”, message_latency_1 = “过去5分钟的消息延迟。”, message_latency_2 = “过去1小时的消息延迟。”, message_latency_3 = “过去5个小时的消息延迟。” }
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/pdb23c.xxxx.vcn1.oraclevcn.com -p 9161:9161 txeventq_exporter:1.0

在本地(http://localhost:9161/metrics)中确认
# HELP oracledb_up Oracle数据库服务器是否运行。
# TYPE oracledb_up gauge
oracledb_up 1

有许多指标被记录下来,但其中一个指标oracledb_up的值为1,说明已成功连接到数据库服务器。

普罗米修斯的设置

    1. 创建作业用目录

 

    1. mkdir -p monitoring/prometheus

 

    1. cd monitoring/prometheus

创建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

拉取Prometheus官方镜像
docker pull prom/prometheus:v2.47.2

Grafana的设置

    1. 创建作业目录

 

    1. mkdir monitoring/grafana

配置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

配置dashboard
本次将使用两个预先创建的仪表板进行DB实例和TxEventQ的监视。在dashboards目录下,创建两个json文件oracledb.json和txeventq.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

拉取Grafana官方镜像
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/pdb23c.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
image.png
    • データベースのステータス

 

    • アクティブなセッション数(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和23c。

我已经创建了一个队列表,接下来将尝试向队列表发送消息(入队)。

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;
/

因为我们已经完成了Enqueue,所以我会在Grafana上进行确认。我会查看仪表板上的TxEventQ Monitor。
你可以通过以下指标进行确认。

    • TxEventQのステータス

 

    • キュー表(トピック)の数

 

    • サブスクライバの数

 

    • エンキュー/デキュー率(性能指標)

 

    エンキュー/デキューされたメッセージ数
image.png

另外,您还可以获取以下针对每个主题或订阅者的特定指标。

image.png

最后一句

本次我们尝试使用Oracle Database Observability Exporter + Prometheus + Grafana来监控Oracle Transactional Event Queues。虽然可以使用Enterprise Manager(EM)或云端的Database Management等服务来监控Oracle Database,但如果要对特定队列进行指标监控,则可以结合这些开源工具来实现。

bannerAds