TimescaleDB による Zabbix の性能改善

Zabbix では、データベースとして PostgreSQL や MySQL などに対応していますが、バージョン 4.4 から TimescaleDB が正式にサポートされるようになりました。

TimescaleDB は、時系列データベースの機能を PostgreSQL に追加する拡張モジュールで、自動的にデータを時間単位で分割された小さなテーブルに格納できます。Zabbix のデータベースに TimescaleDB を使用することで、性能向上、ディスク使用量の削減などの効果が期待できます。

本記事では、 Zabbix で TimescaleDB を利用するメリット、セットアップ方法、利用上の注意点について紹介します。

 

TimescaleDB のサポート

TimescaleDB は Zabbix 4.4 から正式にサポートされるようになりました。

TimescaleDB では、時系列データベースの機能を適用した親テーブルをハイパーテーブルと呼び、データは内部的にチャンクと呼ばれる小さなテーブルに分割されます。

具体的には以下のヒストリ・トレンドデータを格納するテーブルをハイパーテーブルに変換し、日付ごとにチャンクが自動的に作成されます。

  • history
  • history_uint
  • history_log
  • history_text
  • history_str
  • trends
  • trends_uint

また、Zabbix 5.0 以降では、古くなったチャンクを圧縮し、ファイルサイズを縮小することも可能です。

Zabbix で TimescaleDB を利用するメリット

Zabbix で TimescaleDB を利用することで、次のようなメリットが得られます。

Housekeeper による削除処理の負荷軽減

Housekeeper とは、保存期間を超えたヒストリ・トレンドやイベント、アラートなどのデータを定期的に削除する機能です。

Housekeeper の削除処理は時間範囲で絞り込んで、1行ずつ DELETE するので、削除するレコード数が多くなればなるほど時間がかかり、データベースへの負荷が高まります。データベースの負荷上昇によって、データの読み取り/書き込みが遅くなり、監視の遅延や誤検知など監視全体に影響を与える可能性があります。

一方、Zabbix で TimescaleDB を利用すると、1行ずつ削除する DELETE に対して、TimescaleDB はチャンク単位でデータを削除するため、非常に高速です。これまでの Housekeeper の削除処理による高負荷問題を解決できます。

NVPS が 300 程度、同様な監視設定の Zabbix サーバで、素の PostgreSQL と TimescaleDB を利用した場合の Housekeeper の負荷を検証してみました。Zabbix サーバとデータベースは同一サーバ上で動作し、環境情報は以下の通りです。

  • OS: RHEL 8.5 (VirtualBox 上の VM)
  • CPU: 2vCPUs
  • メモリ: 4GB

PostgreSQL の場合は、Housekeeper プロセスのビジー率が 100% まで上がる場合がありました。PostgreSQL と比べて、TimescaleDB の場合は最大でも 20% 以下で大幅に軽減されていることがわかります。
※今回の検証で以下の結果を得ましたが、削除するイベントやアラートなどの量によって Housekeeper プロセスのビジー率が変動します。

PostgreSQL を利用した場合の Housekeeper プロセスのビジー率

 

TimescaleDB を利用した場合の Housekeeper プロセスのビジー率

不要領域発生の抑止

PostgreSQL は追記型アーキテクチャを採用しているため、DELETE を実行しても PostgreSQL が使用するディスク領域サイズは減りません。DELETE はデータを削減することはできますが、不要領域が発生します。不要領域を回収して再利用可能な状態にするには VACUUM が必要になります。

Zabbix で TimescaleDB を利用すると、チャンクごと削除するため、DELETE による不要領域の発生を抑止でき、不要領域を回収するための VACUUM 処理によるオーバーヘッドも削減できます。

圧縮によるディスク領域の節約

Zabbix で長期運用すると、収集した監視データによって DB のサイズが肥大化していきます。TimescaleDB の圧縮機能を利用し、一定期間経過したヒストリ・トレンドデータを自動的に圧縮できます。

10GB の history テーブルと history_uint テーブルにおいて、7日を超過したデータを圧縮すると、圧縮前に比べて、ディスク領域はそれぞれ 89% と 95% 削減できました。history_loghistory_texthistory_str テーブルのレコードは可変長レコードであり、レコードのサイズによって圧縮率が変動します。

テーブル 圧縮前 圧縮後 圧縮率
history 10GB 1175MB 89%
history_uint 10GB 466MB 95%

書き込み性能の向上

TimescaleDB では、チャンクごとにインデックスを構築するため、インデックスのサイズが小さくなります。また、TimescaleDB は最新のチャンクのデータとインデックスをメモリに保存するため、データ挿入時のインデックスの更新が高速になり、書き込み性能が向上します。

