Redis 시니어 트러블슈팅 면접
새 면접Q. 운영 중인 Redis 인스턴스에서 메모리 사용량이 급격히 증가하여 OOM(Out of Memory)이 발생했습니다. INFO commandstats를 확인했더니 KEYS * 명령어가 주기적으로 실행되고 있었습니다. KEYS 명령어가 메모리 문제를 유발할 수 있는 메커니즘을 설명하고, 장애 상황에서 안전하게 키를 조회하는 방법과 재발 방지를 위한 설정 및 모니터링 전략을 제시해주세요.
KEYS 명령어의 블로킹 특성과 응답 데이터 크기, 그리고 대안 명령어를 고려해보세요.
KEYS 명령어는 O(N) 시간복잡도로 모든 키를 스캔하며 단일 스레드 이벤트 루프를 블로킹하여 다른 명령어 처리를 지연시킵니다. 수백만 개의 키가 있을 경우 결과를 메모리에 모두 적재하여 응답 버퍼가 급증하고, 클라이언트 출력 버퍼 제한을 초과하면 연결이 끊기면서 재연결 시도로 메모리가 추가 소모됩니다. 장애 상황에서는 SCAN 명령어를 cursor 기반으로 사용하여 점진적으로 키를 조회하고, rename-command 설정으로 KEYS 명령어를 비활성화하거나 이름을 변경해야 합니다. slowlog를 모니터링하여 긴 실행 시간을 가진 명령어를 추적하고, client-output-buffer-limit 설정을 적절히 조정하며, Redis 6.2 이상에서는 ACL을 활용해 위험한 명령어 실행을 제한해야 합니다. 또한 애플리케이션 레벨에서 코드 리뷰와 정적 분석 도구를 통해 KEYS 사용을 사전에 차단하는 것이 중요합니다.
- • KEYS 명령어의 O(N) 블로킹 특성과 응답 버퍼 메모리 증가
- • SCAN 명령어를 통한 커서 기반 안전한 키 조회
- • rename-command, slowlog, ACL을 활용한 재발 방지 전략
대규모 프로덕션 환경에서 모니터링 도구가 부적절하게 KEYS 명령어를 사용하여 서비스 장애를 유발하는 사례가 빈번합니다.
SCAN 명령어 사용 시 COUNT 파라미터를 어떻게 설정해야 하며, 스캔 중간에 키가 추가되거나 삭제될 때 발생할 수 있는 문제는 무엇인가요?
Q. Redis Master-Replica 구조에서 네트워크 지연이 발생하면서 Replica가 Master와 동기화가 끊어졌다가 재연결되는 상황이 반복되고 있습니다. 로그를 확인하니 계속 Full Resync가 발생하고 있습니다. Partial Resync가 실패하고 Full Resync가 반복되는 원인을 replication backlog 관점에서 분석하고, 이로 인한 성능 영향과 적절한 repl-backlog-size 산정 방법, 그리고 장애 상황에서의 대응 방안을 설명해주세요.
replication backlog buffer의 크기와 네트워크 단절 시간, 쓰기 트래픽 양의 관계를 생각해보세요.
Partial Resync는 replication backlog buffer에 Master의 쓰기 연산이 순환 버퍼 형태로 저장되어 있을 때만 가능한데, 네트워크 단절 시간 동안 발생한 쓰기 데이터가 backlog 크기를 초과하면 오래된 데이터가 덮어써지면서 Partial Resync가 실패합니다. Full Resync 시 Master는 fork()로 RDB 스냅샷을 생성하며 이 과정에서 COW로 인한 메모리 급증과 CPU 스파이크가 발생하고, 대용량 RDB 파일 전송으로 네트워크 대역폭이 포화되며 Replica는 기존 데이터를 모두 삭제하고 재적재하는 동안 읽기 서비스가 중단됩니다. repl-backlog-size는 '평균 초당 쓰기 바이트 수 × 예상 최대 단절 시간(초) × 안전 계수(2~3)'로 산정하며, 일반적으로 수백 MB에서 수 GB로 설정합니다. 장애 상황에서는 우선 repl-backlog-size를 즉시 증가시키고, repl-timeout 값을 네트워크 상황에 맞게 조정하며, 네트워크 지연 원인을 분석하여 해결해야 합니다. 모니터링으로는 INFO replication에서 master_repl_offset과 slave_repl_offset 차이, repl_backlog_size, repl_backlog_histlen을 추적해야 합니다.
- • replication backlog 크기 부족으로 Partial Resync 실패 시 Full Resync 발생
- • Full Resync의 fork, RDB 생성, 네트워크 전송으로 인한 성능 저하
- • 쓰기 속도와 단절 시간 기반 repl-backlog-size 산정 공식
클라우드 환경에서 가용 영역 간 복제 시 일시적 네트워크 불안정으로 Full Resync가 반복되어 서비스 성능 저하가 발생하는 경우가 많습니다.
Redis 4.0에서 도입된 Diskless Replication은 어떤 상황에서 유용하며, 일반 RDB 기반 복제와 비교했을 때 어떤 트레이드오프가 있나요?
Q. 애플리케이션 서버에서 Redis 연결이 간헐적으로 끊어지면서 'Connection reset by peer' 에러가 발생하고 있습니다. Redis 서버의 connected_clients 수는 정상이지만, timeout 설정은 300초로 되어 있습니다. 이 장애의 가능한 원인들을 클라이언트와 서버 양측 관점에서 분석하고, tcp-keepalive 설정의 역할과 커넥션 풀 설정 최적화 방법, 그리고 디버깅을 위해 확인해야 할 Redis 로그 및 메트릭을 설명해주세요.
방화벽, 로드밸런서의 idle timeout과 Redis의 timeout, tcp-keepalive 설정 간의 관계를 고려하세요.
연결 끊김의 주요 원인은 중간 네트워크 장비(방화벽, 로드밸런서, NAT)의 idle timeout이 Redis timeout 설정보다 짧아서 유휴 연결을 강제로 종료하는 것입니다. Redis의 timeout 설정은 클라이언트가 idle 상태일 때 서버가 연결을 끊는 시간이지만, 중간 장비는 이를 인식하지 못하고 자체 정책으로 연결을 끊습니다. tcp-keepalive 설정(기본값 300초)을 활성화하면 주기적으로 TCP keepalive 패킷을 전송하여 연결이 살아있음을 중간 장비에 알려 idle timeout을 방지할 수 있으며, 일반적으로 60초 정도로 설정합니다. 클라이언트 측에서는 커넥션 풀의 maxIdleTime을 네트워크 장비의 timeout보다 짧게 설정하고, testOnBorrow나 healthcheck를 활성화하여 사용 전 연결 상태를 검증해야 합니다. 디버깅 시에는 Redis 로그에서 'Client closed connection' 메시지를 확인하고, INFO clients에서 connected_clients, blocked_clients를 모니터링하며, CLIENT LIST로 각 클라이언트의 idle 시간과 flags를 분석해야 합니다.
- • 중간 네트워크 장비의 idle timeout과 Redis timeout 불일치 문제
- • tcp-keepalive로 주기적 패킷 전송하여 idle timeout 방지
- • 커넥션 풀의 maxIdleTime과 healthcheck 설정 최적화
AWS ELB나 방화벽의 기본 idle timeout이 60초인 경우, Redis timeout 300초와 충돌하여 연결 끊김이 빈번하게 발생합니다.
Redis 클라이언트 라이브러리에서 재연결 로직을 구현할 때 exponential backoff를 적용해야 하는 이유는 무엇인가요?
Q. Redis를 캐시로 사용하는 서비스에서 DB 업데이트 후 캐시를 삭제하는 Cache-Aside 패턴을 사용 중입니다. 그런데 간헐적으로 오래된 데이터가 캐시에 남아있는 문제가 발생하고 있습니다. Race Condition 관점에서 이 문제가 발생하는 시나리오를 분석하고, Write-Through와 Write-Behind 패턴과의 비교, 그리고 이 문제를 해결하기 위한 Delayed Delete 전략과 TTL 기반 방어 메커니즘을 설명해주세요.
DB 업데이트와 캐시 삭제 사이의 타이밍, 그리고 다른 요청의 캐시 재적재 타이밍을 고려하세요.
Cache-Aside 패턴에서 요청 A가 DB를 업데이트하고 캐시를 삭제하기 전에, 요청 B가 캐시 미스로 오래된 DB 값을 읽어 캐시에 다시 쓰고, 그 후 요청 A가 캐시를 삭제하면 요청 B가 쓴 오래된 값이 캐시에 남게 되는 race condition이 발생합니다. 또 다른 시나리오는 DB 업데이트 전 캐시 삭제 시 삭제와 DB 업데이트 사이에 다른 요청이 오래된 값을 캐시에 적재하는 경우입니다. Write-Through는 DB와 캐시를 동기적으로 업데이트하여 일관성을 보장하지만 쓰기 지연이 증가하고, Write-Behind는 캐시를 먼저 쓰고 비동기로 DB에 반영하여 성능은 좋지만 장애 시 데이터 유실 위험이 있습니다. Delayed Delete 전략은 DB 업데이트 후 즉시 삭제하고, 일정 시간(예: 1초) 후 한 번 더 삭제하여 그 사이에 적재된 오래된 캐시를 제거합니다. 또한 모든 캐시에 적절한 TTL을 설정하여 race condition으로 남은 오래된 데이터도 일정 시간 후 자동 만료되도록 하는 방어 메커니즘이 필요합니다.
- • DB 업데이트와 캐시 삭제 사이의 race condition으로 오래된 데이터 적재
- • Delayed Delete로 일정 시간 후 재삭제하여 중간에 적재된 캐시 제거
- • TTL 기반 방어 메커니즘으로 최종적 일관성 보장
전자상거래 서비스에서 상품 정보 업데이트 시 캐시 불일치로 잘못된 가격이나 재고가 표시되는 문제가 발생할 수 있습니다.
분산 환경에서 여러 애플리케이션 인스턴스가 동시에 같은 캐시 키를 업데이트할 때, 캐시 스탬피드 문제를 어떻게 방지할 수 있나요?
Q. Redis에서 대량의 데이터를 처리하는 배치 작업 중 응답 시간이 급격히 느려지고, INFO stats를 확인했더니 instantaneous_ops_per_sec가 평소의 10%로 떨어져 있습니다. MONITOR 명령어로 확인한 결과 HGETALL 명령어가 큰 해시(수만 개의 필드)에 대해 반복 실행되고 있었습니다. 이 장애의 원인을 단일 스레드 모델과 시간복잡도 관점에서 분석하고, 대용량 해시를 다루는 올바른 방법과 HSCAN 사용 전략, 그리고 재발 방지를 위한 데이터 모델링 개선 방안을 제시해주세요.
HGETALL의 O(N) 복잡도가 이벤트 루프를 블로킹하는 시간과 다른 명령어 처리 지연을 고려하세요.
HGETALL은 O(N) 시간복잡도로 해시의 모든 필드-값 쌍을 한 번에 반환하는데, 수만 개의 필드를 가진 해시에서 실행 시 수십~수백 밀리초 동안 단일 스레드 이벤트 루프를 블로킹하여 다른 모든 클라이언트 요청이 대기하게 됩니다. 이로 인해 전체 처리량이 급격히 감소하고 응답 시간이 증가하며, slowlog에 기록될 정도로 긴 실행 시간을 가지게 됩니다. HSCAN 명령어를 사용하면 cursor 기반으로 점진적으로 필드를 조회하여 각 iteration마다 짧은 시간만 블로킹하므로 다른 명령어와 인터리빙되어 처리됩니다. COUNT 파라미터로 한 번에 가져올 대략적인 필드 수를 조절할 수 있으며, 일반적으로 100~1000 정도로 설정합니다. 근본적인 해결책은 데이터 모델링 개선으로, 하나의 큰 해시를 여러 개의 작은 해시로 분할하거나(예: user:1000:profile, user:1000:settings), 필요한 필드만 HMGET으로 조회하도록 애플리케이션 로직을 변경하는 것입니다. 또한 latency monitor를 활성화하여 지연 이벤트를 추적하고, 코드 리뷰에서 O(N) 명령어 사용을 제한하는 정책을 수립해야 합니다.
- • HGETALL의 O(N) 블로킹으로 전체 처리량 저하
- • HSCAN으로 cursor 기반 점진적 조회하여 블로킹 최소화
- • 해시 분할과 필요 필드만 조회하는 데이터 모델링 개선
사용자 세션 데이터를 하나의 해시에 모두 저장하여 로그아웃 시 HGETALL로 조회하다가 서비스 전체가 느려지는 장애가 발생합니다.
Redis에서 Big Key를 탐지하고 분석하기 위해 redis-cli의 --bigkeys 옵션과 MEMORY USAGE 명령어를 어떻게 활용할 수 있나요?
Q. Redis Cluster 운영 중 특정 노드의 CPU 사용률이 90%를 넘으면서 해당 노드가 관리하는 슬롯에 대한 요청이 타임아웃되고 있습니다. CLUSTER NODES로 확인한 결과 슬롯 분배는 균등한데, 특정 슬롯에 트래픽이 집중되는 핫키 문제로 판단됩니다. 핫키를 식별하는 방법과 --hotkeys 분석 도구의 동작 원리, 그리고 핫키 문제를 해결하기 위한 클라이언트 측 캐싱과 읽기 복제본 활용 전략, 데이터 샤딩 재설계 방안을 설명해주세요.
Redis의 LFU 정보 활용, 클라이언트 측 로컬 캐시, 그리고 해시 태그의 역할을 생각해보세요.
핫키 식별은 redis-cli --hotkeys 옵션으로 가능하며, 이는 maxmemory-policy가 LFU 기반일 때 각 키의 접근 빈도 정보를 활용하거나, 전체 키스페이스를 샘플링하여 통계를 수집합니다. 또한 MONITOR 명령어로 실시간 명령어 스트림을 분석하거나, Redis 4.0 이상에서는 --memkeys로 메모리 사용량과 접근 패턴을 함께 분석할 수 있습니다. 클라이언트 측 캐싱은 Redis 6.0의 Client-side Caching 기능이나 애플리케이션 레벨 로컬 캐시(예: Caffeine, Guava Cache)를 활용하여 핫키 데이터를 로컬에 캐싱하고 짧은 TTL로 관리하여 Redis 요청을 줄입니다. 읽기 복제본 활용은 Cluster 모드에서 READONLY 명령어로 replica에서도 읽기를 허용하여 부하를 분산시키는 방법입니다. 데이터 샤딩 재설계는 핫키를 여러 키로 분할하거나(예: trending:topic:1, trending:topic:2), 해시 태그를 제거하여 같은 슬롯에 몰리는 것을 방지하고, 애플리케이션에서 라운드로빈으로 분산 조회하는 방식입니다. 또한 읽기 전용 데이터는 CDN이나 애플리케이션 캐시로 이동하는 아키텍처 개선도 고려해야 합니다.
- • redis-cli --hotkeys와 LFU 기반 핫키 식별
- • 클라이언트 측 로컬 캐싱과 READONLY를 통한 replica 읽기 분산
- • 핫키를 여러 키로 분할하고 해시 태그 제거하여 샤딩 개선
실시간 랭킹이나 인기 게시물 같은 핫 데이터가 특정 노드에 집중되어 해당 노드만 과부하되는 문제가 자주 발생합니다.
Redis 6.0의 Server-assisted Client-side Caching에서 Broadcasting 모드와 Tracking 모드의 차이점과 각각의 적합한 사용 사례는 무엇인가요?
Q. Redis AOF 모드로 운영 중인 서버가 갑자기 재시작되었는데, 시작 로그에서 'Bad file format reading the append only file' 에러가 발생하며 Redis가 기동되지 않습니다. AOF 파일이 손상된 원인으로 디스크 풀, 비정상 종료 등을 고려하여 분석하고, redis-check-aof 도구를 사용한 복구 절차와 appendfsync 설정(always, everysec, no)에 따른 데이터 유실 범위, 그리고 AOF 파일 손상을 최소화하기 위한 운영 전략을 설명해주세요.
AOF 쓰기 버퍼, fsync 타이밍, 그리고 OS 레벨 버퍼의 관계를 생각해보세요.
AOF 파일 손상의 주요 원인은 디스크 공간 부족으로 쓰기가 중단되거나, 서버 비정상 종료(kill -9, 커널 패닉, 정전) 시 OS 버퍼에 있던 데이터가 디스크에 flush되지 않아 불완전한 명령어가 기록되는 것입니다. redis-check-aof 도구로 AOF 파일을 검사하고, --fix 옵션으로 손상된 부분 이후를 잘라내어 복구할 수 있지만 잘린 부분의 데이터는 유실됩니다. appendfsync 설정에 따라 always는 매 명령마다 fsync하여 데이터 유실이 거의 없지만 성능이 크게 저하되고, everysec(기본값)는 1초마다 fsync하여 최대 1초 데이터 유실 가능성이 있으며 성능과 안전성의 균형이 좋고, no는 OS에 맡겨 성능은 최고지만 수십 초의 데이터가 유실될 수 있습니다. 운영 전략으로는 디스크 공간 모니터링을 철저히 하고, AOF rewrite 시 auto-aof-rewrite-percentage와 auto-aof-rewrite-min-size를 적절히 설정하며, RDB와 AOF를 함께 활성화하여 상호 백업하고, 정기적으로 AOF 파일을 외부 스토리지에 백업해야 합니다.
- • 디스크 풀과 비정상 종료로 인한 AOF 파일 손상
- • redis-check-aof --fix로 손상 부분 제거 및 복구
- • appendfsync 설정별 데이터 유실 범위와 성능 트레이드오프
클라우드 환경에서 디스크 IOPS 제한이나 볼륨 풀로 인해 AOF 쓰기가 실패하여 서비스 복구가 지연되는 경우가 발생합니다.
Redis 7.0에서 도입된 Multi-part AOF는 기존 단일 AOF 파일 방식과 비교했을 때 어떤 장점이 있으며, AOF rewrite 과정에서 어떻게 개선되었나요?
Q. Redis를 캐시로 사용하는 서비스에서 메모리 사용량이 계속 증가하여 maxmemory에 도달했는데, eviction이 제대로 동작하지 않아 'OOM command not allowed when used memory' 에러가 발생합니다. INFO memory를 확인했더니 used_memory는 높지만 evicted_keys는 0입니다. maxmemory-policy가 volatile-lru로 설정되어 있을 때 이 문제가 발생하는 원인을 분석하고, 각 eviction 정책의 동작 조건과 적절한 정책 선택 기준, 그리고 TTL 없는 키를 찾아 정리하는 방법을 설명해주세요.
volatile-* 정책들은 expire set이 있는 키에만 적용된다는 점을 고려하세요.
volatile-lru 정책은 TTL이 설정된 키(expire set에 속한 키)들 중에서만 LRU 알고리즘으로 제거 대상을 선택하는데, TTL이 없는 키들이 메모리의 대부분을 차지하고 있으면 제거할 수 있는 키가 없어 eviction이 동작하지 않습니다. 이 경우 메모리가 maxmemory에 도달하면 새로운 쓰기 명령이 모두 실패하게 됩니다. volatile-* 계열(volatile-lru, volatile-lfu, volatile-ttl, volatile-random)은 모두 expire set 내에서만 동작하고, allkeys-* 계열(allkeys-lru, allkeys-lfu, allkeys-random)은 모든 키를 대상으로 eviction을 수행합니다. 캐시 용도로는 allkeys-lru나 allkeys-lfu가 적합하고, TTL 기반 만료를 주로 사용하면서 보조적으로 eviction이 필요한 경우 volatile-lru를 사용합니다. TTL 없는 키를 찾는 방법은 SCAN으로 모든 키를 순회하며 TTL 명령어로 -1을 반환하는 키를 식별하거나, redis-rdb-tools를 사용해 RDB 덤프를 분석하여 expire 정보가 없는 키를 추출할 수 있습니다. 정리 시에는 DEL보다 UNLINK를 사용하여 비동기로 삭제하고, 대량 삭제는 SCAN과 파이프라인을 조합하여 점진적으로 수행해야 합니다.
- • volatile-* 정책은 TTL 있는 키만 대상으로 하여 eviction 실패 가능
- • 캐시 용도는 allkeys-lru/lfu, TTL 기반 만료는 volatile-* 선택
- • SCAN + TTL 또는 redis-rdb-tools로 TTL 없는 키 식별 및 정리
개발 단계에서 임시로 TTL 없이 저장한 키들이 프로덕션에 그대로 남아 메모리를 점유하여 eviction이 동작하지 않는 경우가 많습니다.
Redis의 LFU(Least Frequently Used) eviction에서 counter decay와 logarithmic counter의 개념은 무엇이며, 왜 이런 설계를 채택했나요?
Q. Redis MULTI/EXEC 트랜잭션을 사용하는 결제 시스템에서 간헐적으로 잔액 차감이 실패하는 문제가 발생했습니다. 로그를 확인하니 EXEC 명령어가 nil을 반환하고 있었습니다. WATCH를 사용한 낙관적 잠금에서 EXEC가 실패하는 메커니즘을 설명하고, 동시성이 높은 환경에서 재시도 로직의 문제점과 적절한 재시도 전략, 그리고 WATCH 대신 Lua 스크립트나 INCR 같은 원자적 명령어를 사용하는 것이 더 나은 상황을 설명해주세요.
WATCH한 키가 다른 클라이언트에 의해 변경될 때의 동작과 재시도 폭증 문제를 생각해보세요.
WATCH 명령어는 지정한 키를 모니터링하다가 MULTI/EXEC 사이에 다른 클라이언트가 해당 키를 변경하면 트랜잭션을 중단하고 EXEC가 nil을 반환합니다. 이는 낙관적 잠금(Optimistic Locking) 방식으로 충돌 감지 후 재시도를 통해 일관성을 보장하는데, 동시성이 높은 환경에서는 여러 클라이언트가 동시에 같은 키를 WATCH하고 수정 시도하면 대부분 실패하여 재시도가 폭증하는 thundering herd 문제가 발생합니다. 재시도 전략으로는 무한 재시도 대신 최대 재시도 횟수를 제한하고, exponential backoff나 jitter를 추가한 지연을 두어 재시도 타이밍을 분산시켜야 합니다. Lua 스크립트는 서버 측에서 원자적으로 실행되어 WATCH/MULTI/EXEC 패턴 없이도 일관성을 보장하며 네트워크 왕복이 줄어들고, INCR/DECR 같은 단일 원자적 명령어는 가장 간단하고 효율적입니다. 잔액 차감 같은 단순 증감 연산은 DECRBY를 사용하고 음수 검증은 결과값으로 처리하거나, 복잡한 로직은 Lua 스크립트로 구현하는 것이 WATCH보다 성능과 안정성이 우수합니다.
- • WATCH한 키 변경 시 EXEC가 nil 반환하며 트랜잭션 중단
- • 동시성 높은 환경에서 재시도 폭증 문제, 재시도 횟수 제한과 backoff 필요
- • Lua 스크립트나 원자적 명령어로 WATCH 없이 일관성 보장 가능
동시 접속이 많은 이벤트나 한정 수량 판매에서 WATCH 기반 재고 차감 시 대부분의 요청이 실패하고 재시도하여 성능이 급격히 저하됩니다.
Redis 트랜잭션은 Rollback을 지원하지 않습니다. 이것이 설계상 어떤 철학을 반영하며, 실무에서 이를 어떻게 보완해야 하나요?
Q. Redis 운영 중 갑자기 P99 응답 시간이 평소 1ms에서 100ms 이상으로 급증했습니다. SLOWLOG를 확인했더니 SORT 명령어가 빈번하게 기록되어 있고, 일부는 수백만 개의 요소를 가진 Set에 대해 실행되고 있었습니다. SORT 명령어의 시간복잡도와 블로킹 특성을 설명하고, SORT의 STORE 옵션과 BY/GET 파라미터 사용 시 성능 영향, 그리고 대용량 정렬이 필요한 경우 Sorted Set이나 애플리케이션 레벨 정렬로 대체하는 전략과 트레이드오프를 설명해주세요.
SORT의 O(N*log(N)) 복잡도와 외부 키 참조 시 추가 I/O를 고려하세요.
SORT 명령어는 기본적으로 O(N*log(N)) 시간복잡도를 가지며, 수백만 개의 요소를 정렬할 때 수백 밀리초에서 초 단위로 블로킹되어 다른 모든 명령어 처리가 중단됩니다. BY 파라미터로 외부 키를 참조하면 각 요소마다 GET 연산이 추가로 발생하여 O(N*M*log(N)) 수준으로 성능이 더욱 저하되고, GET 파라미터도 마찬가지로 정렬 후 각 요소의 관련 데이터를 가져오는 추가 비용이 발생합니다. STORE 옵션은 정렬 결과를 새로운 키에 저장하는데, 결과를 반복 사용할 경우 한 번만 정렬하고 캐싱하는 효과가 있지만 여전히 초기 정렬 시간은 동일합니다. Sorted Set으로 대체하면 삽입 시 자동 정렬되어 조회는 O(log(N) + M)으로 매우 빠르지만, score 기준으로만 정렬 가능하고 다중 필드 정렬이나 복잡한 정렬 로직은 불가능합니다. 애플리케이션 레벨 정렬은 Redis에서 데이터를 가져와 애플리케이션에서 정렬하는 방식으로, Redis 블로킹을 피할 수 있고 복잡한 정렬 로직 구현이 가능하지만 네트워크 전송량이 증가하고 애플리케이션 메모리와 CPU를 소모합니다. 최선의 전략은 데이터 모델링 단계에서 정렬 요구사항을 고려하여 Sorted Set을 사용하거나, 정렬된 결과를 미리 계산하여 캐싱하고, 실시간 정렬이 필요한 경우 페이징과 함께 제한된 범위만 정렬하는 것입니다.
- • SORT의 O(N*log(N)) 복잡도와 BY/GET 사용 시 추가 성능 저하
- • Sorted Set으로 자동 정렬 활용, 단 score 기준만 가능
- • 애플리케이션 레벨 정렬로 블로킹 회피, 네트워크/메모리 트레이드오프
리더보드나 검색 결과 정렬을 SORT로 구현했다가 사용자 증가 시 응답 시간이 급격히 느려지는 장애가 발생합니다.
Redis에서 복잡한 쿼리나 조인이 필요한 경우, RediSearch나 RedisJSON 같은 모듈을 사용하는 것과 별도의 검색 엔진을 사용하는 것의 장단점은 무엇인가요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!