Nesne önbelleğe alma nasıl çalışır?


21

Burada kesin bir cevap arıyorum. Nesne önbelleğe alma etkinleştirildiğinde, seçenekler ve geçici olaylar nerede yaşarlar?

Varsayılan olarak, her ikisi de veritabanında saklanır. Ancak memcache'in başka bir yerde saklayacağı ve APC'nin tamamen başka bir şey yapacağına dair bazı referanslar duydum. Her iki durumda da bu veriler tam olarak nerede devam edecek?


2
Bahseder @toscho makale üzerinde artık kullanılabilir archive.org: WordPress Önbellek API keşfetmek
burada

Yanıtlar:


34

WordPress, varsayılan olarak, "Nesne Önbelleğe Alma" biçimini oluşturur, ancak kullanım ömrü yalnızca bir sayfa yüklenir.

Seçenekler aslında bunun gerçekten güzel bir örneği. Bu cevabı kontrol etDaha fazla bilgi için göz . Özet:

  1. Bir sayfa başlar
  2. Tüm seçenekler basit bir şekilde yüklenir SELECT option_name, option_value from $wpdb->options açıklamada
  3. Bu seçenekler için müteakip talepler (örneğin get_option, WP önbellek API'si ile depolandıklarından, veritabanına asla vurulmaması gereken bir çağrı) .

Seçenekler her zaman veritabanında "yaşar" ve orada her zaman ısrar edilir - bu onların "kurallı" kaynağıdır. Bununla birlikte, seçenekler nesne önbelleğine yüklenir, bu nedenle bir seçenek isteğinde,% 99'luk bir isteğin veritabanına ulaşma şansı yoktur.

Geçici olaylar biraz farklı.

WordPress bir ile önbellek api yerine sağlar açılan içinde bir dosya sizin doğrudan yerleştirilen alır - wp-contentklasörde. Kendi önbelleğinizi oluşturursanız ya da mevcut bir eklentiyi kullanıyorsanız , nesne önbelleğini tek sayfadan daha uzun süre devam ettirebilirsiniz. Bunu yaptığınızda, geçici olaylar biraz değişiyor.

set_transientFonksiyonuna bir göz atalım 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;
}

Hmmm $_wp_using_ext_object_cache? Doğruysa, WordPress geçici depolamak için veritabanı yerine nesne önbelleğini kullanır . Peki bu nasıl gerçek oldu? WP'nin kendi önbellek API'sini nasıl kurduğunu keşfetme zamanı.

WordPress'in önyükleme işlemi için çok önemli olan hemen hemen her şeyi wp-load.phpveya her birini izleyebilirsiniz wp-settings.php. Bizim önbelleğimizde ilgili bazı satırlar var wp-settings.php.

// Start the WordPress object cache, or an external object cache if the drop-in is present.
wp_start_object_cache();

Yukarıdan çıkan o şeyi hatırlıyor musun? En az bir bakalım wp_start_object_cacheiçinde 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' ) );
    }
}

Fonksiyonun ilgili çizgileri (bununla ilgili olanlar $_wp_using_ext_object_cachegeçici durumların nasıl depolandığını değiştirir).

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;
}

eğer object-cache.phpiçerik dizininde exist o dahil ve WP harici, Kalıcı önbelleği kullandığınız varsayılmıştır alır - bu ayarlar $_wp_using_ext_object_cachetrue.

Harici bir nesne kullanıyorsanız, geçicibellekler önbellek kullanır. Bu seçenek ne zaman geçici seçeneklere karşı kullanılacağı sorusunu gündeme getirmektedir.

Basit. Süresiz olarak devam etmek için veriye ihtiyacınız varsa, seçenekleri kullanın. Önbelleklenirler, ancak kanonik kaynakları veritabanıdır ve bir kullanıcı açıkça talep etmediği sürece asla kaybolmazlar.

