[Go] redis 활용 데이터 캐싱

🧠·2022년 9월 5일
2

Go

목록 보기
2/5
post-thumbnail

Before

  • Redis가 데이터베이스의 캐시로 쓰일 수 있다는 건 많이 들어봤다. 하지만 직접 그 성능을 체험하지 못했고 어느 정도로 빠른지 감이 오지 않아 직접 테스트를 해보려고 마음먹었다. 물론 구글과 유튜브의 힘을 빌려서 진행했다.
  • 소스 코드는 깃허브에 있다.

Redis

The open source, in-memory data store used by millions of developers as a database, cache, streaming engine, and message broker.

in-memory 데이터 저장소. Key-Value 형태로 데이터를 저장하며 string, list, hash, set, sorted set 등 다양한 데이터 구조를 지원.

Redis는 데이터베이스, 캐시, 메시지 브로커 등 여러 목적으로 사용된다.

그 외 많은 정보들이 있지만 다음 기회에 천천히 알아보고 단순히 데이터베이스에서 데이터에 접근하는 상황과 외부 API 호출 시에 사용했을 때 성능 차이가 있는지를 비교해 보고자 했다.

Redis Tutorial

Redis를 사용하기 위해 Docker image 파일을 다운 받아 실행시킨다.

$ docker pull redis:alpine
$ docker run --name redis-test -d -p 6379:6379 reids:alpine
$ docker exec -it redis-test /bin/sh
$ redis-cli

위 명령어를 모두 입력하면 redis 명령어를 사용할 수 있다.

데이터를 Key-Value 형태로 캐싱하고 해당 데이터를 Key를 활용하여 꺼내오는 예제를 따라 해보았다.

> SET user:1 salvatore
> GET user:1

예제를 살펴보니 해당 데이터의 만료 기간도 정할 수 있다.

> EXPIRE user:1 1

user:1이라는 키를 가지는 데이터의 만료 기간을 1초로 정해준 것이다. 1초 후 해당 키를 넣어 GET 요청하면 nil이 반환되는 것을 볼 수 있다.

TEST

다음과 같은 구조로 api 서버를 구성했다.

데이터베이스에서의 데이터 접근과 외부 api를 통한 데이터 요청에 대한 테스트를 진행했다.

Server: Go (net/http)
DB: Postgres:14-alpine
Cache DB: Redis:alpine
External API: https://quotation-api-cdn.dunamu.com/v1/forex/recent?codes=FRX.KRWUSD

3개의 도커를 활용하여 해당 테스트를 진행했다. docker-compose.yml 파일은 다음과 같이 작성하였다.

services:
  web:
    build:
      context: .
      dockerfile: api.Dockerfile
    ports:
      - 9090:9090
    environment:
      PORT: 9090
      REDIS_URL: redis
      POSTGRES_URL: postgres

  redis:
    image: redis:alpine

  postgres:
    build:
      context: .
      dockerfile: postgres.Dockerfile

Go로 작성한 서버에서 redis와 postgres 컨테이너에 접근하기 위해 환경 변수에 각각의 service name을 적어주었다. 또한 postgres 컨테이너가 빌드 됨과 동시에 디비에 원하는 데이터를 삽입해놓기 위해 api.Dockerfile과 postgres.Dockerfile을 따로 작성하였다.

  1. DB 데이터 접근 테스트
  • /db?codes=KRWUSD 경로로 다음과 같은 GET 요청을 받으면 데이터베이스에 삽입된 KRWUSD에 대한 정보를 가져온다.
  1. 외부 API 데이터 접근 테스트
  • /api?codes=KRWUSD 경로로 다음과 같은 GET 요청을 받으면 외부 API를 호출하여 KRWUSD에 대한 정보를 가져온다.

두 테스트 모두 Redis에서 Get요청에 실패(cache miss)하면 데이터베이스 또는 API를 호출하도록 하였다.

결과는 다음과 같다.

Go 언어에서의 Marshal과 Unmarshal 과정이 포함되어 있긴 하지만 결과에 유의미한 영향을 줄 것 같지 않았다. (진짜 그런지 확인해 보고 싶어서 Go 언어에서의 해당 과정에 대해 알아보고 글을 작성하려고 한다.)

실무나 실제 운영되고 있는 서비스에서 해당 결과의 차이가 유의미 한지는 모르겠으나 단순 수치로만 봤을 때는 굉장히 효과가 있는 것으로 보였다.

캐싱 전략을 잘 세운다면 Redis를 활용하여 api 서버의 성능을 더욱 올릴 수 있을 것 같다.

Caching

  • 원본 데이터에 접근하는 시간보다 캐시 데이터에 접근하는 시간이 빨라야 함
  • DB 접근 시간 or 또 다른 API 호출을 통한 데이터 접근 시간보다 짧아야 함
  • 동일한 데이터에 대해 반복적으로 접근하는 상황이 많을 때 사용
    - 데이터의 재사용 횟수가 1회 이상
  • Read/Update 과정이 많은 데이터보다는 단순 Read 과정이 많은 데이터
  • 특정 기간에 대한 데이터 접근 시 (가계부 같은 경우는 한 달 치 데이터를 캐싱 등..)

Reference:

profile
: )

0개의 댓글