5.12. インメモリキャッシュ

Pgpool-IIの全てのモードでインメモリクエリキャッシュを利用することができます。 クエリキャッシュはSELECTの結果を保管しておいて再利用するものです。 テーブルの更新によりキャッシュが古くなると、自動的にそのテーブルに関連したキャッシュが削除される(memqcache_auto_cache_invalidationがonの場合。デフォルトでこの項目はonになっています)のでPgpool-IIの再起動の必要はありません。

注意: 基本的に以下のSELECTはキャッシュされません。

    immutableでない関数を含むSELECT
    TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEを返す関数を使っているSELECT
    TIMESTAMP WITH TIMEZONE、TIME WITH TIMEZONEへのキャストを含むSELECT
    SQLValueFunction (CURRENT_TIME, CURRENT_USERなど)を含むSELECT
    一時テーブル、unloggedテーブルを使ったSELECT
    検索結果が memqcache_maxcache を越えるようなSELECT
    SELECT FOR SHARE/UPDATE
    /*NO QUERY CACHE*/コメントで始まるSELECT
    システムカタログを使用しているSELECT
    TABLESAMPLEを使っているSELECT
    行セキュリティが設定されているテーブルを使っているSELECT
   

ただし、VIEWと unloggedテーブルは、cache_safe_memqcache_table_list に記載することでキャッシュされます。

注意: 以下のコマンドはクエリキャッシュとデータベース内容の整合性を失わせる可能性があるので、実行されるとクエリキャッシュをすべて削除します。

    ALTER DATABASE
    ALTER ROLE
    ALTER TABLE
    REVOKE
   

また、SET ROLE、SET SESSION AUTHORIZATIONが実行されると、そのセッション内ではクエリキャッシュは使用されず、また新たにクエリキャッシュが作成されることもありません。 Pgpool-IIはセッションユーザが異なるとクエリキャッシュを違うものと見なしますが、一方でPostgreSQLのアクセス権管理はカレントユーザ(current user)を基準に行っており、これらのコマンドはクエリキャッシュとPostgreSQLのアクセス権管理の間の整合性を損なう可能性があるからです。 ただし、更新クエリによるクエリキャッシュの削除はこれらのコマンドが使われていない場合と同様に行われます。

インメモリクエリキャッシュは、ユーザ名、データベース名、SELECT文(拡張問い合わせの場合は更にバインドパラメータ)と 検索結果をペアで記録します。 ユーザ名、データベース名、バインドパラメータが同じSELECT文が発行された場合に、Pgpool-IIはキャッシュから結果を返します。 SQLの解析もPostgreSQLへのアクセスも行われないため、インメモリキャッシュからの結果の提供は非常に高速です。

反面、キャッシュをストアするオーバヘッドが生じるので、通常の方法より遅くなる場合も有ります。 また、あるテーブルが更新された場合、Pgpool-IIは自動的にそのテーブルに関係する全てのキャッシュを削除します。 そのため、更新が多いシステムではパフォーマンスが悪くなります。 キャッシュのヒット率(SHOW POOL_CACHEを使って確認できます)が70%以下の場合は、インメモリクエリキャッシュを無効にしたほうが良いかもしれません。

クエリキャッシュにSELECT結果が登録されるのは、基本的にSELECTが正常終了したときです。 明示的なトランザクションを実行中なら、そのトランザクションがコミットされるまではクエリキャッシュにはSELECT結果は登録されません。 また、拡張問い合わせでは、クラスタリングモードにより、キャッシュの登録されるタイミングが異なることに注意してください。 ストリーミングレプリケーションモードロジカルレプリケーションモードでは、Syncメッセージがフロントエンドから送られ、その応答(Ready for queryメッセージ)がバックエンドから返ってきたタイミングになります。 ですから、

   Parse (SELECT 1)
   Bind (SELECT 1)
   Execute (SELECT 1)
   Parse (SELECT 1)
   Bind (SELECT 1)
   Execute (SELECT 1)
   Sync
  

という順でコマンドがフロントエンドから送信されても、2回目のExecute (SELECT 1)ではクエリキャッシュは利用されません。 一方それ以外のクラスタリングモードでは、1回目のExecute (SELECT 1)の結果がクエリキャッシュに登録されるので、2回目のExecute (SELECT 1)ではクエリキャッシュが利用されます。

5.12.1. インメモリクエリキャッシュを有効にする

memory_cache_enabled (boolean)

onにするとメモリキャッシュが有効になります。 デフォルトはoffです。

このパラメータはサーバ起動時にのみ設定可能です。