Belirli bir süre boyunca depolanması gereken, ancak belirli bir ömür boyu kullanım geçici sürelerinin ötesinde kalması gerekmeyen veriler için. Dahili olarak WP, harici, kalıcı bir nesne önbelleği kullanmaya çalışacak, aksi takdirde veriler seçenekler tablosuna girecek ve süresi dolduğunda WordPress'in 'psuedo-cron' u yoluyla çöp toplanacaktır .

Diğer bazı endişeler / sorular:

  1. Bir ton çağrı yapmak sorun olur get_optionmu? Muhtemelen. Baştaki bir işleve çağrı yaparlar, ancak muhtemelen veritabanına çarpmaz. Veri tabanı yükü, web uygulaması ölçeklenebilirliği konusunda genellikle tercih ettiğiniz dilde sayfa üretme işinden daha büyük bir endişe kaynağıdır.
  2. Önbellek API'sine göre geçici işlemleri kullanmayı nasıl bilebilirim? Verilerin belirli bir süre boyunca devam etmesini beklerseniz, geçici API'yi kullanın. Verilerin devam edip etmediği önemli değilse (örneğin, verilerin hesaplanması / alınması uzun sürmez, ancak sayfa başına bir defadan fazla olmamalıdır) önbellek API'sini kullanın.
  3. Tüm seçenekler her sayfa görünümünde gerçekten önbelleğe alınmış mı? Şart değil. add_optionSonuncusuyla çağırırsanız , isteğe bağlı argüman nootomatik olarak yüklenmediklerinden. Bununla birlikte, bir kez onları bir kez getirdiğinizde, önbelleğe girerler ve sonraki çağrılar veritabanına çarpmaz.

nitpick 1: Tüm seçenekler sayfa başlangıcında yüklenmez, yalnızca oluşturulduğunda "autoload = yes" işaretli olanlar. Add_option'daki bu parametre için varsayılan 'evet' ve çoğu eklenti yazarı, orada 'hayır' kullanmanın farklılığını anlamaktan rahatsız olmaz, ifadenizi pratikte doğrular.
Mark Kaplun

Otomatik yüklenmeyen seçenekler bile bir kez alındıktan sonra önbelleğe alınır. Başlangıçta yüklenmemiş olabilirler, ancak bundan sonra nesne önbelleğine giderler. Var olmayan seçenekler bile önbelleğe alınır! github.com/WordPress/WordPress/blob/master/wp-includes/… Bununla birlikte, autoload seçeneği hakkında bir not ekledim.
chrisguitarguy

bu nitpick 2 idi;)
Mark Kaplun

Harika yazı için ve tüm bunları özetleyen zaman için teşekkürler.
prosti

5

Bildiğim 4 önbellek türü var

  1. Önemsiz - Diğer önbelleklemeler devreye girmeden önce her zaman açıktır ve etki eder. Önbelleğe alınmış öğeleri bir php dizisinde saklar, bu da php yürütme oturumunuzdan bellek harcadığı ve php yürütme bittikten sonra önbelleğin boşaltıldığı anlamına gelir. yani, başka bir önbellek kullanmadan bile, arka arkaya iki kez get_option ('opt') 'i çağırırsanız, DB sorgulamasını sadece ilk kez ve ikinci kez değerin bellekten döndürülmesini sağlarsınız.

  2. Dosya - Önbelleğe alınmış değerler, kök dizininizin altındaki dosyalarda saklanır. Çok hızlı bir disk veya bellek eşlemeli dosya depolamanız olmadığı sürece performans açısından etkili olmadığını kanıtladım.

  3. APC (veya diğer php hızlandırıcıya dayalı önbellekleme) - Önbelleğe alınmış değerler, ana makinenizin hafızasında ve php hafıza tahsisinizin dışında saklanır. En büyük potansiyel sorun, hiçbir veri kapsamı olmaması ve potansiyel olarak iki site işletiyorsanız her birinin diğerinin önbelleğe alınmış verilerine erişebilmesi veya üzerine yazabilmesidir.

  4. Memcache - ağ tabanlı bir önbellektir. Önbellekleme servisini ağın herhangi bir yerinde çalıştırabilirsiniz ve muhtemelen değerleri ana belleğinde saklar. Muhtemelen bir işlem dengeleyicisi olmadıkça memcache'e ihtiyacınız yoktur.