TimescaleDB のインストール・設定

この節では、Zabbix のデータベースとして TimescaleDB を利用するためのインストール・設定手順を説明します。

検証環境

今回は以下の構成でインストールを行います。各ソフトウェアは 2022 年 5 月時点での最新バージョンを利用しています。

  • OS: RHEL 8.5
  • Zabbix 6.0.3
  • PostgreSQL 14.2
  • TimescaleDB 2.6.1

TimescaleDB は 2022 年 5 月時点で以下のバージョンがメンテナンスされており、それぞれ対応する PostgreSQL のバージョンは以下の通りです。

TimescaleDB バージョン 対応 PostgreSQL バージョン
2.5 以降 12、13、14
2.4 12、13
2.1~2.3 12、13
2.0 11、12
1.7 9.6、10、11、12

前提条件

TimescaleDB をインストールする前に、Zabbix サーバと PostgreSQL がすでにインストールされており、データベースの初期設定、データベーススキーマと初期データの投入が完了していることが前提となります。

まだ完了していない場合は、こちらのインストール手順を参照してください。

TimescaleDB のインストール

本記事では、RHEL 8 上で構築した PostgreSQL サーバに TimescaleDB をインストールします。他のプラットフォーム向けのインストール方法については TimescaleDB のドキュメントを参照してください。

TimescaleDB の Yum リポジトリを登録します。

$ sudo tee /etc/yum.repos.d/timescale_timescaledb.repo <<EOL
[timescale_timescaledb]
name=timescale_timescaledb
baseurl=https://packagecloud.io/timescale/timescaledb/el/$(rpm -E %{rhel})/\$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/timescale/timescaledb/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
EOL

TimescaleDB の RPM パッケージをインストールします。
※ PostgreSQL xx がインストールされている場合は timescaledb-2-postgresql-xx を指定します。

$ sudo dnf install timescaledb-2-postgresql-14

TimescaleDB の設定

PostgreSQL で TimescaleDB を利用するための設定を行います。

PostgreSQL の設定ファイル postgresql.conf を直接編集しても良いですが、ここでは、環境のスペックに応じて対話的に PostgreSQL パラメータのチューニングを行う timescaledb-tune コマンドを使います。

--pg-config オプションには pg_config コマンドのパスを指定します。その他のオプションについては timescaledb-tune --help で確認できます。
以下のコマンドを実行すると、次々と質問されますが、基本的には y を入力していけば良いです。最後に設定が postgresql.conf に書き込まれます。環境によって、Zabbix で使用するには max_connections の推奨値が小さすぎる可能性があるので、ここでは明示的に max_connections の値を設定します。

$ sudo timescaledb-tune --pg-config=/usr/pgsql-14/bin/pg_config --max-conns=100

上記コマンドによって、TimescaleDB が shared_preload_libraries にロードされ、PostgreSQL のパラメータが環境に応じた適切な値に設定されます。

設定変更を反映するため、PostgreSQL のサービスを再起動します。

$ sudo systemctl restart postgresql-14

TimesaceleDB 拡張の作成

Zabbix サーバが利用する zabbix データベースに TimesaceleDB 拡張をインストールします。

$ echo "CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;" | sudo -u postgres psql zabbix

/usr/share/doc/zabbix-sql-scripts/postgresql/ にある TimescaleDB のスキーマ作成スクリプト timescaledb.sql を実行します。

$ cat /usr/share/doc/zabbix-sql-scripts/postgresql/timescaledb.sql | sudo -u zabbix psql zabbix

上記コマンドに指定した timescaledb.sql スクリプトの中身を確認してみましょう。

(以下、実行不要)
$ cat /usr/share/doc/zabbix-sql-scripts/postgresql/timescaledb.sql
(省略)
# ヒストリ・トレンドテーブルを1日ごとにチャンクを作成するハイパーテーブルに変換。
# ヒストリ・トレンドテーブルに既存のデータがある場合には、既存のデータの移行が行われる。
PERFORM create_hypertable('history', 'clock', chunk_time_interval => 86400, migrate_data => true);
PERFORM create_hypertable('history_uint', 'clock', chunk_time_interval => 86400, migrate_data => true);
PERFORM create_hypertable('history_log', 'clock', chunk_time_interval => 86400, migrate_data => true);
PERFORM create_hypertable('history_text', 'clock', chunk_time_interval => 86400, migrate_data => true);
PERFORM create_hypertable('history_str', 'clock', chunk_time_interval => 86400, migrate_data => true);
PERFORM create_hypertable('trends', 'clock', chunk_time_interval => 2592000, migrate_data => true);
PERFORM create_hypertable('trends_uint', 'clock', chunk_time_interval => 2592000, migrate_data => true);

