Home Redis with Docker Project
Post
Cancel

Redis with Docker Project

Project: Redis with Docker

목차


프로젝트 목표

Docker를 이용해 Redis를 실행하고, 포트 매핑, 데이터 저장, 볼륨 마운트를 통해 Redis의 기본 개념을 이해한다.

1
2
3
4
5
학습 목표:
1. Docker 이미지 실행
2. 포트 매핑의 의미
3. 컨테이너 데이터 영속성
4. 볼륨 사용

Redis 개념

Redis란?

1
2
3
4
5
6
7
8
9
10
11
12
Redis (REmote DIctionary Server):
- 메모리 기반 데이터 저장소
- Key-Value 형식
- 매우 빠른 읽기/쓰기
- 캐시, 세션, 실시간 데이터에 사용

특징:
✓ 메모리 저장 (매우 빠름)
✓ 단순한 자료구조 (String, List, Set, Hash)
✓ TTL (Time To Live) 지원
✓ Pub/Sub 메시징
✗ 메모리에만 저장 (휘발성)

데이터 구조

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
String (문자열):
key: "username"
value: "john"

List (리스트):
key: "tasks"
value: ["task1", "task2", "task3"]

Set (집합):
key: "tags"
value: {"python", "redis", "docker"}

Hash (해시):
key: "user:1"
value: {name: "john", age: 30, email: "john@example.com"}

Sorted Set (정렬된 집합):
key: "scores"
value: {john: 100, jane: 95, bob: 85}
(점수 기준 정렬)

Docker 실행

기본 실행

1
2
3
4
5
6
7
8
9
# Redis 컨테이너 실행 (가장 간단한 방식)
docker run --name redis-study -p 6379:6379 redis:alpine

# 백그라운드 실행
docker run -d --name redis-study -p 6379:6379 redis:alpine

# 확인
docker ps
docker logs redis-study

“컨테이너 포트와 호스트 포트는 무엇이 다른가?”

호스트 포트는 실제 시스템 포트, 컨테이너 포트는 컨테이너 내부 포트이다. 포트 매핑으로 둘을 연결한다.

1
2
3
4
5
6
7
8
9
10
11
호스트 (컴퓨터):
포트 6379 ← 외부 접속

         ↓ 포트 매핑 (-p 6379:6379)

컨테이너 (Redis):
포트 6379 (Redis 기본 포트)

포트 매핑 없으면:
호스트에서 localhost:6379로 접속 불가능
컨테이너 내부에서만 접속 가능

포트 매핑 옵션

1
2
3
4
5
6
7
8
9
10
11
# 모든 인터페이스에서 수신
docker run -p 6379:6379 redis:alpine
# 외부: 0.0.0.0:6379

# localhost에서만 수신 (안전)
docker run -p 127.0.0.1:6379:6379 redis:alpine
# 외부: 127.0.0.1:6379

# 다른 호스트 포트 사용
docker run -p 6380:6379 redis:alpine
# 호스트:6380 → 컨테이너:6379

Docker Compose로 실행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# docker-compose.yml
version: '3.8'

services:
  redis:
    image: redis:alpine
    container_name: redis-study
    ports:
      - "6379:6379"  # 호스트:컨테이너
    volumes:
      - redis-data:/data
    command: redis-server --appendonly yes
    restart: unless-stopped

volumes:
  redis-data:
    driver: local

Docker Compose 사용

1
2
3
4
5
6
7
8
9
10
11
# 시작
docker-compose up -d

# 로그 보기
docker-compose logs -f redis

# 중지
docker-compose down

# 볼륨 포함 완전 삭제
docker-compose down -v

Redis CLI 사용

redis-cli 접속

1
2
3
4
5
6
7
8
# 방법 1: 호스트에서 직접 (redis-cli 설치 필요)
redis-cli -h localhost -p 6379

# 방법 2: 컨테이너 내부에서
docker exec -it redis-study redis-cli

# 방법 3: 대화형 쉘
docker run -it redis:alpine redis-cli -h host.docker.internal -p 6379

기본 명령어

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# String
SET key1 "Hello"
GET key1                    # "Hello"
APPEND key1 " World"
GET key1                    # "Hello World"
STRLEN key1                 # 11

# Key 관리
EXISTS key1                 # 1 (존재)
DEL key1                    # 1 (삭제됨)
KEYS *                      # 모든 key 조회
FLUSHALL                    # 모든 데이터 삭제 (주의!)

# 만료 시간 (TTL)
SET session_id "abc123" EX 3600  # 1시간 후 자동 삭제
TTL session_id              # 3599 (남은 시간)
EXPIRE key1 60              # 60초 후 삭제

# List
LPUSH mylist "a"            # 왼쪽에 추가
RPUSH mylist "b"            # 오른쪽에 추가
LRANGE mylist 0 -1          # ["a", "b"]
LPOP mylist                 # "a" (제거)

# Set
SADD myset "python"
SADD myset "redis"
SMEMBERS myset              # {"python", "redis"}
SISMEMBER myset "python"    # 1 (포함)

# Hash
HSET user:1 name "john" age 30
HGET user:1 name            # "john"
HGETALL user:1              # {name: "john", age: 30}

모니터링

1
2
3
4
5
6
7
8
9
10
11
12
# 실시간 명령 모니터링
MONITOR

# 서버 정보
INFO
INFO memory
INFO stats

# 메모리 사용
DBSIZE                      # key 개수
INFO memory                 # 메모리 사용량
MEMORY USAGE key1           # 특정 key 메모리

데이터 영속성

