API 응답이 느려서 캐시를 붙여야 하는 상황이 왔다. Redis가 가장 무난한 선택이었는데, 서버에 직접 설치하면 버전 관리도 귀찮고 나중에 지울 때도 깔끔하지 않다. Docker로 띄우면 한 줄이면 되고, 안 쓸 때 컨테이너만 지우면 끝이라 편하다.

기본 실행

가장 간단한 방법:

docker run -d --name redis \
  -p 6379:6379 \
  redis:7-alpine

끝이다. 이것만으로 Redis 서버가 돌아간다. 접속 테스트:

docker exec -it redis redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set hello "world"
OK
127.0.0.1:6379> get hello
"world"

근데 이렇게 쓰면 컨테이너가 죽을 때 데이터가 다 날아간다. 캐시 용도라면 상관없지만, 세션 스토어 같은 걸로 쓸 때는 데이터를 보존해야 한다.

데이터 영속성 설정

볼륨을 마운트하고 Redis 설정을 커스텀해야 한다. 먼저 redis.conf 파일을 만든다:

# redis.conf
bind 0.0.0.0
protected-mode yes
requirepass your-password

# RDB 스냅샷
save 900 1
save 300 10
save 60 10000

# AOF (Append Only File)
appendonly yes
appendfsync everysec

# 메모리 제한
maxmemory 256mb
maxmemory-policy allkeys-lru

maxmemory-policy allkeys-lru는 메모리가 꽉 차면 가장 오래 안 쓴 키부터 지운다는 뜻이다. 캐시 서버로 쓸 때 적합한 정책이다.

Docker Compose로 구성하면:

version: "3.8"

services:
  redis:
    image: redis:7-alpine
    command: redis-server /usr/local/etc/redis/redis.conf
    ports:
      - "6379:6379"
    volumes:
      - ./redis.conf:/usr/local/etc/redis/redis.conf
      - redis-data:/data
    restart: unless-stopped

volumes:
  redis-data:

비밀번호 설정

프로덕션에서는 반드시 비밀번호를 걸어야 한다. redis.confrequirepass를 넣거나, 커맨드라인으로:

docker run -d --name redis \
  -p 6379:6379 \
  redis:7-alpine \
  redis-server --requirepass your-password

접속할 때:

redis-cli -a your-password
# 또는
redis-cli
127.0.0.1:6379> AUTH your-password
OK

외부에 포트를 열지 않고 Docker 내부 네트워크에서만 접근하게 하는 것도 좋은 방법이다. compose에서 ports 항목을 빼면 외부 접근이 차단된다.

Node.js에서 연결

실제 앱에서 Redis를 사용하는 예시. ioredis 패키지가 가장 많이 쓰인다:

const Redis = require('ioredis');

const redis = new Redis({
  host: '192.168.1.100',
  port: 6379,
  password: 'your-password',
});

// 캐시 패턴
async function getUser(userId) {
  const cacheKey = `user:${userId}`;
  const cached = await redis.get(cacheKey);

  if (cached) {
    return JSON.parse(cached);
  }

  const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
  await redis.setex(cacheKey, 3600, JSON.stringify(user)); // 1시간 캐시

  return user;
}

setex로 TTL(유효기간)을 같이 설정하면 자동으로 만료된다. 캐시 무효화를 신경 쓸 필요가 줄어든다.

모니터링

Redis가 잘 돌아가는지 확인하는 명령어 몇 가지:

# 메모리 사용량
docker exec redis redis-cli -a your-password INFO memory

# 연결된 클라이언트 수
docker exec redis redis-cli -a your-password INFO clients

# 실시간 명령어 모니터링
docker exec redis redis-cli -a your-password MONITOR

MONITOR는 들어오는 모든 명령을 실시간으로 보여준다. 디버깅할 때 유용한데, 프로덕션에서 오래 켜두면 성능에 영향을 줄 수 있으니 잠깐만 쓰자.

Redis는 캐시 말고도 세션 스토어, 메시지 큐, 실시간 랭킹 등 다양하게 쓸 수 있다. Docker로 띄우면 5분이면 세팅이 끝나니까, 일단 써보고 필요에 맞게 설정을 조정하면 된다.