Redis - Cache

인철·2023년 11월 1일
0

programming

목록 보기
14/17
post-thumbnail

Cache에 대해 알아보자

Cache

한번 조회된 데이터를 미리 특정 공간에 저장해놓고, 똑같은 요청이 발생하게 되면 서버에게 다시 요청하지 말고 저장해놓은 데이터를 제공해서 빠르게 서비스를 제공해주는 것을 의미한다.
즉, 미리 결과를 저장하고 나중에 요청이 오면 그 요청에 대해서 DB또는 API를 참조하지 않고 Canche를 접근하여 요청을 처리하는 기법이다.
서비스를 처음 운영할 때는 WEB-WAS-DB 정도로 작게 인프라를 구축하는데, 사용자가 늘어나면 DB에 무리가 가기 시작한다.
DB는 데이터를 물리 디스크에 직접 쓰기 때문에 서버에 문제가 발생해도 데이터가 손실되지는 않지만, 매 트랜젝션마다 디스크에 접근해야 하므로 부하가 많아지면 성능이 떨어진다.
그래서 사용자가 늘어나면 DB를 스케일 인 또는 스케일 아웃하는 방식 외에도 캐시 서버를 검토하게 된다.

Cache 구조 패턴

Look aside Cache 패턴

위에서 말한 일반적인 캐시 정의를 그대로 구현한 구조이다.
캐시를 한번 접근하여 데이터가 있는지 판단한 후, 있다면 캐시의 데이터를 사용하고 없으면 실제 DB 또는 API를 호출한다.

  • Look aside Cache 쿼리순서

    1. 클라이언트에서 데이터 요청
    2.서버에서 캐시에 데이터 존재 유무 확인
    3.데이터가 있다면 캐시의 데이터 사용
    4.데이터가 없다면 실제 DB 데이터에 접근
    5.DB에서 가져 온 데이터를 캐시에 저장하고 클라이언트에 반환

    Write Back 패턴

    주로 쓰기 작업이 굉장히 많아서 INSERT 쿼리를 일일이 날리지 않고 한꺼번에 배치 처리를 하기 위해 사용한다.
    예를 들어 영어 듣기 평가를 온라인으로 진행하는 서비스가 있을 때, 여러 학생이 동시에 제출 버튼을 누르면서 DB에 갑작스럽게 엄청난 쓰기 요청이 몰리게 되면 DB가 죽을 수도 있다.
    이때 write back 기반의 캐시를 사용하면 캐시 메모리에 데이터를 저장해 놓고, 이후 DB 디스크에 업데이트 해주면 안전하게 쓰기 작업을 이행할 수 있는 것이다.
    DB에서 디스크를 접근하는 횟수가 줄어들기 때문에 성능 향상을 기대할 수 있지만, DB에 데이터를 저장하기 전에 캐시 서버가 죽으면 데이터가 유실된다는 문제점이 있다.
    그래서 다시 재생 가능한 데이터나, 극단적으로 heavy한 데이터에서 write back 방식을 많이 사용한다.
    예를 들면 로그를 캐시에 저장하고 특정 지점에 DB에 한번에 저장하는 경우가 있다.

  • Write Back 쿼리순서

    1.우선 모든 데이터를 캐시에 싹 저장
    2.캐시의 데이터를 일정 주기마다 DB에 한꺼번에 저장 (배치)
    3.그리고나선 DB에 저장했으니 잔존 데이터를 캐시에서 제거

Cache 활용 사례

Twitter는 140자 정도의 짧은 글을 올릴 수 있는 소셜 네트워킹 서비스(SNS)이다.
Twitter에서의 Timeline은 사용자가 Follow(구독)하는 사용자들의 최근 트윗을 확인할 수 있는 페이지이다.
2012년 당시 Twitter는 15만명이 넘는 실시간 활동 사용자와 초당 30만 건이 넘는 Timeline 요청이 발생했었다.
이러한 규모의 Timeline 요청을 데이터베이스에 직접 접근하는 방식으로 처리하면 Query가 복잡해짐에 따라 속도가 현저히 떨어지는 문제가 발생한다.
Twitter는 이 문제를 해결하기 위해 메모리 기반 NoSQL 기술인 Redis를 사용하였다고 한다.
Twitter의 데이터 센터에 존재하는 방대한 양의 Redis Cluster는 각 사용자의 Timeline에 노출될 Tweet의 정보(Tweet ID, 작성자 ID)를 List 형태로 약 800개 정도 캐싱한다.
발생하는 Timeline 요청은 바로 데이터베이스로 접근하지 않고 Redis에 캐싱된 Timeline 정보를 먼저 가져와서, 이를 토대로 Query를 단순화하여 데이터베이스에 접근하여 처리한다.


