Redis 시니어 코딩 면접

Redis 시니어 (7년+) 코딩 · 알고리즘 5문항 조회수 139 · 2026-05-03 (일) 03:11:03
1 Redis Pipeline & Transaction
Hard

Q. Redis에서 MULTI/EXEC를 사용한 트랜잭션과 Pipeline의 차이점을 설명하고, 재고 차감 시스템에서 동시성 문제를 해결하기 위해 WATCH 명령어를 활용한 Optimistic Locking을 구현하는 알고리즘 접근 방식을 설명해주세요. 또한 재시도 로직에서 고려해야 할 사항은 무엇인가요?

A. 모범답안

Pipeline은 여러 명령어를 한 번에 전송하여 네트워크 RTT를 줄이는 성능 최적화 기법이며, MULTI/EXEC는 명령어들의 원자적 실행을 보장하는 트랜잭션입니다. 재고 차감 시 WATCH로 재고 키를 모니터링하고, GET으로 현재 재고를 읽은 후, MULTI/EXEC 블록 내에서 재고를 차감하면 다른 클라이언트가 중간에 값을 변경했을 때 트랜잭션이 실패합니다. 재시도 로직에서는 최대 재시도 횟수 제한, 지수 백오프 적용, 재고 부족 시 명확한 실패 처리가 필요하며, UNWATCH를 통한 리소스 정리도 중요합니다.

핵심 포인트
  • • Pipeline은 네트워크 최적화, MULTI/EXEC는 원자성 보장이라는 서로 다른 목적
  • • WATCH는 Check-and-Set 패턴으로 낙관적 락 구현
  • • 트랜잭션 실패 시 재시도 로직에 백오프와 최대 횟수 제한 필요
  • • Lua 스크립트를 사용하면 WATCH 없이도 원자적 연산 가능
Follow-up 질문

재시도가 계속 실패하는 상황에서 성능 저하를 방지하기 위해 어떤 아키텍처 개선을 고려할 수 있을까요? Redis Lua 스크립트와 WATCH 방식의 성능 차이는 어떤가요?

2 Redis Pub/Sub
Hard

Q. Redis Pub/Sub의 메시지 전달 방식과 한계점을 설명하고, 구독자가 오프라인 상태일 때 메시지 유실 문제를 해결하기 위한 Redis Streams의 Consumer Group 구현 방식을 설명해주세요. XREADGROUP 명령어를 활용한 메시지 처리 흐름과 장애 복구 시나리오를 포함해주세요.

A. 모범답안

Redis Pub/Sub은 fire-and-forget 방식으로 구독자가 연결되어 있지 않으면 메시지가 유실되며, 메시지 영속성과 ACK 메커니즘이 없습니다. Redis Streams는 로그 구조로 메시지를 저장하고, Consumer Group을 통해 여러 소비자가 메시지를 분산 처리하며 각자 독립적인 오프셋을 관리합니다. XREADGROUP으로 메시지를 읽으면 PEL(Pending Entry List)에 저장되고, XACK로 명시적 확인 후 제거되며, 장애 발생 시 XPENDING과 XCLAIM으로 처리되지 않은 메시지를 다른 소비자가 재처리할 수 있습니다.

핵심 포인트
  • • Pub/Sub은 실시간 브로드캐스트용이지만 영속성과 신뢰성이 없음
  • • Streams는 Kafka와 유사한 로그 기반 메시징 시스템
  • • Consumer Group으로 메시지 분산 처리 및 at-least-once 보장
  • • PEL과 XCLAIM을 통한 장애 복구 메커니즘
Follow-up 질문

대용량 실시간 이벤트 처리 시스템에서 Redis Streams와 Kafka 중 어떤 것을 선택할지 결정하는 기준은 무엇인가요? XAUTOCLAIM 명령어의 활용 사례는?

3 Redis Lua Scripting
Hard

Q. Redis Lua 스크립트의 실행 원리와 제약사항을 설명하고, Rate Limiting(Sliding Window 방식)을 구현할 때 Lua 스크립트를 사용하는 이유와 알고리즘 설계 방법을 설명해주세요. EVALSHA와 스크립트 캐싱 전략도 포함해주세요.

A. 모범답안

Redis Lua 스크립트는 단일 스레드에서 원자적으로 실행되어 중간에 다른 명령어가 끼어들 수 없으며, 스크립트 내에서 여러 Redis 명령을 조합할 수 있습니다. Sliding Window Rate Limiting은 현재 시간을 기준으로 과거 윈도우 내의 요청 수를 계산해야 하는데, Sorted Set에 타임스탬프를 저장하고 ZREMRANGEBYSCORE로 오래된 항목 제거, ZCARD로 카운팅, ZADD로 추가하는 로직을 Lua로 구현하면 race condition 없이 원자적으로 처리됩니다. EVALSHA는 스크립트 해시로 실행하여 네트워크 전송량을 줄이며, SCRIPT LOAD로 사전 로드하고 NOSCRIPT 에러 시 폴백 처리가 필요합니다.