# [管理] -> [一般設定] -> [データの保存期間]ページで「アイテムのヒストリ/トレンドの保存期間設定を上書き」オプションを有効にする。
UPDATE config SET db_extension='timescaledb',hk_history_global=1,hk_trends_global=1;

# 圧縮機能を有効にする。デフォルトでは7日間を超えたデータは自動的に圧縮される。
UPDATE config SET compression_status=1,compress_older='7d';

Zabbix サーバのデータベースにアクセスし、history テーブルを確認してみます。

$ psql -U zabbix
Password for user zabbix: 
psql (14.2)
Type "help" for help.

zabbix=> \d+ history
                                                    Table "public.history"
 Column |       Type       | Collation | Nullable |        Default        | Storage | Compression | Stats target | Description 
--------+------------------+-----------+----------+-----------------------+---------+-------------+--------------+-------------
 itemid | bigint           |           | not null |                       | plain   |             |              | 
 clock  | integer          |           | not null | 0                     | plain   |             |              | 
 value  | double precision |           | not null | '0'::double precision | plain   |             |              | 
 ns     | integer          |           | not null | 0                     | plain   |             |              | 
Indexes:
    "history_pkey" PRIMARY KEY, btree (itemid, clock, ns)
    "history_clock_idx" btree (clock DESC)
Triggers:
    ts_insert_blocker BEFORE INSERT ON history FOR EACH ROW EXECUTE FUNCTION _timescaledb_internal.insert_blocker()
Child tables: _timescaledb_internal._hyper_1_1_chunk
Access method: heap

history テーブルがハイパーテーブルに変換されており、チャンク (Child tables) が1つ存在することがわかります。

ヒストリ・トレンドテーブルデータの保存期間や圧縮に関する詳細設定は Web インターフェースの [管理] -> [一般設定] -> [データの保存期間] ページにて設定できます。

timescaledb.sql スクリプトを実行すると、以下のような設定となります。

 

「アイテムのヒストリの保存期間設定を上書き」と「アイテムのトレンドの保存期間設定を上書き」にチェックが付いている状態になります。この設定により、ヒストリ・トレンドテーブルにて Housekeeper によるチャンクごとの削除処理が有効になります。また、これらにチェックが入っていると、各アイテムで設定したヒストリとトレンドの保存期間を上書きし、すべてのアイテムで共通のヒストリとトレンドの保存期間を設定できます。

ヒストリとトレンドが圧縮されるまでの期間は「次よりも古いものはレコードを圧縮」にて設定できます。7日以上の値を設定する必要があります。

TimescaleDB 利用上の注意点

本節では、Zabbix で TimescaleDB を利用する際の注意点を記載します。

  • TimescaleDB は Zabbix プロキシではサポートされていません。
  • パーティション化された Housekeeper 処理を利用する場合は、Zabbix サーバで共通のヒストリ・トレンドの保存期間を使用することになるので、アイテム別にヒストリ・トレンドの保存期間を設定できません。
  • TimescaleDB の圧縮を利用するには、以下の条件が前提となります。
    • Zabbix 5.0 以降
    • PostgreSQL 10.2 以降
    • TimescaleDB 1.5 以降
  • 圧縮したヒストリ・トレンドテーブルのデータは参照処理 (SELECT) はできますが、更新処理 (INSERT、UPDATE、DELETE) はできません。また、圧縮した ヒストリ・トレンドテーブルのスキーマ変更はできません。
  • PostgreSQL から TimescaleDB に移行する場合、既存のヒストリ・トレンドテーブルのデータ量が多ければ多いほど、移行に時間がかかります。データの移行を行う前に、サーバに十分な空き領域があることを確認してください。少なくともヒストリ・トレンドテーブルとインデックスの合計サイズの 1.5 倍の空き領域が必要です。また、移行期間中に、Zabbix サーバと Zabbix フロントエンドを停止する必要があります。

おわりに

今回は、Zabbix サーバのバックエンドデータベースとして時系列データベース TimescaleDB を利用する際のメリットや注意点、インストール手順について紹介しました。

TimescaleDB を導入することによって、Housekeeper による負荷の軽減や書き込み性能の向上、ディスク使用量の削減などのメリットを得られます。

既存の PostgreSQL から容易に移行でき、これまで PostgreSQL で利用していたバックアップ、リストアなどの運用方式は TimescaleDB でも利用できるので、PostgreSQL を利用していて性能やディスク使用量を改善したい場合は、TimescaleDB を使うことを検討してみてはいかがでしょうか。