단, 모든 사용자의 Timeline을 캐싱하게 되면 메모리가 부족해질 수 있으므로, 로그인을 안한 지 30일이 지난 사용자의 Timeline은 Redis Cluster에서 삭제하도록 설정한다.
Redis Cluster에서 삭제된 사용자의 Timeline 정보는 해당 사용자가 다시 로그인을 할 시에 재생성 하게 하는데, 이때 데이터베이스에 직접 접근하는 과정이 필요하기에 시간이 다소 소요될 수도 있다.
이외에도 Redis를 주로 사용하는 곳은 다음과 같다.
1.인증 토큰 등을 저장(Strings or Hash)
2.Ranking 보드로 사용(Sorted-Set)
3.유저 API Limit
4.잡큐(list)
이처럼, Redis는 특히 Remote Dictionary로서 RDBMS의 캐시 솔루션으로 사용 용도가 굉장히 높다.
일반적으로 데이터베이스는 저장장치에 저장이 되는데, 데이터베이스를 조회하려면 저장장치로 i/o가 발생하게 된다.
RDBMS에서 SELECT 쿼리문을 날려 특정 데이터들을 FETCH했을 때, RDBMS의 구조상 DISK에서 데이터를 꺼내오는 데 Memory에서 읽어들이는 것보다 천배 가량 더 느리다.
예를 들어 데이터베이스에 접근하여 10,000개의 레코드를 읽는다고 가정했을 때 disk에 저장되어 있다면 약 30초의 시간이 걸리는 반면 RAM에서 읽을 경우엔 약 0.0002초 밖에 걸리지 않는다.


따라서 Redis같은 유연한 자료구조를 가지는 인메모리 Key-value 솔루션을 사용하여 DB 부하의 Read 연산의 부하를 분산시키는 데 적용한다.
캐시는 in-memory 방식을 활용하여 데이터를 임시로 저장해두기 때문에 저장장치의 i/o보다 훨씬 빠르게 동작할 수 있다.
그래서 자주 사용하는 데이터는 캐시 서버에서 우선 조회하고 없을 때는 데이터베이스를 다시 조회하는 방식을 활용하면 전체적인 서비스의 속도를 향상시킬 수 있다.
또, 하드한 작업 같은 경우 쿼리문이 길고 복잡해 기본적으로 데이터베이스를 조회하는 시간이 오래 걸리는데, 만일 이 쿼리가 자주 사용되는 경우라면 해당 쿼리가 전체 서비스 속도의 병목이 될 수 있다.
그럴때는 쿼리 결과 자체를 Redis로 캐싱을 해두고, 쿼리의 결과가 바뀔 수 있는 이벤트가 발생할 때마다 캐시에 적재를 새로한다면 전체 서비스 속도를 향상 시킬 수도 있다.
그래서 캐싱이 필요할 때 많이 사용되는데 즉시 메시지를 주고 받아야 될 때나, 장바구니의 삭제와 같은 경우에 많이 사용하는 편이다.
또한 RAM은 휘발성인데 그럼 실행중인 Redis를 끄면 데이터가 전부 날라간다고 생각이 들게 되는데, Redis는 in-memory 이지만 persistent on-disk 데이터베이스 이기도 하다.
Redis는 특정한 때에 현재까지의 in-memory 상태를 disk에 저장해 두었다가 Redis를 다시 시작했을 때 disk에 저장해 두었던 dump 파일들을 load 하기 때문에 데이터의 손실 발생을 방지할수도 있다.

profile
같은글이있어도양해부탁드려요(킁킁)

0개의 댓글

관련 채용 정보