“Redis 데이터는 컨테이너 삭제 후 어떻게 되는가?”

Redis 데이터는 메모리에 저장되므로, 컨테이너가 삭제되면 데이터도 사라진다. 영속성을 위해서는 볼륨 마운트나 RDB/AOF 저장이 필요하다.

1
2
3
4
5
6
7
8
9
10
영속성 없이:
컨테이너 생성
→ SET data
→ docker rm redis-study
→ 데이터 손실!

영속성 있이:
docker run -v redis-data:/data redis:alpine
→ /data에 저장된 데이터는 유지
→ 컨테이너 재시작해도 복구

“volume은 왜 필요한가?”

Volume은 컨테이너가 삭제되어도 데이터를 호스트에 보존한다.

1
2
3
4
5
6
7
8
9
볼륨 없이:
컨테이너 A (메모리: key=value)
→ docker rm (모두 삭제)

볼륨 있이:
컨테이너 A (메모리)
    ↓ 마운트
호스트 /var/lib/docker/volumes/redis-data/
    (디스크에 저장, 삭제 안 됨)

RDB vs AOF

1
2
3
4
5
6
7
8
9
10
11
RDB (Snapshot):
- 주기적으로 메모리 전체 저장
- 빠르지만 변경 손실 가능
- 파일: dump.rdb
- 설정: save 900 1 (15분마다 1개 변경 시)

AOF (Append Only File):
- 모든 명령 기록
- 느리지만 데이터 손실 최소
- 파일: appendonly.aof
- 설정: appendonly yes

영속성 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# RDB + AOF 둘 다 사용
docker run \
  -d \
  --name redis-study \
  -p 6379:6379 \
  -v redis-data:/data \
  redis:alpine \
  redis-server --appendonly yes --save 900 1

# docker-compose.yml
services:
  redis:
    image: redis:alpine
    volumes:
      - redis-data:/data
    command: redis-server --appendonly yes

볼륨 확인

1
2
3
4
5
6
7
8
9
10
# 볼륨 목록
docker volume ls

# 볼륨 세부 정보
docker volume inspect redis-data

# 호스트 경로
# Linux: /var/lib/docker/volumes/redis-data/_data
# Mac: Docker Desktop VM 내부
# Windows: WSL2 VM 내부

검증 방법

동작 확인

1
2
3
4
5
6
7
8
9
10
11
12
# 컨테이너 실행
docker run -d --name redis-test -p 6379:6379 redis:alpine

# 데이터 저장
docker exec redis-test redis-cli SET hello world

# 데이터 확인
docker exec redis-test redis-cli GET hello
# 출력: "world"

# 성공!
docker stop redis-test

성능 테스트

1
2
3
4
5
6
7
8
9
10
# 벤치마크
docker exec redis-test redis-benchmark -n 1000 -c 10
# 10개 동시 연결로 1000개 요청

# 메모리 사용량 확인
docker exec redis-test redis-cli INFO memory

# 응답 예시:
# used_memory: 1045632 bytes (1MB)
# used_memory_human: 1.00M

연결 확인

1
2
3
4
5
6
# Redis CLI 접속
docker exec -it redis-test redis-cli

# 핑 테스트
PING                        # PONG
echo "Hello" | docker exec -i redis-test redis-cli

문제 해결

포트 충돌

1
2
3
4
5
6
7
8
9
10
11
12
13
# 포트 사용 중 에러
docker: Error response from daemon: Ports are not available

# 해결 방법
# 1) 다른 포트 사용
docker run -p 6380:6379 redis:alpine

# 2) 기존 컨테이너 중지
docker stop <container_id>

# 3) 포트 확인
netstat -tulpn | grep 6379
lsof -i :6379

데이터 접근 불가

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 호스트에서 접속 안 될 때
redis-cli ping
# 에러: Could not connect

# 확인
docker ps (컨테이너 실행 중?)
docker logs redis-test (에러 메시지?)

# 포트 매핑 확인
docker port redis-test
# 출력: 6379/tcp -> 0.0.0.0:6379

# localhost 대신 127.0.0.1 시도
redis-cli -h 127.0.0.1 ping

메모리 부족

1
2
3
4
5
6
7
8
# 메모리 제한 설정
docker run \
  -m 512m \              # 512MB 제한
  -p 6379:6379 \
  redis:alpine

# 확인
docker stats redis-study

다음 단계

Redis Python 연결

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import redis

# 연결
r = redis.Redis(host='localhost', port=6379, decode_responses=True)

# 데이터 저장
r.set('name', 'john')
r.set('score', 100)

# 데이터 조회
print(r.get('name'))    # john
print(r.get('score'))   # 100

# 만료 시간
r.setex('session', 3600, 'abc123')

# List 사용
r.rpush('tasks', 'task1', 'task2')
print(r.lrange('tasks', 0, -1))

캐싱 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
def get_user(user_id):
    # 캐시에서 먼저 확인
    cached = r.get(f'user:{user_id}')
    if cached:
        return json.loads(cached)
    
    # DB에서 조회
    user = db.query(f"SELECT * FROM users WHERE id = {user_id}")
    
    # 캐시에 저장 (1시간)
    r.setex(f'user:{user_id}', 3600, json.dumps(user))
    
    return user

정리

개념설명
Redis메모리 기반 Key-Value 저장소
Docker컨테이너로 Redis 실행
Port Mapping호스트 포트와 컨테이너 포트 연결
Volume데이터 영속성 보장
RDB스냅샷 기반 영속성
AOF명령 기반 영속성
TTLKey 만료 시간
This post is licensed under CC BY 4.0 by the author.