Transient API를 사용하여 HTML 문자열 또는 객체를 저장해야합니까?


18

매우 복잡한 쿼리로 20 개의 관련 게시물 (각 게시물에 대해)을 표시하는 플러그인이 있다고 가정 해 봅시다. 그런 다음이 쿼리의 데이터를 사용하여 복잡한 HTML 레이아웃을 만듭니다. 또한 플러그인은 공용이며 모든 구성의 서버에 설치할 수 있습니다.

다음과 같은 것 :

/* complex and large query */
$related_posts = get_posts( ... );

$html_output = '';
foreach($related_posts as $key => $item) {
     /* complex layout rendering logic (but not as slow as the previous query) */   
     $html_output .= ...;
}

그래서 내 질문은 :

  • 그러한 데이터를 캐시하는 가장 안전하고 올바른 방법은 무엇입니까?
  • Transient API를 사용하여 $related_posts배열 또는 $html_output문자열 을 캐시해야합니까 ? $html_ouput문자열을 캐시하면 최대 크기 제한에 도달합니까? 저장하기 전에 압축해야합니까?
  • 여기서 Transient API를 사용해야합니까?

답변:


18

여기서 Transient API를 사용해야합니까?

아니.

기본 WordPress 설치 임시는 wp_options 테이블에 저장되며 코어 업그레이드 중에 만 정리됩니다. 옵션 테이블에 50,000 개의 게시물이 있고 50,000 개의 추가 행이 있다고 가정합니다. 분명히 그것들은 autoload = no로 설정되어 있으므로 모든 메모리를 소비하지는 않지만 또 다른 경고가 있습니다.

옵션 테이블의 자동로드 필드에 색인이 없습니다. 즉, wp_load_alloptions() 전체 테이블 스캔을 수행하게됩니다. 행이 많을수록 시간이 오래 걸립니다. 옵션 테이블에 자주 쓸수록 MySQL의 내부 캐시는 덜 효율적입니다.

캐시 된 데이터가 게시물과 직접 관련된 경우 게시물 메타에 저장하는 것이 좋습니다. 또한 포스트 메타 캐시는 WP_Query에서 포스트 검색 중에 프라이밍되기 때문에 캐시 된 컨텐츠를 표시해야 할 때마다 쿼리를 저장합니다.

메타 값에 대한 데이터 구조는 다를 수 있으며, 캐시 된 값이 오래된 경우 일시적인 동작과 같이 시간 소인이 있고 값 비싼 쿼리를 수행 할 수 있습니다.

명심해야 할 또 하나의 중요한 생각은 영구 객체 캐싱이있는 환경에서 WordPress 과도 현상이 휘발성 일 수 있다는 것입니다. 즉, 캐시 된 데이터를 일시적으로 24 시간 동안 저장하면 23 시간 또는 12 분 또는 5 분 내에 사용 가능하다는 보장은 없습니다. 많은 설치에 대한 객체 캐시 백엔드는 Redis 또는 Memcached와 같은 메모리 내 키-값 저장소이며, 새로운 객체에 맞도록 할당 된 메모리가 충분하지 않으면 오래된 항목이 제거됩니다. 이것은 메타 스토리지 접근 방식에있어 큰 승리입니다.

무효화도 더 똑똑 할 수 있습니다. 즉, 왜 X 시간 내에 관련 게시물 캐시를 무효화합니까? 일부 내용이 변경 되었기 때문입니까? 새로운 게시물이 추가 되었습니까? 새로운 태그가 할당 되었습니까? "복잡하고 큰 쿼리"에 따라 쿼리 결과를 변경할 무언가가 발생한 경우에만 무효화하도록 선택할 수 있습니다.

Transient API를 사용하여 $ related_posts 배열 또는 $ html_output 문자열을 캐시해야합니까? $ html_ouput 문자열을 캐시하면 최대 크기 제한에 도달합니까? 저장하기 전에 압축해야합니까?

PHP, MySQL 등에서 데이터가 흐르기 때문에 문자열의 크기에 따라 크게 달라집니다. MySQL의 한계에 도달하려면 매우 열심히 노력해야하지만 1MB 만

"복잡한 레이아웃 렌더링 로직"이 실제로 얼마나 걸립니까? 프로파일 러를 통해 실행하여 찾으십시오. 매우 빠르면 병목 현상이 발생하지 않을 가능성이 있습니다.

