回答:
WordPressは、デフォルトで「オブジェクトキャッシュ」の形式を実行しますが、その有効期間は1ページのロードのみです。
オプションは実際にこれの実に良い例です。詳細については、この回答をご覧ください。サマリー:
SELECT option_name, option_value from $wpdb->options
ステートメントでロードされますget_option
、WPキャッシュAPIで保存されているため、データベースにヒットしない呼び出し)。オプションは常にデータベースに「ライブ」され、常にそこに永続化されます。それが「標準的な」ソースです。ただし、オプションはオブジェクトキャッシュに読み込まれるため、オプションを要求すると、99%の確率でその要求がデータベースにヒットしない可能性があります。
トランジェントは少し異なります。
WordPressでは、キャッシュAPIをドロップイン(wp-content
フォルダーに直接配置されるファイル)に置き換えることができます。独自のキャッシュドロップを作成するか、既存の プラグインを使用する場合、1ページのロードよりも長くオブジェクトキャッシュを保持できます。それを行うと、トランジェントが少し変わります。
のset_transient
関数を見てみましょうwp-includes/option.php
。
<?php
/**
* Set/update the value of a transient.
*
* You do not need to serialize values. If the value needs to be serialized, then
* it will be serialized before it is set.
*
* @since 2.8.0
* @package WordPress
* @subpackage Transient
*
* @uses apply_filters() Calls 'pre_set_transient_$transient' hook to allow overwriting the
* transient value to be stored.
* @uses do_action() Calls 'set_transient_$transient' and 'setted_transient' hooks on success.
*
* @param string $transient Transient name. Expected to not be SQL-escaped.
* @param mixed $value Transient value. Expected to not be SQL-escaped.
* @param int $expiration Time until expiration in seconds, default 0
* @return bool False if value was not set and true if value was set.
*/
function set_transient( $transient, $value, $expiration = 0 ) {
global $_wp_using_ext_object_cache;
$value = apply_filters( 'pre_set_transient_' . $transient, $value );
if ( $_wp_using_ext_object_cache ) {
$result = wp_cache_set( $transient, $value, 'transient', $expiration );
} else {
$transient_timeout = '_transient_timeout_' . $transient;
$transient = '_transient_' . $transient;
if ( false === get_option( $transient ) ) {
$autoload = 'yes';
if ( $expiration ) {
$autoload = 'no';
add_option( $transient_timeout, time() + $expiration, '', 'no' );
}
$result = add_option( $transient, $value, '', $autoload );
} else {
if ( $expiration )
update_option( $transient_timeout, time() + $expiration );
$result = update_option( $transient, $value );
}
}
if ( $result ) {
do_action( 'set_transient_' . $transient );
do_action( 'setted_transient', $transient );
}
return $result;
}
うーん$_wp_using_ext_object_cache
?trueの場合、WordPressはデータベースの代わりにオブジェクトキャッシュを使用してトランジェントを保存します。では、どのようにtrueに設定しますか?WPが独自のキャッシュAPIを設定する方法を探る時間です。
あなたはにほとんどすべてを追跡することができるwp-load.php
か、wp-settings.php
ワードプレスのブートストラッププロセスに重要であるどちらも- 。キャッシュには、に関連する行がいくつかありますwp-settings.php
。
// Start the WordPress object cache, or an external object cache if the drop-in is present.
wp_start_object_cache();
上から物を落としたことを覚えていますか?のは、見てみましょうwp_start_object_cache
ではwp-includes/load.php
。
<?php
/**
* Starts the WordPress object cache.
*
* If an object-cache.php file exists in the wp-content directory,
* it uses that drop-in as an external object cache.
*
* @access private
* @since 3.0.0
*/
function wp_start_object_cache() {
global $_wp_using_ext_object_cache, $blog_id;
$first_init = false;
if ( ! function_exists( 'wp_cache_init' ) ) {
if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
require_once ( WP_CONTENT_DIR . '/object-cache.php' );
$_wp_using_ext_object_cache = true;
} else {
require_once ( ABSPATH . WPINC . '/cache.php' );
$_wp_using_ext_object_cache = false;
}
$first_init = true;
} else if ( !$_wp_using_ext_object_cache && file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
// Sometimes advanced-cache.php can load object-cache.php before it is loaded here.
// This breaks the function_exists check above and can result in $_wp_using_ext_object_cache
// being set incorrectly. Double check if an external cache exists.
$_wp_using_ext_object_cache = true;
}
// If cache supports reset, reset instead of init if already initialized.
// Reset signals to the cache that global IDs have changed and it may need to update keys
// and cleanup caches.
if ( ! $first_init && function_exists( 'wp_cache_switch_to_blog' ) )
wp_cache_switch_to_blog( $blog_id );
else
wp_cache_init();
if ( function_exists( 'wp_cache_add_global_groups' ) ) {
wp_cache_add_global_groups( array( 'users', 'userlogins', 'usermeta', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', 'rss', 'global-posts', 'blog-id-cache' ) );
wp_cache_add_non_persistent_groups( array( 'comment', 'counts', 'plugins' ) );
}
}
関数の関連する行(それに関連する行は、$_wp_using_ext_object_cache
トランジェントの格納方法を変更します)。
if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
require_once ( WP_CONTENT_DIR . '/object-cache.php' );
$_wp_using_ext_object_cache = true;
} else {
require_once ( ABSPATH . WPINC . '/cache.php' );
$_wp_using_ext_object_cache = false;
}
object-cache.php
コンテンツディレクトリに存在する場合は含まれ、WPは外部の永続キャッシュを使用していると想定します$_wp_using_ext_object_cache
。true に設定されます。
外部オブジェクトキャッシュを使用している場合、トランジェントはそれを使用します。これにより、オプションとトランジェントをいつ使用するかという疑問が生じます。
シンプル。データを無期限に永続化する必要がある場合は、オプションを使用します。それらは「キャッシュ」されますが、それらの正規のソースはデータベースであり、ユーザーが明示的に要求しない限り決して消えません。
設定された期間保存する必要があるが、指定されたライフタイムを超えて持続する必要がないデータの場合は、トランジェントを使用します。内部的には、WPは外部の永続オブジェクトキャッシュを使用しようとします。そうしないと、データがオプションテーブルに移動し、WordPressのpsuedo-cronで有効期限が切れたときにガベージコレクションが行われます。
その他の懸念事項/質問:
get_option
ですか?多分。関数のオーバーヘッドが発生しますが、データベースにはヒットしません。多くの場合、データベースの負荷は、選択した言語でページを生成する作業よりも、Webアプリケーションのスケーラビリティにおいて大きな懸念事項です。add_option
、最後のオプションの引数で呼び出す場合no
。ただし、一度フェッチすると、キャッシュに入れられ、以降の呼び出しはデータベースにヒットしません。私が知っている4つのキャッシュタイプがあります
自明-これは常にオンであり、他のキャッシュが作用する前に有効になります。キャッシュされたアイテムをphp配列に保存します。つまり、php実行セッションからメモリを消費し、phpの実行が終了するとキャッシュが空になります。つまり、他のキャッシュを使用せずにget_option( 'opt')を2回続けて呼び出す場合でも、メモリから値が返されるのは1回目と2回目のDBクエリのみです。
ファイル-キャッシュされた値は、ルートディレクトリの下のどこかのファイルに保存されます。非常に高速なディスクまたはメモリにマップされたファイルストレージがない限り、パフォーマンスの点で効果的でないことがわかったと思います。
APC(または他のphpアクセラレータベースのキャッシュ)-キャッシュされた値は、ホストマシンのメモリとphpメモリ割り当ての外部に保存されます。潜在的な最大の落とし穴は、データのスコープがないことであり、2つのサイトを実行すると、それぞれが他方のキャッシュデータにアクセスしたり、上書きしたりする可能性があります。
Memcache-ネットワークベースのキャッシュです。キャッシングサービスはネットワーク上のどこでも実行でき、おそらくホストメモリに値を保存します。負荷分散を実行していない限り、おそらくmemcacheは必要ありません。
ところで、オブジェクトキャッシングはオプションよりもはるかに多くをキャッシングしているため、高レベルのWP APIを使用してDBから取得したほぼすべてのものを保存します。
いい質問ですね。
WordPressがWP_Object_Cache
クラスを使用する方法に関する部分がまだないので、それを追加します。
ドキュメントから:
DEF:データベースへの旅行を保存するためにWordPressオブジェクトキャッシュが使用されます。オブジェクトキャッシュは、すべてのキャッシュデータをメモリに保存し、キーを使用してキャッシュコンテンツを使用可能にします。キーは、キャッシュコンテンツに名前を付けて後で取得するために使用されます。
WP_Object_Cache
構造は次のとおりです。
注+はパブリック、-プライベート、#保護されています。
このstats()
メソッドを使用して、グローバルキャッシュオブジェクトとその内容に関する一般的な統計を表示します。出力は次のとおりです。
Cache Hits: 110
Cache Misses: 98
Group: options - ( 81.03k )
Group: default - ( 0.03k )
Group: users - ( 0.41k )
Group: userlogins - ( 0.03k )
Group: useremail - ( 0.04k )
Group: userslugs - ( 0.03k )
Group: user_meta - ( 3.92k )
Group: posts - ( 1.99k )
Group: terms - ( 1.76k )
Group: post_tag_relationships - ( 0.04k )
Group: category_relationships - ( 0.03k )
Group: post_format_relationships - ( 0.02k )
Group: post_meta - ( 0.36k )
これは、などのテンプレートの最初の段階で取得したものsingle.php
です。
関心のある変数は次のとおりです。
global $wp_object_cache
です。
メンバー$cache
が実際のキャッシングデータを保持するプライベート。
プログラミングでは、キャッシュ構造はどこにでもあります。単純な形式では、キーと値のペアとして認識できます。バケット、NoDB構造、データベースインデックス。WordPress Object Cacheの究極の目標は、可能な限り単純な構造にすることではありませんでしたが、キーと値のペアは認識できます。
私はsingle.php
キャッシュを印刷したときにいたので:
print_r($wp_object_cache->cache['posts']);
キャッシュされた単一の投稿を取得しています。
[last_changed] => 0.34169600 1481802075
[get_page_by_path:2516f01e446b6c125493ec7824b63868:0.34169600 1481802075] => 0
[2831] => WP_Post Object
(
[ID] => 2831
[post_author] => 1
... the cached post object goes here
)
オブジェクトは値であり、キャッシュキーは
get_page_by_path:2516f01e446b6c125493ec7824b63868:0.34169600 1481802075
ここで、$cache_key
構造を確認できます。
File: /wp-includes/post.php
4210: /**
4211: * Retrieves a page given its path.
4212: *
4213: * @since 2.1.0
4214: *
4215: * @global wpdb $wpdb WordPress database abstraction object.
4216: *
4217: * @param string $page_path Page path.
4218: * @param string $output Optional. The required return type. One of OBJECT, ARRAY_A, or ARRAY_N, which correspond to
4219: * a WP_Post object, an associative array, or a numeric array, respectively. Default OBJECT.
4220: * @param string|array $post_type Optional. Post type or array of post types. Default 'page'.
4221: * @return WP_Post|array|null WP_Post (or array) on success, or null on failure.
4222: */
4223: function get_page_by_path( $page_path, $output = OBJECT, $post_type = 'page' ) {
4224: global $wpdb;
4225:
4226: $last_changed = wp_cache_get_last_changed( 'posts' );
4227:
4228: $hash = md5( $page_path . serialize( $post_type ) );
4229: $cache_key = "get_page_by_path:$hash:$last_changed";
4230: $cached = wp_cache_get( $cache_key, 'posts' );
4231: if ( false !== $cached ) {
4232: // Special case: '0' is a bad `$page_path`.
4233: if ( '0' === $cached || 0 === $cached ) {
4234: return;
4235: } else {
4236: return get_post( $cached, $output );
4237: }
4238: }