TECH BLOG
技術ブログ
  • 2020-11-05 PostgreSQLPostgreSQL チューニング全文検索

    PGroongaの設定値チューニング

はじめに

みなさん、こんにちは。インサイトの加藤です。
久しぶりのブログ記事となりましたが、今回はPGroongaの設定値とその影響、
内部動作について詳しい情報がWEB上になかったので、それについてのブログを書かせていただきます。

注意点

今回のブログ記事内容は、LinuxサーバーにてPostgreSQLを運用する前提となっております。

PGroongaの内部動作について

公式ページにもある通り、PGroongaはGroongaを使った新しいインデックスアクセスメソッドを提供します。
内部的にはPostgreSQLのインデックスとしてGroongaのテーブルを作成し、そのインデックスを使用した参照処理があった場合、Groonga内で検索をしてくれるというものとなっております。
そのためRecheckなしで検索することが可能であり、ヒット数が多くなる場合でも処理が高速です。

Recheckとは

ハッシュインデックスやpg_bigmの検索でマッチしたレコードに対し、検索結果に問題がないか再度シーケンシャルサーチをすることです。
ヒット数が多くなるほどこの処理は遅くなり、全文検索のボトルネックになるケースが多いです。

PGroongaの設定値

PGroongaの設定として、PostgreSQLの設定ファイルに設定するものとインデックス作成時に設定するものがございますが、今回はチューニングと題しておりますので、PGroongaのパフォーマンスに関するPostgreSQLの設定パラメータのご紹介と最適値についてご説明させていただきます。
ちなみに設定値の変更については、PostgreSQLの再起動ではなく、設定ファイルの再読み込みで適用が可能です。

pgroonga.enable_wal

PGroongaはPostgreSQL 9.6以降で使う場合はWALをサポートしています。
PostgreSQL 9.5以前で使う場合、もしくは、レプリケーション機能を使用していない場合は「pgroonga.enable_wal」パラメーターを設定しても意味はありません。
WAL機能とはいってもPostgreSQL標準のWAL機能ではなく、Msgpackを利用したレプリケーション用機能であるからです。
そのため、クラッシュセーフではないことに注意してください。
WALサポートを有効にすると更新性能が落ちます。これは追加のディスク書き込みが必要になるからです。
デフォルト値は「off」です。
レプリケーション機能を使用しない場合は「off」を推奨します。

pgroonga.lock_timeout

ロックのタイムアウトを制御します。
PGroongaはロックを獲得するまで、1ミリ秒おきに指定したタイムアウト回数だけロックを獲得しようとします。
デフォルト値は「10000000」です。これは、PGroongaはデフォルトではロックを獲得するまで約2.7時間ロック獲得を試みるということです。
ロックの獲得を長く複数回に亘って行うと、DBの全体的なパフォーマンスダウンに繋がるため、システム内で許容できる時間を適切に設定します。
ロックが起きる例としては、DML実行先オブジェクトに対し、「データの更新」「インデックスの作成」「VACUUM FULL」が実行されている場合等が挙げられます。

pgroonga.match_escalation_threshold

いつマッチエスカレーションが実行されるかを制御します。
マッチエスカレーションとは自動で条件のゆるい検索をする機能のことです。ヒット数が「pgroonga.match_escalation_threshold」パラメーターで指定した閾値よりも小さい時、自動で条件のゆるい検索をします。
「-1」を指定することでマッチエスカレーションを無効にできます。
デフォルト値は「0」です。これは1件もヒットしない時は自動で条件のゆるい検索を再度行うという意味です。
詳細な検証が必要ですが、Groongaのエスカレーション動作によると「完全一致検索」→「非分かち書き検索」→「部分一致検索」の順に行うようです。
内部的に複数回の検索をするため、高速化するという観点では「-1」を推奨します。

Groonga関連のチューニング

先ほどご説明させていただいた通り、PGroongaは内部的にGroongaを利用しています。
そのため、Groongaを高速化が大きくPGroongaの性能を左右することになります。
とはいってもGroongaに直接手を加えるわけではなく、Linux上でGroonga等を使用した時の扱いを変更するチューニングとなりますので、Linux上の様々なプロセスに影響を与えることとなるため、綿密な検証が必要です。

1プロセスで開ける最大ファイル数

サーバーによっては、各ユーザー毎の設定として1プロセスで開ける最大ファイル数を設定している場合があります。
その設定の値は以下のコマンドを実行することで確認ができます。

$ ulimit -n

この設定の制限を緩和することでPostgreSQLのプロセスを円滑に実行することができる場合が多いため、以下のようなコマンドを実行することを推奨します。

# echo -e "postgres soft nofile 10000\npostgres hard nofile 10000" > /etc/security/limits.d/groonga.conf

この設定はGroongaサービスが再起動したあと、あるいは、 postgresユーザーがログインし直したときに反映されます。

メモリ関連

下記内容を「/etc/sysctl.d/groonga.conf」に置き、
設定した内容はシステムを再起動するか、次のコマンドを実行することで反映されます。

# sysctl -p
vm.overcommit_memory

常に高速なGroongaの処理を行いたい場合は、Linuxの「vm.overcommit_memory」カーネルパラメータを「1」に設定します。
これによりPostgreSQL自体の高速化も見込めますが、OOM killerが頻繁に起きてしまう可能性もあるため、適宜オーバーコミットを許容する「0」をカーネルパラメータに設定すべきです。
ちなみに、「2」を設定することでオーバーコミット機能を無効化し、OOM killerの発生頻度をかなり軽減することができます。

vm.max_map_count

Linuxの「vm.max_map_count」カーネルパラメーターの値を増やすことで16GiB以上のサイズのGroongaデータベースを扱うことができます。
これはPostgreSQLのデータベースの大きさとは異なることに注意してください。
以下のコマンドでGroongaデータベースのサイズを計測できます。

ls -la $PGDATA/base/データベースID/pgrn* | awk '{ total += $5 }; END { print total }'

このカーネルパラメーターのデフォルト値は 65530 か 65536 です。
Groongaは一度に256KiBずつメモリー上にマップします。
データベースが16GiBよりも大きい場合、Groongaはこの制限に達します。( 256KiB × 65536 = 16GiB )
例えば、 65536 * 2 = 131072 まで増やすと32GiBくらいのデータベースを扱うことができます。

まとめ

いかがでしたでしょうか。
PGroongaは高速かつ便利である反面、前回パフォーマンス比較をした同じ全文検索モジュールであるpg_bigm以上に考慮しなければならない点が多くあることがお分かりになったかと思います。
全文検索だけではなく、配列用、JSON用、類似文書用など様々な用途のインデックスを作成することができ、どれに対しても検索が非常に高速です。
それによりPGroongaのニーズが高まってきているため、これを機により深くPGroongaについて今後も触れていきたいと思っております。
今後もどうぞよろしくお願いいたします。

CATEGORY

ARCHIVE

PostgreSQLに関するご相談は
株式会社インサイトまで
お気軽にお問い合わせください。

CONTACT