핵심 포인트
  • • Lua 스크립트는 원자성과 네트워크 왕복 감소 제공
  • • Sliding Window는 Sorted Set + Lua로 정확한 rate limiting 구현
  • • EVALSHA로 스크립트 재사용 시 성능 향상
  • • 스크립트 실행 시간이 길면 Redis 전체가 블로킹되므로 최적화 필수
Follow-up 질문

Lua 스크립트가 너무 오래 실행되어 Redis가 블로킹되는 상황을 방지하기 위한 모니터링과 대응 방안은? Fixed Window Counter 방식과 비교했을 때 Sliding Window의 메모리 오버헤드는?

4 Redis Replication & Failover
Hard

Q. Redis Sentinel을 사용한 자동 장애조치(Failover) 과정에서 Quorum과 Majority의 차이를 설명하고, split-brain 문제가 발생할 수 있는 시나리오와 이를 방지하기 위한 min-replicas-to-write, min-replicas-max-lag 설정의 역할을 설명해주세요. 또한 비동기 복제로 인한 데이터 유실 가능성을 코드 레벨에서 어떻게 처리해야 하나요?

A. 모범답안

Quorum은 마스터 장애를 감지하기 위해 필요한 Sentinel 수이고, Majority는 실제 페일오버를 승인하기 위해 필요한 과반수입니다. 네트워크 파티션 발생 시 구 마스터가 소수 파티션에 격리되어도 쓰기를 계속 받으면 데이터 유실이 발생하는데, min-replicas-to-write를 설정하면 최소 개수의 복제본이 연결되지 않으면 쓰기를 거부합니다. min-replicas-max-lag는 복제 지연 시간을 제한하여 너무 뒤처진 복제본은 카운트에서 제외합니다. 코드에서는 쓰기 실패 시 재시도 로직, WAIT 명령어로 복제 확인, 또는 애플리케이션 레벨 트랜잭션 로그로 보상 처리를 구현해야 합니다.

핵심 포인트
  • • Quorum은 장애 감지, Majority는 페일오버 승인으로 역할이 다름
  • • min-replicas 설정으로 split-brain 시 데이터 유실 최소화
  • • 비동기 복제의 특성상 일부 데이터 유실은 불가피
  • • WAIT 명령어로 동기식 복제 대기 가능하나 성능 트레이드오프 존재
Follow-up 질문

Redis Cluster 환경에서는 Sentinel 없이 자동 페일오버가 가능한데, Sentinel 방식과 비교했을 때 장단점은? WAIT 명령어 사용 시 타임아웃 설정 전략은?

5 Redis Memory Optimization
Hard

Q. 대용량 세션 저장소를 Redis로 구현할 때, Hash 자료구조의 ziplist 인코딩 최적화를 활용하는 방법을 설명하고, hash-max-ziplist-entries와 hash-max-ziplist-value 설정의 영향을 설명해주세요. 또한 수백만 개의 세션 키를 효율적으로 관리하기 위한 키 네이밍 전략과 만료 처리 알고리즘을 제시해주세요.

A. 모범답안

Hash는 작은 크기일 때 ziplist라는 연속 메모리 구조로 인코딩되어 포인터 오버헤드를 줄이고 메모리를 절약합니다. hash-max-ziplist-entries는 필드 개수 임계값, hash-max-ziplist-value는 각 값의 크기 임계값으로, 이를 초과하면 hashtable로 변환됩니다. 세션을 user:session:{user_id} 형태의 단일 Hash에 모든 필드를 저장하면 ziplist 최적화를 활용할 수 있으며, EXPIRE로 전체 세션에 TTL을 설정하고, HGETALL 대신 HMGET으로 필요한 필드만 조회합니다. 키 스캔이 필요한 경우 SCAN 명령어로 커서 기반 순회를 사용하여 블로킹을 방지하고, 세션 정리는 Redis의 자동 만료에 의존하되 애플리케이션에서 주기적인 정리 작업을 보조적으로 수행합니다.

핵심 포인트
  • • ziplist 인코딩으로 작은 Hash의 메모리 효율 극대화
  • • 임계값 설정으로 메모리와 성능의 균형 조절
  • • 키 네이밍과 TTL 전략으로 자동 만료 활용
  • • SCAN으로 대량 키 조회 시 블로킹 방지
Follow-up 질문

세션 데이터가 ziplist 임계값을 초과할 정도로 크다면 어떤 샤딩 전략을 사용할 수 있나요? Redis의 lazy free 메커니즘이 대량 만료 처리에 어떻게 도움이 되나요?

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!