注意: enable_shared_relcacheが有効の場合、クエリキャッシュはリレーションキャッシュでも使用されます。 その上、たとえmemory_cache_enabledパラメータがオフに設定されていたとしても、クエリキャッシュは使用されます。 リレーションキャッシュの詳細は項5.15を参照してください。

5.12.2. キャッシュストレージの選択

memqcache_method (string)

キャッシュに用いるストレージのタイプを指定します。 このパラメータで有効な全ての値のリストを以下の表に示します。

表 5-10. Memcache method options

説明
'shmem'共有メモリを使用
'memcached'memcachedを使用

一般的にshmemはネットワークアクセスが不要なため、memcachedより高速です。 しかし、shmemでは、memqcache_total_sizeはシステムで決まっている共有メモリサイズの合計に制限されます。 最近のLinuxシステムでは、そのサイズは十分大きいのですが、他のシステムでは制限値が小さいかもしれません。 この場合は共有メモリサイズの最大値のシステム設定を変更する必要があるでしょう。 PostgreSQLのドキュメントに共有メモリに関する良い記述があります。

どちらのmemqcache_methodを使ったらよいかわからない場合は、まずshmemを試してください。

デフォルトは'shmem'です。

このパラメータはサーバ起動時にのみ設定可能です。

5.12.3. 共通設定

以下はshmemmemcachedの両タイプのクエリキャッシュで有効なパラメータです。

memqcache_expire (integer)

クエリキャッシュの寿命を秒単位で設定します。 デフォルト0で、キャッシュの期限はなくなり、関連テーブルが更新されるまではキャッシュが有効になります。

このパラメータはサーバ起動時にのみ設定可能です。

注意: memqcache_expirememqcache_auto_cache_invalidationは互いに独立です。

memqcache_auto_cache_invalidation (boolean)

onに設定した場合、更新されたテーブルに関連するキャッシュを自動で削除します。 offならばキャッシュは削除されません。

デフォルト値はonです。

注意: memqcache_auto_cache_invalidationmemqcache_expireは互いに独立です。

このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。

memqcache_maxcache (integer)

キャッシュされるSELECTクエリ結果の最大サイズをバイト数で指定します。 この値より大きいサイズのデータの結果はPgpool-IIにキャッシュされません。 サイズの制約によりデータのキャッシュができなかった場合、以下のメッセージが表示されます。

       LOG:   pid 13756: pool_add_temp_query_cache: data size exceeds memqcache_maxcache. current:4095 requested:111 memq_maxcache:4096
      

注意: 共有メモリによるクエリキャッシュ('shmem')の場合は、memqcache_maxcachememqcache_cache_block_sizeを超えないように、'memcached'を使用する場合は、slabのサイズ(デフォルトで1MB)を超えないようにしてください。

このパラメータはサーバ起動時にのみ設定可能です。

cache_safe_memqcache_table_list (string)

SELECT結果がPgpool-IIにキャッシュされるべきテーブル名のリストをカンマ区切りで指定します。 このパラメータは、VIEWとunloggedテーブルにのみ適用されます。 通常のテーブルは、cache_unsafe_memqcache_table_listに記載されていない限りキャッシュされます。

テーブル名のマッチングには正規表現も利用できます (指定した各表現に ^ と $ をつけた形で使われます)。

注意: スキーマ名を付けないテーブル名とスキーマ名を付けた形の両方をクエリの中で使う場合は、両方共リストに登録してください。

	#For example:
	#If the queries sometime use "table1" and other times "public.table1"
	#to refer the table1 then the cache_safe_memqcache_table_list
	#would be configured as follows.

	cache_safe_memqcache_table_list = "table1,public.table1"

       

注意: cache_unsafe_memqcache_table_listcache_safe_memqcache_table_listより優先されます。

このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。

cache_unsafe_memqcache_table_list (string)

SELECT結果がPgpool-IIにキャッシュされるべきでないテーブル名のリストをカンマ区切りで指定します。

テーブル名のマッチングには正規表現も利用できます (指定した各表現に ^ と $ をつけた形で使われます)。

注意: スキーマ名を付けないテーブル名とスキーマ名を付けた形の両方をクエリの中で使う場合は、両方共リストに登録してください。

	#For example:
	#If the queries sometime use "table1" and other times "public.table1"
	#to refer the table1 then the cache_unsafe_memqcache_table_list
	#would be configured as follows.

	cache_unsafe_memqcache_table_list = "table1,public.table1"

       

このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。

memqcache_oiddir (string)

SELECTクエリが使用するテーブルにOIDを格納するディレクトリへのフルパスで指定します。

