キャッシュタブ — 3 backend と TTL の設定
md サブドメインで生成された Markdown のキャッシュ戦略を決めるタブです。Transient / Object Cache / 専用テーブルの 3 つのバックエンドから選択し、TTL (1 時間〜1 週間) を設定。手動で全 flush するボタンも用意されています。
概要
「キャッシュ」タブは WordPress 管理画面 → LLMO Markdown → キャッシュ でアクセスできるタブです (URL: /wp-admin/admin.php?page=kashiwazaki-llmo-md&tab=cache)。
md サブドメインへのリクエストでは、WP_Query → DOMDocument 解析 → Markdown 変換 → Schema.org ヘッダ/フッタ生成 という多段処理が走ります。これをリクエストごとに実行すると CPU コストが高いため、生成済み Markdown をキャッシュします。本タブはそのキャッシュ機構を制御します。
設定項目は 2 つです:
- キャッシュ TTL — キャッシュ保持秒数
- キャッシュバックエンド — どこに保存するか (Transient / Object Cache / 専用テーブル)
加えて「全キャッシュをクリア」ボタンが下部に配置されています。
画面構成
<select> と 3 種の backend ラジオボタン、その下にキャッシュ管理セクションの全 flush ボタン。
wp_using_ext_object_cache() が true でないと選択不可で、未検出時は disabled かつ「(未検出)」と表示されます。
UI 部品の対応表
| セクション | UI 部品 | option key | デフォルト |
|---|---|---|---|
| キャッシュ TTL | select (5 オプション) | cache_duration (int 秒) |
3600 (1 時間) |
| キャッシュバックエンド | radio (3 オプション) | cache_backend (string enum) |
'transient' |
| 全キャッシュをクリア | submit ボタン | — | — |
キャッシュ TTL
キャッシュエントリの保持時間を選択します。値は秒数で cache_duration として保存されます。
選択肢
| 表示 | 秒数 | 用途 |
|---|---|---|
| 0 (キャッシュしない) | 0 | 開発中 / 設定変更を即時反映したい時 |
| 1 時間 | 3600 | コンテンツ更新頻度が高いニュースサイト |
| 6 時間 | 21600 | 1 日数回更新するメディア |
| 24 時間 | 86400 | 更新頻度が日次のブログ |
| 1 週間 | 604800 | 静的ページが多い企業サイト |
0 を選ぶ場合の注意
TTL = 0 は「キャッシュしない」相当ですが、内部的には set_transient($key, $value, 0) 的な動作で max( 1, (int) $ttl ) ガードが入るため最小 1 秒だけキャッシュされます。実質的にはほぼ毎リクエスト regenerate に近い挙動です。AI クローラからの大量アクセス時は CPU 負荷が高くなるため、本番では避けてください。
自動 invalidation
個別の post / term の更新時には自動的に該当キャッシュエントリが削除されるよう実装されています (save_post, edited_term 等の hook)。 TTL を長くしても 編集に反応してその post 単独のキャッシュは消えるので、エディタ視点では即時反映されます。ただし archive 系 (categoryなど) は影響範囲の広さから一律 TTL 切れまで残ることがあります。
キャッシュバックエンド
キャッシュデータの保存先 (永続化媒体) を 3 種から選びます。それぞれ性能・スケーラビリティ・副作用が異なります。
3 backend の比較
| 項目 | transient (デフォルト) | object_cache | custom_table |
|---|---|---|---|
| 保存先 | wp_options (transient API) |
Redis / Memcached / W3TC | {prefix}ksmd_cache 専用テーブル |
| 速度 | 遅 (DB クエリ) | 最速 (in-memory) | 中 (DB クエリ、ただし options より軽量) |
| スケール上限の目安 | 〜 500 ページ | 10 万 〜 数百万ページ | 10 万ページ超 |
| 外部依存 | なし | Redis / Memcached + drop-in | なし (MySQL のみ) |
| UI での選択可否 | 常時可 | wp_using_ext_object_cache() = true のみ |
常時可 |
| 副作用 (全 flush 時) | 自分の transient のみ削除 | group flush 非対応 drop-in では 全 object cache flush | 自分のテーブル truncate のみ |
| テーブル増加 | wp_options が肥大化 | — | 専用テーブル単独 |
| 手動管理 | 不要 | 必要 (Redis 起動 / drop-in) | activation 時に自動作成 |
transient backend
WordPress の標準 Transient API (set_transient() / get_transient() / delete_transient()) を使うバックエンド。追加のミドルウェア不要で動くため、本プラグインのデフォルトです。
内部実装:
// includes/cache.php (抜粋)
function ksmd_cache_get( $key ) {
return get_transient( $key );
}
function ksmd_cache_set( $key, $value, $ttl ) {
return set_transient( $key, $value, max( 1, (int) $ttl ) );
}
保存先は wp_options テーブル (option_name が _transient_* パターン)。WordPress が外部 object cache を使っている場合は自動的にそちらにリダイレクトされます (透過的にスケールアップ)。
object_cache backend
Redis / Memcached / W3TC などの外部キャッシュエンジンを wp_cache_* API 経由で利用するバックエンド。性能最良ですが、サーバ環境に Redis 等を導入し、対応する drop-in (例: object-cache.php in wp-content/) を配置する必要があります。
本プラグインは 'ksmd' という cache group を使います:
wp_cache_set( $key, $value, 'ksmd', max( 1, (int) $ttl ) );
wp_cache_get( $key, 'ksmd', false, $found );
UI では wp_using_ext_object_cache() が true のときのみ選択可能。未検出時はラジオボタンが disabled になり「(未検出)」と表示されます。
⚠️ Warning
古い drop-in が wp_cache_supports( 'flush_group' ) をサポートしていない場合、ksmd_cache_flush_all() 内で 全 object cache を wp_cache_flush() で消去 します (他プラグインのキャッシュも巻き添えに)。これは backend = object_cache のときのみ発動する対称設計です。
custom_table backend
本プラグイン専用の MySQL テーブル {prefix}ksmd_cache を作成して使うバックエンド。10 万ページを超える大規模サイトで、Object Cache 環境がない場合の選択肢です。
テーブルは初回利用時 (またはプラグイン activation 時) に dbDelta 経由で作成されます。ksmd_cache_table_ready option flag によって 1 回だけ実行されるよう制御されています。
主な利点:
- 専用テーブルなので
wp_optionsが肥大化しない - 独自インデックスで lookup が高速
- flush 時は
TRUNCATE1 発で済む - 他プラグインのキャッシュには副作用なし
backend 選択の意思決定ツリー
- Redis / Memcached が利用可能 → object_cache 一択 (最速)
- サイト規模が 10 万ページ超 → custom_table (Object Cache が無いとき)
- サイト規模が ~500 ページ程度 → transient (デフォルトのまま)
- サイト規模が中程度 (~1 万ページ) → transient でも OK、肥大化が気になれば custom_table
キャッシュ管理 — 全キャッシュをクリア
タブ最下部の「全キャッシュをクリア」ボタンは、選択中の backend に応じて以下の挙動を取ります。
backend 別の flush 挙動
// includes/cache.php
function ksmd_cache_flush_all() {
// (1) transient は backend と無関係に常に削除 (互換性のため)
if ( function_exists( 'ksmd_clear_all_transients' ) ) {
ksmd_clear_all_transients();
}
// (2) object_cache の group flush
if ( function_exists( 'wp_cache_supports' )
&& wp_cache_supports( 'flush_group' )
&& function_exists( 'wp_cache_flush_group' ) ) {
wp_cache_flush_group( 'ksmd' );
} elseif ( ksmd_cache_backend() === 'object_cache'
&& function_exists( 'wp_cache_flush' ) ) {
// backend が object_cache でかつ group flush 非対応 → 全 object cache flush
wp_cache_flush();
}
// (3) custom_table truncate
ksmd_cache_truncate_custom_table();
}
flush の実行タイミング
このボタン以外にも以下のタイミングで flush が走ります:
- kill switch toggle — 一般タブの kill switch を ON/OFF した瞬間
- save_post / edited_term hook — 該当エントリのキャッシュキーをピンポイントで削除 (全 flush ではない)
- md_host 変更 — 推奨は手動 flush。自動的には削除されないので注意
- プラグインアップデート — version 更新時に
ksmd_cache_table_readyが再評価されてテーブル再作成
内部挙動 — cache key の組み立て
singular のキー
個別ページのキャッシュキーは post ID + 設定 hash + locale をベースに組み立てられます (実装は md-renderer.php)。例:
ksmd_singular_42_a1b2c3d4_ja
└─ post ID
└─ 設定 hash (schema_type_map 等)
└─ locale
archive のキー
route 種別 + WP_Query args の正規化された hash でキー化:
ksmd_archive_category_news_pageNoOf2_a1b2c3d4_ja
これにより、同じカテゴリの 1 ページ目と 2 ページ目は別キーとして扱われ、独立にキャッシュされます。
typical configurations
パターン A — 小規模ブログ (デフォルト推奨)
cache_backend: transientcache_duration: 3600 (1 時間)
用途: 月間 1 万 PV 程度、~ 500 ページの個人/中小企業ブログ。導入直後の標準設定。
パターン B — 中規模サイト + Redis
cache_backend: object_cachecache_duration: 21600 (6 時間)- + Redis Object Cache plugin / Object Cache Pro 等を導入
用途: 月間 10 万 PV〜100 万 PV、Redis または Memcached を運用中のメディアサイト。
パターン C — 大規模 + Redis なし
cache_backend: custom_tablecache_duration: 86400 (24 時間)
用途: 数十万ページ規模だが Object Cache 環境が用意できないサイト。専用テーブルで wp_options 汚染を回避。
パターン D — 開発環境
cache_backend: transientcache_duration: 0 (キャッシュしない)
用途: ローカル開発中で、設定変更や filter 修正の効果を即時確認したい場合。
よくある質問
Q. transient と object_cache、結局どちらが速い?
A. Object Cache (Redis/Memcached) のほうが圧倒的に速いです。Transient は wp_options 経由で MySQL に往復するため、典型的に 5〜20ms / アクセスのオーバーヘッドが乗ります。Redis なら同等の処理が 0.1〜1ms 程度。
Q. Object Cache を選択したら設定が transient に戻ってる
A. wp_using_ext_object_cache() が false の環境では、ksmd_cache_backend() 関数内で自動的に transient にフォールバックされます。Redis 等の drop-in が機能しているか確認してください。
Q. custom_table を選択したらいつテーブルが作られる?
A. プラグイン activation 時、または初回キャッシュ書き込み時に dbDelta 経由で作成されます。テーブル名は {wp_prefix}ksmd_cache。ksmd_cache_table_ready option が KSMD_VERSION と一致しているとスキップされます。
Q. flush を押したのに古いコンテンツが返ってくる
A. CDN / Cloudflare / Varnish 等の上流キャッシュが残っている可能性があります。md サブドメイン側の CDN 設定を確認し、必要なら CDN レベルでも purge してください。
Q. TTL を 1 週間にしたら、コンテンツ更新が反映されない?
A. 個別 post の save_post hook によって該当キャッシュキーは削除されるため、編集した個別ページは即時反映されます。ただし category archive 等の一覧系は更新時に消されない場合があるため、必要なら手動で全 flush してください。
Q. 大量の wp_options エントリ _transient_ksmd_* がある
A. transient backend で運用していると wp_options に _transient_ksmd_* および _transient_timeout_ksmd_* エントリが大量生成されます。WP-CLI wp transient delete --all や本タブの全 flush で削除できます。長期的な運用では custom_table または object_cache への移行を推奨。
Q. flush 後にレスポンスが急に遅くなる
A. キャッシュ MISS 時は DOMDocument 解析 + Markdown 変換が走るため、数十〜数百 ms かかります。AI クローラのリクエストパターン次第ですが、 1〜2 リクエスト後には HIT に切り替わって高速化します。大規模サイトでは flush タイミングをトラフィック少ない時間帯に。
関連
- 一般タブ — kill switch toggle 時に全 flush が走る
- アーキテクチャ — md-renderer のキャッシュ判定パイプライン
- 診断タブ — Test renderer はキャッシュ bypass
- トラブルシューティング — キャッシュ起因の挙動異常の切り分け
- WordPress Transients API