이 경우 게시물 ID를 캐싱하는 것이 좋습니다. WP_Post 객체는 전체 게시물 내용을 포함하지만 게시물 ID 배열 만 포함하기 때문에 WP_Post 객체는 아닙니다. 그런 다음 a 키 WP_Query를 사용하면 post__in기본 키로 매우 빠른 MySQL 쿼리가 발생합니다.

즉, 항목 당 필요한 데이터가 제목, 썸네일 URL 및 퍼머 링크와 같이 상당히 단순하면 MySQL에 대한 추가 왕복 오버 헤드없이 매우 긴 HTML 캐싱 오버 헤드없이이 세 개만 저장할 수 있습니다. 문자열.

와우, 그것은 많은 단어입니다, 희망이 도움이됩니다.


12

모든 WP 코드가 공개 코드는 아닙니다

당신이 공개 뭔가를 발표하려고한다면, kovshenin의 모든 것 말한 완벽하게 유효합니다.

자신이나 회사의 개인 코드를 작성하려는 경우 상황이 다릅니다.

외부 객체 캐시는 어떠한 경우에도 큰 이점입니다

외부 영구 객체 캐시를 설정하는 것이 좋습니다. .

트랜시버와 MySQL에 대한 kovshenin의 답변에서 말한 모든 것은 매우 사실이며 WP 자체와 많은 플러그인이 객체 캐시를 사용한다는 것을 고려할 때 성능 향상이 있습니다. Redis 또는 Memcached와 같은 최신 캐시 시스템.

캐시 된 값이 없을 수도 있습니다.

또한 외부 개체 캐시는 신뢰할 수 없습니다 . 과도 현상이 있다는 사실에 의존해서는 안됩니다. 캐시 된 위치가 아닌 경우 캐시가 작동하는지 확인 해야 합니다.

캐시는 저장되지 않고 캐시는 캐시입니다.

선택적으로 캐시 사용

이 예를보십시오 :

function my_get_some_value($key) {
   // by default no cache when debug and if no external object_cache
   $defUse = ! (defined('WP_DEBUG') && WP_DEBUG) && wp_using_ext_object_cache();
   // make the usage of cache filterable
   $useCache = apply_filters('my_use_cache', $defUse);
   // return cached value if any
   if ($useCache && ($cached = get_transient($key))) {
     return $cached;
   }
   // no cached value, make sure your code works with no cache
   $value = my_get_some_value_in_some_expensive_way();
   // set cache, if allowed
   $useCache and set_transient($key, $value, HOUR_IN_SECONDS);

   return $value;
}

이 같은 코드를 사용하면, 개인 사이트, 사이트의 성능을 향상시킬 수있는 많은 당신은 많은 사용자가 특히.

참고 :

  • 기본적으로 디버그가 켜져 있으면 캐시가 사용되지 않으므로 개발 환경에서 캐시가 사용되기를 바랍니다. 나를 믿어, 캐시는 디버그를 지옥으로 만들 수있어.
  • 기본적으로 WP가 외부 오브젝트 캐시를 사용하도록 설정되지 않은 경우에도 캐시가 사용되지 않습니다. 이는 MySQL을 사용할 때 일시적인 기능을 사용하지 않기 때문에 MySQL과 관련된 모든 문제가 존재하지 않음을 의미합니다. 아마도 더 쉬운 대안은 함수 를 사용하는 wp_cache_*것입니다. 것이므로 외부 캐시가 설정되어 있지 않으면 캐시는 메모리에서 발생하며 데이터베이스는 관여하지 않습니다.
  • 캐시 사용은 필터링이 가능하여 발생할 수있는 일부 경우를 처리 할 수 ​​있습니다.

캐시가없는 경우 웹 스케일 없음

캐시의 속도 문제를 해결하려고 시도해서는 안됩니다. 속도 문제가있는 경우 코드를 다시 생각해야합니다.

그러나 웹 스케일로 웹 사이트를 확장 하려면 캐시가 필요합니다. .

컨텍스트 인식 캐시는 여러 번 (항상 그런 것은 아님) 단편적인 전체 페이지 캐싱보다 훨씬 유연하고 적합합니다.

당신의 질문:

여기서 Transient API를 사용해야합니까?

때에 따라 다르지 .

