개체 캐싱은 어떻게 작동합니까?


21

나는 여기에 확실한 대답을 찾고 있습니다. 객체 캐싱이 활성화되면 옵션과 과도 상태가 어디에서 발생합니까?

기본적으로 둘 다 데이터베이스에 저장됩니다. 그러나 memcache가 다른 곳에 저장하고 APC가 완전히 다른 일을 할 것이라는 언급을 들었습니다. 두 경우 모두이 데이터가 정확히 어디에 유지됩니까?


2
@toscho 언급 기사는 이제 archive.org에서
여기에

답변:


34

기본적으로 WordPress는 "개체 캐싱"형식을 수행하지만 수명은 단일 페이지로드입니다.

옵션은 실제로 이것의 좋은 예입니다. 자세한 내용은 이 답변 을 확인하십시오 . 요약:

  1. 페이지가 시작됩니다
  2. 모든 옵션은 간단한 SELECT option_name, option_value from $wpdb->options문장으로 로드됩니다
  3. 해당 옵션에 대한 후속 요청 (예 : get_optionWP 캐시 API와 함께 저장되기 때문에 데이터베이스 에 절대 도달하지 않는 호출)

옵션은 항상 데이터베이스에 "라이브"되고 항상 거기에 유지됩니다. 이것이 "정식"소스입니다. 즉, 옵션은 객체 캐시에로드되므로 옵션을 요청할 때 요청이 데이터베이스에 절대로 도달하지 않을 확률이 99 %입니다.

과도는 약간 다릅니다.

WordPress를 사용하면 캐시 API를 드롭 인 (wp-content 폴더 에 직접 배치되는 파일) 으로 바꿀 수 있습니다 . 고유 한 캐시 드롭 인을 작성하거나 기존 플러그인을 사용하는 경우 오브젝트 캐시가 단일 페이지로드보다 오래 지속되도록 할 수 있습니다. 그렇게하면 과도 상태가 조금 변경됩니다.

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로 설정됩니까? WP가 자체 캐시 API를 설정하는 방법을 살펴볼 시간입니다.

WordPress의 부트 스트랩 프로세스에 중요한 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_cachetrue로.

외부 객체 캐시를 사용하는 경우 일시적으로 사용됩니다. 옵션과 과도를 언제 사용해야하는지에 대한 질문을 제기합니다.

단순한. 무기한으로 데이터를 유지해야하는 경우 옵션을 사용하십시오. "캐시"되지만, 정식 소스는 데이터베이스이며 사용자가 명시 적으로 요청하지 않으면 사라지지 않습니다.

정해진 시간 동안 저장해야하지만 지정된 수명 이상으로 지속될 필요가없는 데이터의 경우 과도 전류를 사용하십시오. 내부적으로 WP는 외부 영구 객체 캐시를 사용하려고 시도합니다. 그렇지 않으면 데이터가 옵션 테이블로 이동하여 만료 될 때 WordPress의 psuedo-cron을 통해 가비지 수집을 수행 할 수 있습니다.

다른 우려 사항 / 질문 :

  1. 많은 통화를해도 괜찮 get_option습니까? 아마. 함수 오버 헤드에 대한 호출이 발생하지만 데이터베이스에 충돌하지는 않습니다. 데이터베이스로드는 종종 선택한 언어가 페이지를 생성하는 작업보다 웹 응용 프로그램 확장 성에서 더 큰 관심사입니다.
  2. 임시 API와 캐시 API를 사용하는 방법을 어떻게 알 수 있습니까? 설정된 기간 동안 데이터가 지속될 것으로 예상되는 경우 임시 API를 사용하십시오. 데이터가 지속되는지 여부가 중요하지 않은 경우 (예 : 데이터를 계산 / 페치하는 데 시간이 걸리지 않지만 페이지로드 당 두 번 이상 발생하지 않아야 함) 캐시 API를 사용하십시오.
  3. 모든 옵션이 모든 페이지로드에 실제로 캐시됩니까? 반드시 그런 것은 아닙니다. 자동로드되지 않으므로 add_option마지막 선택적 인수를 사용하여 호출 하는 경우 no즉, 일단 한 번 가져 오면 캐시에 들어가고 후속 호출은 데이터베이스에 도달하지 않습니다.

nitpick 1 : 모든 옵션이 페이지 시작시로드되는 것이 아니라 "autoload = yes"로 표시된 옵션 만 작성됩니다. add_option의 해당 매개 변수에 대한 기본값은 'yes'이며 대부분의 플러그인 작성자는 '아니오'를 사용하는 것의 차이점을 이해하려고 귀찮게하지 않습니다.
Mark Kaplun

