서버 부하 이슈 때문에;; 통합검색 자동완성 애드온에 캐시를 적용해보려고 하는데요
화제의 글 애드온의 캐시 적용 코드를 가져와서 재활용을 했습니다.
(애드온 제작자 Canto님께 감사 말씀 드립니다~)
근데 제가 캐시 적용을 처음 해보는 것이어서 이게 제대로 되는 건지 확신이 없네요;;;
1. 일단은 페이지 로딩 시에 json 데이터를 가져오는 게 아니라 검색창에 focus를 했을 때 가져오도록 작업해놨구요ㅎ
1-1. 데이터는 클라이언트의 로컬저장소에 보관을 해놔서 가급적 서버와의 통신 시도를 제한하고 있어요.
2. (로컬저장소에 데이터가 없을 경우에 한해) js에서 별도의 php 파일로 json 데이터를 호출하는데 캐시 여부에 따라 쿼리를 실행하게끔 하는 의도입니다.
아래는 php 파일 전체 소스인데요.
캐시 적용을 제대로 한 건지 살펴봐주시면 감사하겠습니다.
<?php define('__XE__', true); require_once '../../config/config.inc.php'; $oContext = &Context::getInstance(); $oContext->init(); // 키워드 수집 대상 : tag or title $target = $_REQUEST['target']; // 캐시 타임 설정 if ( !$_REQUEST['cache_time'] ) { $cache_time = 0; } else { $cache_time = 60 * (int)$_REQUEST['cache_time']; } // 자동완성 JSON 데이터 반환용 더미 변수 $autocompleteIS = array(); $args = new stdClass(); $args->list_count = (int)$_REQUEST['list_count']; $args->module_srl = $_REQUEST['module_srl']; // 캐시 관련 ( 캐시 설정이 되어있는 상태에서 캐시가 만료 되지 않았을 경우에는 캐시에서 데이터를 취득 ) $oCacheHandler = CacheHandler::getInstance(); // 사이트가 캐시를 지원하고 자동완성 캐시가 존재 할 때 if( $cache_time && $oCacheHandler->isSupport() && $oCacheHandler->isValid('autocompleteIS', $cache_time) ) { // 캐시를 가져와서 더미 변수에 입력 $cache = $oCacheHandler->get('autocompleteIS', $cache_time); $autocompleteIS = $cache; } // 캐시가 만료 되거나 캐시 시간이 설정 되어 있지 않는 경우 DB를 통해 데이터 취득 else { // 쿼리로 게시물 데이터 가져오기 if ( $target === 'tag' ) { $output = executeQueryArray('addons.ap_autocompleteIS.getTagList', $args); } else if ( $target === 'title' ) { $output = executeQueryArray('addons.ap_autocompleteIS.getDocumentTitle', $args); } // 결과 값이 있을 때 해당 키워드를 더미 변수에 저장 && 중복값 회피 if( $output->toBool() && $output->data ) { foreach( $output->data as $val ) { if ( !in_array($val->$target, $autocompleteIS) ) { $autocompleteIS[] = $val->$target; } } // 캐시를 지원하고 캐시 타임이 설정 되어 있을 경우 수집된 데이터를 캐시로 만들기 if( $oCacheHandler->isSupport() && $cache_time !== 0 ) { $oCacheHandler->put('autocompleteIS', $autocompleteIS, $cache_time); } } } echo json_encode($autocompleteIS, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE); unset($output); unset($args); unset($autocompleteIS); $oContext->close(); ?>
캐시핸들러 호출 방식은 맞습니다. 그러나
1. 달라질 가능성이 있는 값에 따라 캐시 키(autocompleteIS)도 달라져야 합니다. 위의 소스를 보면 module_srl, list_count 등이 달라지는 것 같네요. 검색어(target) 변수는 어디에 들어가는지 잘 모르겠고요... 아무튼 데이터가 달라질 수 있는 경우의 수에 따라 캐시 키도 구분하여 써야 합니다. 엉뚱한 게시판의 검색 결과가 나올 수 있어요.
2. isValid()는 쓰지 마세요. 그냥 get() 해서 값이 있으면 쓰고, 없으면 버리면 그만입니다. 예전에 이것과 관련해서 어디에 댓글을 단 적이 있는데 찾을 수가 없네요. isValid()는 값이 있는지 없는지 가볍게 체크하는 함수가 아니라, 기껏 데이터 불러와서 버리는 매우 비효율적인 함수입니다.