코드가 많은 리소스를 소비하고 있습니까? 그렇지 않은 경우 캐시가 필요하지 않을 수 있습니다. 말했듯이 속도의 문제가 아닙니다. 코드가 빠르게 실행되지만 몇 명의 사용자를 위해 많은 CPU와 메모리가 필요한 경우 ... 100 명 또는 1000 명의 동시 사용자가있는 경우 어떻게됩니까?

캐시가 좋은 생각이라면 ..

... 공용 코드입니다 : 아마도 no . 위의 예제와 같이 선택적으로 캐시하는 것을 고려할 수 있지만 일반적으로 그러한 결정을 구현 자에게 맡기는 것이 좋습니다.

... 그리고 개인 코드입니다 : 아마도 yes 입니다. 그러나 개인 코드의 경우에도 선택적으로 캐시하는 것이 여전히 좋은 예입니다 (예 : 디버그).

어쨌든이 wp_cache_*기능을 사용하면 데이터베이스를 오염시킬 위험없이 캐시에 액세스 할 수 있습니다.

Transient API를 사용하여 $ related_posts 배열 또는 $ html_output 문자열을 캐시해야합니까?

그것은 많은 것들에 달려 있습니다. 줄이 얼마나 큽니까? 어떤 외부 캐시를 사용하고 있습니까? 게시물을 캐시하려는 경우 ID를 배열로 저장하는 것이 좋습니다 .ID로 적절한 수의 게시물을 쿼리하는 것은 매우 빠릅니다.

최종 노트

일시적 API는 아마도 WordPress의 가장 좋은 것 중 하나 일 것입니다. 모든 종류의 캐시 시스템에서 찾을 수있는 플러그인 덕분에이 소프트웨어는 여러 가지 소프트웨어에서 간단하고 간단한 API가되었습니다.

WordPress 외부에서는 여러 가지 다른 캐싱 시스템을 사용하여 즉시 사용할 수 있으며 노력없이 한 시스템에서 다른 시스템으로 전환 할 수있는 추상화가 매우 어렵습니다.

WordPress가 다른 최신 것보다 낫다는 말은 거의 들리지 않지만 임시 API는 WordPress에서 작업하지 않을 때 놓칠 수있는 몇 가지 중 하나입니다.

확실히 캐시는 어렵고 코드 문제를 해결하지 못하며 은총 알이 아니지만 트래픽이 많은 사이트를 구축 해야 합니다.

캐시를 수행하기 위해 최적화되지 않은 MySQL 테이블을 사용하는 WordPress 아이디어는 미쳤지 만 기본적으로 WordPress 때문에 캐시에서 멀리하는 것이 좋습니다.

작동 방식을 이해 한 다음 선택하십시오.


2

이전의 답변들은 이미“ 이것이 다름 ”이라는 의무를 강조했으며 , 이에 동의합니다.

나는 "방법에 따라, 비록 내가 추천을 추가 할 생각 이 가장 잘 당신이 위에 설명 된 시나리오에서 수행 될 것이다."

내가 사용하지 것이다 과도를 하는 경우, 오히려 포스트 메타 , 후자가 가지고있는 하나 때문에 장점 : 제어 .

게시물별로 데이터를 캐시해야하므로 캐시 할 데이터의 양은 게시물 수에 따라 다르며 시간이 지남에 따라 증가합니다. 특정 개수의 게시물을 초과하면 객체 캐시에서 사용할 수있는 메모리 한계에 도달 할 수 있으며 만료되기 전에 메모리에서 이전에 캐시 된 데이터를 삭제하기 시작합니다. 이로 인해 많은 방문자가 유입 될 수 있으며, 각 방문자가 각 페이지 요청에 따라 "과도하게 복잡한 SQL"을 트리거하고 사이트가 완전히 중단 될 수 있습니다.

Post Meta에 데이터를 캐시하면 데이터 저장 및 검색 방법을 제어 할 수있을뿐만 아니라 데이터 업데이트 방법을 정확하게 제어 할 수도 있습니다. 사이트에 트래픽이 적거나 적은 시간에만 실행되는 크론 작업을 추가합니다. 따라서 사이트의 실제 사용자는 "느린 쿼리"를 발견하지 못하며 사전로드 할 수도 있으므로 첫 번째 방문자가 방문했을 때 작업이 이미 완료되었습니다.

모든 캐싱은 트레이드 오프라는 점을 명심하십시오! 그렇기 때문에 일반적인 대답은 "그것은 달려있다"입니다. 왜 "거룩한 캐싱 성배"가 없는가.

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