BTW, nesne önbellekleme, seçeneklerden çok daha fazlasını önbelleğe alıyor, yüksek düzey WP API kullanarak DB'den alınan neredeyse her şeyi depolayacak.


Cevabın oldukça eski olduğunu biliyorum ama aynı zamanda mükemmel Redis'i de eklerdim .
Cranio

@Cranio, haklısın ama ... redis temelde depolama alanı olan bir memcache çeşididir ve bunun için bir (NoSQL) DB'dir. Bu IMHO gerçekte düğüm başarısız olur veya güncellenemez gibi kötüdür ondan eski bilgiler alabilirsiniz. DB benzeri davranışı kapatmak için bir seçeneği vardır, ancak varsayılan olarak açık veya kapalı olduğundan emin değilim.
Mark Kaplun

Memcached (daha da iyi) için mükemmel bir alternatiftir, başka neye ihtiyacınız var? Şimdiye kadar gördüğüm en yaygın kullanım bir RAM anahtar-değer depolama gibi (evet, bunun dışında veriler kalıcı olabilir, kümelenme devam ediyor ve kuyruk yönetimi yetenekleri var ama herkes Redis’i mükemmel bir şekilde ekliyor). WP için önbellekleme seçeneği)
Cranio

herkes köprünün
üstünden

Bu tamamen anlamsız; RAM önbellekleme istiyorsanız, Redis RAM önbellekleme, dönem; ve harika yapıyor. Bunun için gitmek istemiyorsanız kesinlikle hiçbir karmaşıklık yoktur . Bu yüzden efendim, amacınızı gerçekten anlayamadım.
Cranio

0

Seçenekler her zaman veritabanında saklanırken, geçici işlemler yalnızca APC ve WP'de APC önbelleğe alma işlemini uygulayan bir eklenti yüklüyse, paylaşılan hafızada saklanabilir. Memcache de hafızayı kullanır.

Seçenekler ayrıca bellekte saklanır ve mümkün olduğunda oradan yüklenir (değilse, bir db sorgusu gerçekleştirilir).


0

Harika soru

WordPress'in WP_Object_Cachesınıfı nasıl kullandığı ile ilgili bölüm hala eksik olduğunu düşünüyorum , o yüzden bunu ekleyeceğim.

Dokümanlardan:

DEF: WordPress Nesne Önbelleği, veritabanına yapılan yolculuklarda tasarruf etmek için kullanılır. Nesne Önbelleği, tüm önbellek verilerini belleğe kaydeder ve önbellek içeriğini adlandırmak ve daha sonra almak için kullanılan bir anahtar kullanarak önbellek içeriğini kullanılabilir duruma getirir.

İşte WP_Object_Cacheyapı.

görüntü tanımını buraya girin

Not + herkese açık, - özel, # korumalı.

stats()Genel önbellek nesnesi ve orada ne olduğu hakkında genel istatistikleri göstermek için yöntemi kullanın. İşte çıktı:

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 )

Böyle bir şablonun başında daha önce aldığım şey buydu single.php.

İlgilendiğimiz değişkene dikkat edin: global $wp_object_cache .

Özel üye $cachegerçek önbellek verilerini tutar.

Programlamada, önbellek yapıları her yerdedir. Basit bir biçimde anahtar değer çifti olarak tanınabilirler. Kovalar, NoDB yapıları, veritabanı indeksleri. WordPress Nesne Önbelleği nihai hedefi mümkün olan en basit yapıya sahip olmak değildi, ancak yine de temel değer çiftleri tanınabilir.

single.phpÖnbelleği yazdırdığımda bulunduğumdan beri :

print_r($wp_object_cache->cache['posts']);

Önbelleğe alınmış tek bir gönderi alıyorum.

    [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
        )

Nesne değer olur ve önbellek anahtarı olur

get_page_by_path:2516f01e446b6c125493ec7824b63868:0.34169600 1481802075

Burada $cache_keyyapıyı kontrol edebilirsiniz :

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:   }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.