webentwicklung-frage-antwort-db.com.de

Wie funktioniert das Cachen von Objekten?

Ich suche hier eine endgültige Antwort. Wo leben Optionen und Transienten, wenn die Objekt-Zwischenspeicherung aktiviert ist?

Standardmäßig werden beide in der Datenbank gespeichert. Aber ich habe einige Hinweise gehört, dass memcache sie woanders speichert und APC etwas ganz anderes macht. Wo, genau , bleiben diese Daten in beiden Fällen erhalten?

21
EAMann

WordPress führt standardmäßig eine Art "Objekt-Caching" durch, die Lebensdauer beträgt jedoch nur eine Seite.

Optionen sind tatsächlich ein wirklich gutes Beispiel dafür. Check out diese Antwort für weitere Informationen. Die Zusammenfassung:

  1. Eine Seite beginnt
  2. Alle Optionen werden mit einer einfachen SELECT option_name, option_value from $wpdb->options-Anweisung geladen
  3. Nachfolgende Anforderungen für diese Optionen (z. B. ein Aufruf von get_option) treffen die Datenbank nie, da sie mit der Cache-API WP gespeichert werden.

Optionen "leben" immer in der Datenbank und werden dort immer beibehalten - das ist ihre "kanonische" Quelle. Das heißt, Optionen werden in den Objekt-Cache geladen. Wenn Sie also eine Option anfordern, besteht eine 99-prozentige Wahrscheinlichkeit, dass die Anforderung niemals die Datenbank erreicht.

Transienten sind etwas anders.

Mit WordPress können Sie die Cache-API durch ein Drop-In - ersetzen. Diese Datei wird direkt in Ihrem Ordner wp-content abgelegt. Wenn Sie ein eigenes Cache-Drop-In erstellen oder ein vorhandenesPlug-In verwenden, können Sie dafür sorgen, dass der Objektcache länger als eine einzelne Seite geladen bleibt. Wenn Sie dies tun, ändern Sie die Transienten ein wenig.

Werfen wir einen Blick auf die Funktion set_transient in 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? Wenn es wahr ist, verwendet WordPress den Objekt-Cache anstelle von der Datenbank, um Transienten zu speichern. Wie wird das nun wahr? Zeit zu erkunden, wie WP seine eigene Cache-API einrichtet.

Sie können fast alles auf wp-load.php oder wp-settings.php zurückführen - beides ist für den Bootstrap-Prozess von WordPress von entscheidender Bedeutung. In unserem Cache gibt es einige relevante Zeilen in wp-settings.php.

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

Erinnerst du dich an das Drop-In-Ding von oben? Werfen wir einen Blick auf wp_start_object_cache in 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' ) );
    }
}

Die relevanten Zeilen der Funktion (diejenigen, die sich auf $_wp_using_ext_object_cache beziehen und die die Speicherung von Transienten ändern).

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

wenn object-cache.php in Ihrem Inhaltsverzeichnis vorhanden ist, wird er eingeschlossen und WP setzt voraus, dass Sie einen externen, dauerhaften Cache verwenden - er setzt $_wp_using_ext_object_cache auf true.

Wenn Sie einen externen Objekt-Cache verwenden, wird dieser von Transienten verwendet. Dies wirft die Frage auf, wann Optionen im Vergleich zu Transienten verwendet werden sollen.

Einfach. Wenn Sie Daten für unbegrenzte Zeit benötigen, verwenden Sie Optionen. Sie werden "zwischengespeichert", aber ihre kanonischen Quellen sind die Datenbank und sie werden niemals verschwinden, es sei denn, ein Benutzer fordert dies ausdrücklich an.

Verwenden Sie für Daten, die für einen festgelegten Zeitraum gespeichert werden sollen, jedoch nicht länger als eine bestimmte Lebensdauer bestehen müssen, Transienten. Intern versucht WP, einen externen, beständigen Objekt-Cache zu verwenden, wenn dies nicht möglich ist. Andernfalls werden Daten in die Optionstabelle verschoben und über WordPress 'psuedo-cron gesammelt, wenn sie verfallen.

Einige andere Bedenken/Fragen:

  1. Ist es in Ordnung, eine Menge Anrufe an get_option zu tätigen? wahrscheinlich. Sie verursachen den Aufruf eines Funktions-Overheads, der die Datenbank jedoch wahrscheinlich nicht berührt. Das Laden von Datenbanken ist für die Skalierbarkeit von Webanwendungen oft ein größeres Problem als die Arbeit, mit der Ihre Sprache eine Seite erstellt.
  2. Woher weiß ich, dass ich Transienten im Vergleich zur Cache-API verwenden kann? Wenn Sie erwarten, dass die Daten für einen festgelegten Zeitraum bestehen bleiben, verwenden Sie die transiente API. Wenn es keine Rolle spielt, ob die Daten weiterhin vorhanden sind (z. B. dauert es nicht lange, die Daten zu berechnen/abzurufen, aber es sollte nicht mehr als einmal pro Seitenladevorgang vorkommen), verwenden Sie die Cache-API.
  3. Werden wirklich alle Optionen auf jeder Seite zwischengespeichert? Nicht unbedingt. Wenn Sie add_option mit dem letzten optionalen Argument als no aufrufen, werden sie nicht automatisch geladen. Das heißt, sobald Sie sie einmal abrufen, werden sie in den Cache verschoben, und nachfolgende Aufrufe werden nicht in die Datenbank übernommen.
