Redis 다중 키 연산
Redis 다중 키 연산 (Multi-key operations)
Redis의 다중 키 연산은 단일 명령으로 여러 키를 다룰 수 있게 해주지만, 그 동작은 Redis 설정과 클러스터링 구성에 따라 크게 달라져요. 이 페이지는 다양한 Redis 구성에서 다중 키 연산을 다루는 개발자를 위한 빠른 참조자료예요.
출처: 공식문서
구성(Configurations)
Redis는 서로 다른 다중 키 명령 동작을 보이는 다섯 가지 구성을 지원합니다:
- ROS/RS 클러스터링 비활성 - 단일 Redis 인스턴스
- ROS, 클러스터링 활성 - Redis 오픈소스 클러스터
- RS, 클러스터링 활성, OSS 클러스터 API 활성 - ROS 클러스터 호환성을 가진 Redis Software
- RS, 클러스터링 활성, OSS 클러스터 API 비활성 - Redis Software 독점 클러스터링
- RS, Active-Active - Redis Software Active-Active (단일 샤드여도 클러스터로 간주)
ROS는 Redis Open Source, RS는 Redis Software를 뜻합니다.
명령 동작
각 구성에서 명령은 세 가지 동작 중 하나를 보여줘요:
- single-slot: 명령은 같은 해시 슬롯 안의 키에만 동작해야 합니다
- cross-slot (all shards): 명령은 클러스터의 모든 샤드에 걸쳐 동작할 수 있어요
- cross-slot (within a single shard): 명령은 슬롯을 걸쳐 동작할 수 있지만 단일 샤드 안에서만 동작해요
읽기 전용 명령
| 동작 | 명령 |
|---|---|
| ROS/RS 클러스터링 비활성: – 전체 DB (단일 샤드) ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성): – 현재 샤드 RS 클러스터링 활성 (OSS 클러스터 API 비활성): – 모든 샤드 |
DBSIZE, KEYS, SCAN |
| ROS/RS 클러스터링 비활성: – cross-slot ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성): – single-slot RS 클러스터링 활성 (OSS 클러스터 API 비활성): – cross-slot (all shards) |
EXISTS, MGET |
| ROS/RS 클러스터링 비활성: – cross-slot ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성), RS 클러스터링 활성 (OSS 클러스터 API 비활성): – single-slot |
PFCOUNT, SDIFF, SINTER, SINTERCARD, SUNION, WATCH, XREAD, XREADGROUP, ZDIFF, ZINTER, ZINTERCARD, ZUNION |
| ROS/RS 클러스터링 비활성: – cross-slot ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성), RS 클러스터링 활성 (OSS 클러스터 API 비활성): – single-shard |
JSON.MGET 사용자는 CROSSSLOT 오류를 받지 않아요. 하지만 클러스터링이 켜졌고 지정된 모든 키가 같은 슬롯에 없으면, 현재 샤드의 모든 슬롯에 대해 부분 결과를 받습니다. |
| ROS/RS 클러스터링 비활성: – cross-slot (all shards) ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성), RS 클러스터링 활성 (OSS 클러스터 API 비활성): – cross-slot (all shards), 트랜잭션의 일부가 될 수 없음 |
TS.MGET, TS.MRANGE, TS.MREVRANGE, TS.QUERYINDEX |
읽기-쓰기 명령
| 동작 | 명령 |
|---|---|
| ROS/RS 클러스터링 비활성: – 전체 DB (단일 샤드) ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성): – 현재 샤드 RS 클러스터링 활성 (OSS 클러스터 API 비활성): – 모든 샤드 |
FLUSHALL, FLUSHDB |
| ROS/RS 클러스터링 비활성: – cross-slot ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성): – single-slot RS 클러스터링 활성 (OSS 클러스터 API 비활성): – cross-slot (all shards) |
DEL, MSET, TOUCH, UNLINK 참고: Active-Active에서는 DEL, MSET, UNLINK가 single-slot |
| ROS/RS 클러스터링 비활성: – cross-slot ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성), RS 클러스터링 활성 (OSS 클러스터 API 비활성): – single-slot |
BITOP, BLMOVE, BLMPOP, BLPOP, BRPOP, BRPOPLPUSH, BZMPOP, BZPOPMAX, BZPOPMIN, CMS.MERGE, COPY, GEORADIUS or GEORADIUSBYMEMBER (with STORE or STOREDIST), GEOSEARCHSTORE, JSON.MSET, LMOVE, LMPOP, MSETNX, PFMERGE, RENAME, RENAMENX, RPOPLPUSH, SDIFFSTORE, SINTERSTORE, SMOVE, SUNIONSTORE, TDIGEST.MERGE, TS.MADD, ZDIFFSTORE, ZINTERSTORE, ZMPOP, ZRANGESTORE, ZUNIONSTORE |
| ROS/RS 클러스터링 비활성: – cross-slot ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성), RS 클러스터링 활성 (OSS 클러스터 API 비활성): – single-shard |
TS.CREATERULE, TS.DELETERULE 사용자는 CROSSSLOT 오류를 받지 않아요. 하지만 클러스터링이 켜졌고 두 지정 키가 같은 슬롯에 없으면 (error) ERR TSDB: the key does not exist를 받습니다. |
파이프라인, 트랜잭션, 스크립트
| 동작 | 연산 |
|---|---|
| ROS/RS 클러스터링 비활성: – cross-slot ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성): – single-slot RS 클러스터링 활성 (OSS 클러스터 API 비활성): – cross-slot (all shards) |
파이프라인 |
| ROS/RS 클러스터링 비활성: – cross-slot ROS 클러스터링 활성, RS 클러스터링 활성 (OSS 클러스터 API 활성), RS 클러스터링 활성 (OSS 클러스터 API 비활성): – single-slot |
MULTI/EXEC 트랜잭션 안의 키EVAL 또는 EVALSHA로 실행하는 Lua 스크립트 안의 키 |
구성별 예시
단일 인스턴스 (클러스터링 없음)
단일 Redis 인스턴스에서는 모든 다중 키 연산이 제약 없이 동작해요:
# 파이프라인 연산은 어떤 키에도 동작합니다
PIPELINE
SET user:1 "Alice"
SET product:100 "Widget"
GET user:1
GET product:100
EXEC
# 트랜잭션은 어떤 키에도 동작합니다
MULTI
SET counter:a 1
SET counter:b 2
INCR counter:a
INCR counter:b
EXEC
클러스터 환경
클러스터 환경에서는 슬롯 분포를 고려해야 해요:
# 키가 다른 슬롯에 있으면 실패할 수 있습니다
MSET user:1 "Alice" user:2 "Bob"
# 해시 태그를 써서 같은 슬롯을 보장하세요
MSET {users}:1 "Alice" {users}:2 "Bob"
# 키가 어떤 슬롯에 속하는지 확인하세요
CLUSTER KEYSLOT user:1
CLUSTER KEYSLOT {users}:1
Active-Active 데이터베이스
Active-Active 데이터베이스에는 쓰기 연산에 대한 추가 제약이 있어요:
# 읽기 연산은 슬롯을 걸쳐 동작할 수 있습니다
MGET user:1 user:2 product:100
# 쓰기 연산은 같은 슬롯에 있어야 합니다
MSET {data}:user:1 "Alice" {data}:user:2 "Bob"
다중 키 연산 문제 해결
일반적인 오류 메시지
- CROSSSLOT: 요청의 키들이 같은 슬롯으로 해시되지 않음
- MOVED: 키가 다른 노드로 이동됨 (resharding 중)
- TRYAGAIN: 연산이 일시적으로 사용 불가 (마이그레이션 중)
해결 방법
- 해시 태그(hash tags) 사용 - 연관된 키를 그룹화
- 데이터 모델 재설계 - cross-slot 연산 최소화
- 오류 중 클러스터 상태 확인
- 일시적 실패에 대한 재시도 로직 구현
성능 고려 사항
- Single-slot 연산은 조정(coordinator)이 필요 없어 가장 빠릅니다
- Cross-slot 연산은 내부 라우팅 때문에 지연이 더 높을 수 있어요
- 패턴 명령(KEYS, FLUSHALL)은 모든 샤드를 스캔해서 비쌀 수 있습니다
- 모듈 연산은 최적화된 cross-slot 구현을 가질 수 있어요
자신의 다중 키 연산 요구사항에 맞춰 Redis 구성을 선택하고 데이터 모델을 설계하세요.
더 알아보기 (Learn more)
- 데이터베이스 클러스터링
- Redis 클러스터 규격
- Redis 공식 다중 키 연산 문서