자동로드되지 않은 옵션도 한 번 가져온 후 캐시됩니다. 처음에는로드되지 않을 수 있지만 그 후에 오브젝트 캐시로 이동합니다. 존재하지 않는 옵션조차도 캐시됩니다! github.com/WordPress/WordPress/blob/master/wp-includes/… 그러나 자동로드 옵션에 대한 메모를 추가했습니다.
chrisguitarguy

그건 nitpick 2;)
Mark Kaplun 5

위대한 기사와 시간을 요약 해 주셔서 감사합니다.
prosti

5

내가 아는 4 가지 캐시 유형이 있습니다

  1. 사소한-다른 캐싱이 시작되기 전에 항상 켜져 있으며 적용됩니다. 캐시 된 항목을 php 배열에 저장합니다. 즉, PHP 실행 세션에서 메모리를 소비하고 PHP 실행이 끝나면 캐시가 비워집니다. 즉, 다른 캐시를 사용하지 않아도 get_option ( 'opt')을 두 번 연속으로 호출하면 처음으로 DB 쿼리를 만들고 두 번째로 메모리에서 값을 반환합니다.

  2. 파일-캐시 된 값은 루트 디렉토리 아래의 파일에 저장됩니다. 매우 빠른 디스크 또는 메모리 매핑 파일 저장소가 없으면 성능 측면에서 효과적이지 않은 것으로 보입니다.

  3. APC (또는 다른 PHP 가속기 기반 캐싱)-캐시 된 값은 호스트 컴퓨터의 메모리 및 PHP 메모리 할당 외부에 저장됩니다. 가장 큰 위험은 데이터 범위가없고 두 사이트를 모두 실행할 경우 각 사이트가 다른 사이트의 캐시 된 데이터에 액세스하거나 덮어 쓸 수 있다는 것입니다.

  4. Memcache-네트워크 기반 캐시입니다. 네트워크의 어느 곳에서나 캐싱 서비스를 실행할 수 있으며 아마도 호스트 메모리에 값을 저장합니다. 로드 밸런싱이 작동하지 않으면 memcache가 필요하지 않습니다.

BTW, 객체 캐싱은 옵션보다 훨씬 더 많은 캐싱을 수행하며, 고급 WP API를 사용하여 DB에서 검색된 거의 모든 것을 저장합니다.


나는 대답이 상당히 오래 되었다는 것을 알고 있지만 훌륭한 Redis 도 추가 할 것 입니다.
Cranio

@Cranio, 당신은 옳지 만 ... redis는 기본적으로 스토리지가있는 memcache의 변형이며, 따라서 (NoSQL) DB입니다. 이 IMHO는 실제로 노드가 실패하거나 업데이트 할 수없는 경우 오래된 정보를 얻을 수있는 것처럼 나쁩니다. DB와 같은 동작을 끄는 옵션이 있지만 기본적으로 켜져 있는지 꺼져 있는지 확실하지 않습니다.
Mark Kaplun

Memcached를 대체하는 완벽한 제품입니다 (더 나은 제품도 필요). 지금까지 내가 본 가장 일반적인 사용법은 RAM 키-값 스토리지와 같습니다 (그렇습니다. 그 외에는 데이터를 지속적으로 만들 수 있고 클러스터링이 진행 중이며 큐 관리 기능이 있지만 모든 사람이 Redis를 탁월한 것으로 추가 함) WP에 대한 캐싱 옵션)
Cranio

모두가 다리를 뛰어 넘을 수 있지만;) 추가 된 복잡성은 캐싱에 전혀 필요하지 않습니다
Mark Kaplun

그것은 완전히 무의미합니다. RAM 캐싱을 원한다면 Redis는 RAM 캐싱을 수행합니다. 훌륭하게 해냅니다. 절대적 당신이 그것을 위해 가고 싶어하지 않는 경우 복잡성을 추가하지 않습니다. 그래서 저는 당신의 요점을 이해하지 못합니다.
Cranio

0

옵션은 항상 데이터베이스에 저장되는 반면 APC와 WP에서 APC 캐싱을 구현하는 플러그인이 설치된 경우 임시 메모리는 공유 메모리에만 저장 될 수 있습니다. Memcache는 메모리도 사용합니다.

옵션은 또한 메모리에 저장되며 가능할 때 (DB 쿼리가 수행되지 않은 경우)로드됩니다.


0

좋은 질문입니다.

WordPress에서 WP_Object_Cache클래스를 사용하는 방법에 대한 부분 이 여전히 없다고 생각하므로 추가 할 것입니다.

문서에서 :

DEF : WordPress Object Cache는 데이터베이스에 대한 트립을 저장하는 데 사용됩니다. 오브젝트 캐시는 모든 캐시 데이터를 메모리에 저장하고 캐시 컨텐츠의 이름을 지정하고 나중에 검색하는 데 사용되는 키를 사용하여 캐시 컨텐츠를 사용 가능하게합니다.

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:   }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.