34
chrisguitarguy

Es gibt 4 Cachetypen, die ich kenne

  1. Trivial - Es ist immer aktiviert und wirkt sich aus, bevor ein anderes Caching ins Spiel kommt. Es speichert die zwischengespeicherten Elemente in einem PHP-Array, was bedeutet, dass es Speicher von Ihrer PHP-Ausführungssitzung verbraucht und dass der Cache geleert wird, nachdem die PHP-Ausführung beendet ist. Das heißt, auch ohne Verwendung eines anderen Caches, wenn Sie get_option ('opt') zweimal hintereinander aufrufen, führen Sie eine DB-Abfrage nur beim ersten und beim zweiten Mal durch, wenn der Wert aus dem Speicher zurückgegeben wird.

  2. Datei - Die zwischengespeicherten Werte werden in Dateien irgendwo in Ihrem Stammverzeichnis gespeichert. Ich glaube, es hat sich als nicht effektiv in Bezug auf die Leistung erwiesen, es sei denn, Sie haben einen sehr schnellen Datenspeicher mit Festplatten- oder Speicherzuordnung.

  3. APC (oder anderes auf PHP-Beschleunigern basierendes Caching) - Die zwischengespeicherten Werte werden im Speicher Ihres Host-Rechners und außerhalb Ihrer PHP-Speicherzuordnung gespeichert. Die größte potenzielle Gefahr besteht darin, dass keine Datenbereiche festgelegt werden. Wenn Sie zwei Standorte betreiben, kann jeder potenziell auf die zwischengespeicherten Daten des anderen zugreifen oder diese überschreiben.

  4. Memcache - es ist ein netzwerkbasierter Cache. Sie können den Caching-Dienst überall im Netzwerk ausführen und er speichert wahrscheinlich Werte im Host-Speicher. Sie benötigen wahrscheinlich keinen Memcache, es sei denn, Sie haben einen Lastenausgleich in Aktion.

Übrigens, Objekt-Caching ist viel mehr als Optionen-Caching. Es speichert fast alles, was mit der WP API auf hoher Ebene aus der Datenbank abgerufen wurde.

5
Mark Kaplun

Gute Frage.

Ich denke, der Teil, in dem WordPress die Klasse WP_Object_Cache verwendet, fehlt noch, also werde ich das hinzufügen.

Aus den Dokumenten:

DEF: Der WordPress-Objekt-Cache wird zum Speichern von Fahrten in die Datenbank verwendet. Der Objekt-Cache speichert alle Cache-Daten im Speicher und stellt den Cache-Inhalt mithilfe eines Schlüssels zur Verfügung, mit dem der Cache-Inhalt benannt und später abgerufen wird.

Hier ist die WP_Object_Cache Struktur.

 enter image description here 

Hinweis + ist öffentlich, - privat, # geschützt.

Mit der Methode stats() zeigen Sie allgemeine Statistiken zum globalen Cache-Objekt und zu dessen Inhalt an. Hier ist die Ausgabe:

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 )

Dies ist, was ich am Anfang eines Templates wie single.php vorher bekommen habe.

Beachten Sie, dass die Variable, die uns interessiert, global $wp_object_cache ist.

Der private $cache des Mitglieds enthält die eigentlichen Caching-Daten.

In der Programmierung gibt es überall Cache-Strukturen. In einer einfachen Form können sie als Schlüsselwertpaar erkannt werden. Buckets, NoDB-Strukturen, Datenbankindizes. Das ultimative Ziel von WordPress Object Cache war es nicht, eine möglichst einfache Struktur zu haben, aber dennoch können Schlüsselwertpaare erkannt werden.

Da ich in single.php war, als ich den Cache ausgedruckt habe:

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

Ich bekomme einen einzelnen Beitrag zwischengespeichert.

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

Das Objekt wäre der Wert und der Caching-Schlüssel wäre

get_page_by_path:2516f01e446b6c125493ec7824b63868:0.34169600 1481802075

Hier können Sie die $cache_key Struktur überprüfen:

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:   }
0
prosti

Optionen werden immer in der Datenbank gespeichert, während Transienten möglicherweise nur im gemeinsamen Speicher gespeichert werden, wenn APC und ein Plug-in installiert sind, das APC-Caching in WP implementiert. Memcache verwendet auch Speicher.

Optionen werden ebenfalls im Speicher gespeichert und von dort geladen, wenn dies möglich ist (andernfalls wird eine Datenbankabfrage durchgeführt).

0
onetrickpony