아무거나

elasticcache 도입 사례 및 사용법 본문

Infra/AWS

elasticcache 도입 사례 및 사용법

전봉근 2019. 12. 24. 00:52
반응형

[Elasticache(Redis) 도입 사례]

검색엔진으로 들어오는 부분에 대해서 캐시를 도입했어야했다.

데이터는 현재 천만건기준으로 후에 4천만건정도 또는 그 이상일 경우를 대비하여 설계를해야 했으며

해결책은 이러했다.

 

1. 키를 빨리 찾고, 빨리 값을 리턴해야 한다.

2. 데이터는 메모리에 저장되어야 하고, 이상적으로 EC2 high-memory types(68GB 보다는, 17GB나 34GB) 이내에 들어가야 한다.

(역자 주: EC2에서 가격이 34GB는 17GB 의 2배, 68GB는 17GB의 4배 입니다.)

3. 기존 구조에 적합해야 한다.

4. 서버가 죽어도 다시 데이터를 새로 생성하지 않도록, persistent 해야 한다.

   (여기의 의미는, 다른 DB나 로그에서 데이터를 다시 재생성할 필요 없이, 저장된 데이터를 그대로 나중에 다시 복원할 수 있어야 한다라는 느낌입니다.)

 

Redis는 master-slave 형태로 동작이 가능하고, slave는 매분마다 메모리의 snapshot을 디스크에 저장한다.

Redis가 백만개의 키들을 저장하면 70MB정도가 필요하다고 한다. 천만, 4천만..1억.. 등으로 확장하면 Amazon EC2의 모델보다 더 큰 메모리가 필요했다.

그래서 알아보니 Redis의 Hashes는 메모리에 매우 효과적으로 인코딩된 사전 구조로 되어있다고 한다.

Redis의 hash-zipmap-max-entries’ Setting은 효과적으로 인코딩된 해쉬를 저장하는 엔트리의 최대 개수를 설정한다.

이 값을 대략 1000 으로 저정하는 것이 HSET 에서 가장 CPU 효율이 좋은 것을 알았다.

 

hash type의 장점을 얻기 위해서 우선 단순히 상품의 ID값을 1000개의 bucket로 나누었다. (단순히 ID를 1000을 나누고, 나머지는 버렸다.)

hash는 product ID를 키로 가지고, User ID를 값으로 가진다. 예를 들어 1234567라는 Product ID가 주어지면, bucket는 1234로 할당된다.

( 1234567 / 1000 = 1234 )

[hash ex]

HSET "test:1234" "1234567" "939"

HGET "test:1234" "1234567"

> "939"

 

[redis hash테이블 사용법 php 기준]

// @TODO : caching 정책 필요
date_default_timezone_set('Asia/Seoul');

$cacheKey = date('Ymdh').'_'.$device;
$cacheArrResponse = Redis::hGet($cacheKey, $this->q);

if(empty($cacheArrResponse)) {
    $now = time(NULL);
    Redis::hSet($cacheKey, $this->q, json_encode($arrResponse));
    Redis::expireAt($cacheKey, $now + 300); // 5분단위 캐싱
} else {
    // 첫 페이지일 경우에만 캐싱
    if($limit < 11 || $offset < 1) {
        $cacheArrResponse = Redis::hGet($cacheKey, $this->q);
        $arrResponse = json_decode($cacheArrResponse);
    }
}​ 
반응형
Comments