memqcache_oiddirには、各データベースのためのディレクトリが格納されます。 そのディレクトリ名はデータベースのOIDです。 更に、各データベースディレクトリの下には各テーブルのためのファイルが格納されます。 そのファイル名は同じくテーブルのOIDです。 これらのファイルの中にはクエリキャッシュへのポインタが格納されており、 キャッシュを削除する際のキーとして使われます。

注意: Pgpool-IIの通常の再起動ではmemqcache_oiddirの中身はクリアされません。

このパラメータはPgpool-IIの設定を再読み込みすることで変更可能です。

5.12.4. 共有メモリ使用時の設定

これらはキャッシュストレージとして共有メモリを使用した場合に使われるパラメーターです。

memqcache_total_size (integer)

共有メモリのキャッシュサイズを指定します。 デフォルトは64MBです。

キャッシュはmemqcache_cache_block_sizeで指定される固定長のブロックに格納されます。 このブロックの数は、memqcache_total_size / memqcache_cache_block_size で計算できます。 ブロック数が整数になるように小数点以下が切り捨てられます。 ブロック数が0になると、エラーとなります。 つまり、memqcache_total_sizeは、memqcache_cache_block_sizeよりも大きくなければなりません。

各キャッシュデータは64バイトの管理データと、クエリ結果のデータに分けて一つのブロックに格納されます。 クエリ結果とその管理データは複数のブロックにまたがって格納されることはないので、クエリ結果のデータ長+64バイトがmemqcache_cache_block_sizeより大きいと、ブロックに格納できず、キャッシュされません。

あるブロックがキャッシュで一杯になると、次のブロックが利用されます。 すべてのブロックが一杯になると、最も古いブロックのキャッシュが消去されて再利用されます (新しいキャッシュデータは空きがある最初のブロックに格納されるので、最も古いブロックが最も古いキャッシュデータを保持しているとは限らないことに注意してください)。 したがって、memqcache_total_sizeが小さくてもエラーになりませんが、キャッシュヒット率が下がり、性能を低下させます。 キャッシュヒット率はSHOW POOL_CACHEcache_hit_ratioで確認できます。

このパラメータはサーバ起動時にのみ設定可能です。

memqcache_max_num_cache (integer)

キャッシュエントリの数を指定します。 デフォルトは1,000,000です。

この設定項目は、登録できるキャッシュの数の上限を決めます。 memqcache_max_num_cacheを超えてキャッシュを登録しようと、キャッシュ登録済みのブロックのキャッシュが消去されて再利用されます。 したがって、memqcache_max_num_cacheが小さくてもエラーになりませんが、キャッシュヒット率が下がり、性能を低下させます。 キャッシュヒット率はSHOW POOL_CACHEcache_hit_ratioで確認できます。

注意: キャッシュはアクセスを高速にするために共有メモリ上のハッシュテーブルで管理されており、その大きさは、memqcache_max_num_cache * 64バイトで計算できます。 ハッシュテーブルのエントリ数はSHOW POOL_CACHEnum_hash_entriesで確認できます。 num_hash_entriesは通常memqcache_max_num_cacheと一致しますが、memqcache_max_num_cacheが2のべき乗になっていない場合は、memqcache_max_num_cacheより大きい2のべき乗に丸められるので、一致しないこともあります。 使用済みのエントリ数はused_hash_entriesで確認できます。

このパラメータはサーバ起動時にのみ設定可能です。

memqcache_cache_block_size (integer)

キャッシュのブロックサイズを指定します。 デフォルトは1MBです。

Pgpool-IImemqcache_cache_block_sizeのブロックで管理されたキャッシュメモリを利用します。 各キャッシュデータは64バイトの管理データと、クエリ結果のデータに分けて一つのブロックに格納されます。 クエリ結果とその管理データは複数のブロックにまたがって格納されることはないので、クエリ結果のデータ長+64バイトがmemqcache_cache_block_sizeより大きいと、ブロックに格納できず、キャッシュされません。

memqcache_cache_block_sizeは、512バイト以上の値でなければなりません。

このパラメータはサーバ起動時にのみ設定可能です。

5.12.5. memcached使用時の設定

これらはキャッシュストレージとしてmemcachedを使用した場合に使われるパラメーターです。

memqcache_memcached_host (string)

memcachedが動いているホスト名またはIPアドレスを指定します。 Pgpool-IIと同じマシンでmemcachedを動かす場合は、'localhost'が使えます。

このパラメータはサーバ起動時にのみ設定可能です。

memqcache_memcached_port (integer)

memcachedのポート番号を指定します。 デフォルトは 11211 です。

このパラメータはサーバ起動時にのみ設定可能です。