Varnish Cache의 grace 기능을 PHP/memcached로 구현했습니다.

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");
?>

 
2009/10/25 03:47 2009/10/25 03:47