Varnish Cache의 grace 기능을 PHP/memcached로 구현했습니다.
grace 기능은 백엔드 서버가 죽더라도, 캐싱되어 있는 정보로 지속적인 서비스가 가능하도록 하는 기능입니다. 캐싱할때 여분의 시간(grace 시간)동안 더 캐시를 유지하며, 캐싱 시간이 지났을때 백엔드에 요청이 한번만 전달되게 하고, 나머지 요청에 대해서는 우선적으로 그 전에 있던 캐시로 서비스를 하도록 하여 백엔드 서버의 부하를 줄일수 있습니다.
현재는 memcached에서 expire 되면서 동시에 요청이 발생하는데, grace 기능을 구현하면 오래걸리는 페이지 생성할때 큰 효과를 발휘할수 있을거라 기대됩니다.
PHP 구현은 간단합니다. 원래 key,value 항목의 expire 시간을 grace 시간 만큼 늘리고, 다른 키(key+"_s")에 expire 시간동안 상태값을 입력해두면, 어렵지 않게 grace 기능을 구현할수 있습니다.
초기에 캐시에 없을때는 백엔드에 동시에 여러 요청이 들어갈수 있습니다. 이미 요청이 처리되고 있을때(state="G"), 일정시간동안 주기적으로 memcached를 조회해서 key가 있을때까지 대기하는 방법으로 어느정도 해결 가능할 거라 생각하지만 구현은 하지 않았습니다.
grace 기능은 백엔드 서버가 죽더라도, 캐싱되어 있는 정보로 지속적인 서비스가 가능하도록 하는 기능입니다. 캐싱할때 여분의 시간(grace 시간)동안 더 캐시를 유지하며, 캐싱 시간이 지났을때 백엔드에 요청이 한번만 전달되게 하고, 나머지 요청에 대해서는 우선적으로 그 전에 있던 캐시로 서비스를 하도록 하여 백엔드 서버의 부하를 줄일수 있습니다.
현재는 memcached에서 expire 되면서 동시에 요청이 발생하는데, grace 기능을 구현하면 오래걸리는 페이지 생성할때 큰 효과를 발휘할수 있을거라 기대됩니다.
PHP 구현은 간단합니다. 원래 key,value 항목의 expire 시간을 grace 시간 만큼 늘리고, 다른 키(key+"_s")에 expire 시간동안 상태값을 입력해두면, 어렵지 않게 grace 기능을 구현할수 있습니다.
초기에 캐시에 없을때는 백엔드에 동시에 여러 요청이 들어갈수 있습니다. 이미 요청이 처리되고 있을때(state="G"), 일정시간동안 주기적으로 memcached를 조회해서 key가 있을때까지 대기하는 방법으로 어느정도 해결 가능할 거라 생각하지만 구현은 하지 않았습니다.
array('127.0.0.1:11211'), 'debug' => false, 'persistant' => false));
function generate_value($key) {
sleep(5);
return "VALUE". $key;
}
function get_value($key) {
global $mc;
$expire = 60;
$grace_timeout = 600;
$generation_timeout = 10;
$state = $mc->get($key."_s");
//echo("state=$state<br>\n");
if ($state == "C" || $state == "G") {
$value = $mc->get($key);
if ($value) {
//echo("retreive key=$key<br>\n");
return $value;
}
}
$mc->set($key."_s", "G", $generation_timeout); // state: Generating
$value = generate_value($key);
$mc->set($key, $value, $expire + $grace_timeout);
$mc->set($key."_s", "C", $expire); // state: Cached
//echo("insert key=$key<br>\n");
return $value;
}
get_value("hahaha");
?>
