명령 키 스펙
명령 키 스펙 (Command key specifications)
명령 키 스펙이 무엇이고 클라이언트에서 어떻게 쓰는가.
출처: 공식문서
Redis의 많은 명령은 키 이름을 입력 인수로 받습니다. COMMAND(와 COMMAND INFO) 응답의 9번째 요소는 명령의 키 스펙들로 구성된 배열입니다.
키 스펙(key specification)은 주어진 명령의 인수에서 하나 이상의 키 이름을 추출하는 규칙을 설명합니다. 키 스펙은 Redis 7.0까지 쓰이던 first key, last key, step 방식에 비해 견고하고 유연한 메커니즘을 제공합니다. 이 스펙이 도입되기 전에 Redis 클라이언트는 모든 명령에 대해 키 이름을 추출할 사소한 프로그램적 수단이 없었습니다.
클러스터 인지(cluster-aware) Redis 클라이언트는 EVAL, ZUNIONSTORE처럼 numkeys 인수에 의존하는 명령이나 SORT와 그 많은 절들에 대해 키 추출 로직을 하드코딩해야 했습니다. 대안으로 COMMAND GETKEYS를 쓰면 비슷한 추출 효과를 얻지만 지연(latency)이 더 높습니다.
Redis 클라이언트가 키 스펙을 지원할 의무는 없습니다. 변경되지 않은 채 유지되는 legacy first key, last key, step 방식과 movablekeys 플래그를 계속 쓸 수 있습니다.
그러나 키 스펙 지원을 구현하는 Redis 클라이언트는 키 추출 로직의 대부분을 통합할 수 있습니다. 클라이언트가 익숙하지 않은 타입의 키 스펙을 만나도 항상 COMMAND GETKEYS 명령으로 폴백할 수 있습니다.
그렇긴 해도, 대부분의 클러스터 인지 클라이언트는 올바른 명령 라우팅에 단일 키 이름만 필요하므로, 명령에 익숙하지 않은 스펙이 하나 있다 해도 다른 스펙은 클라이언트가 쓸 수 있을 가능성이 있습니다.
키 스펙은 다음 키를 가진 맵입니다:
begin_search: 키 추출의 시작 인덱스find_keys: BS(시작)를 기준으로 키를 식별하는 규칙notes: 있으면 이 키 스펙에 대한 참고 사항flags: 데이터 접근의 타입을 나타냄
begin_search
스펙의 begin_search 값은 추출의 시작을 클라이언트에 알립니다. 값은 맵입니다. 세 가지 타입이 있습니다:
index: 키 이름 인수가 상수 인덱스에서 시작keyword: 키 이름이 특정 키워드(토큰) 뒤에서 시작unknown: 알 수 없는 타입의 스펙 — incomplete 플래그 섹션 참고
index
index 타입의 begin_search는 입력 키가 상수 인덱스에 나타남을 나타냅니다. spec 키 아래 맵이며 단일 키를 가집니다:
index: 클라이언트가 키 이름 추출을 시작해야 하는 0-기반 인덱스
keyword
keyword 타입의 begin_search는 리터럴 토큰이 키 이름 인수 앞에 옴을 의미합니다. spec 아래 두 키를 가진 맵입니다:
keyword: 키 이름 인수의 시작을 표시하는 키워드(토큰)startfrom: 클라이언트가 검색을 시작해야 하는 인수 배열에 대한 인덱스. 음수일 수 있는데, 이는 인수 배열 끝에서 역순으로 검색을 시작해야 함을 의미. 예:-2는 끝에서 두 번째 인수부터 역방향으로 검색
keyword 검색 타입의 추가 예:
SET은 값 1의index타입 begin_search 스펙을 가짐XREAD는"STREAMS"와 1을 각각 keyword와 startfrom으로 하는keyword타입 begin_search 스펙을 가짐MIGRATE는"KEYS"와-2를 가진keyword타입 start_search 스펙을 가짐
find_keys
키 스펙의 find_keys 값은 키 이름 검색을 어떻게 계속할지 클라이언트에 알립니다. find_keys에는 세 가지 가능한 타입이 있습니다:
range: 키가 특정 인덱스에서 또는 마지막 인수 기준 상대 위치에서 멈춤keynum: 추가 인수가 입력 키 개수를 지정unknown: 알 수 없는 타입의 스펙 — incomplete 플래그 섹션 참고
range
range 타입의 find_keys는 spec 키 아래 세 키를 가진 맵입니다:
lastkey: 마지막 키 인수의, begin_search 기준 인덱스. 음수일 수 있고, 이 경우 상대가 아님. 예:-1은 마지막 인수까지 계속 키를 추출하라는 뜻,-2는 끝에서 하나 전까지, 등keystep: 키를 찾은 후 다음 키를 찾기 위해 건너뛰어야 하는 인수 개수limit:lastkey가-1이면 factor로 검색을 멈추는 데 limit을 씀. 0과 1은 제한 없음. 2는 남은 인수의 절반, 3은 1/3, 등
keynum
keynum 타입의 find_keys는 spec 키 아래 세 키를 가진 맵입니다:
keynumidx: 키 개수를 담은 인수의, begin_search 기준 인덱스firstkey: 첫 키의, begin_search 기준 인덱스. 보통 keynumidx의 다음 인수이며, 이 경우 값이 1만큼 큼keystep: 키를 찾은 후 다음 키를 찾기 위해 건너뛰어야 하는 인수 개수
예:
SET명령은 0, 1, 0의 range를 가짐MSET명령은 -1, 2, 0의 range를 가짐XREAD명령은 -1, 1, 2의 range를 가짐ZUNION명령은 값 1의index타입 start_search와 0, 1, 1 값을 가진keynum타입 find_keys를 가짐
참고: 모듈 작성자가 어떤 것이든 만들어낼 수 있으므로 완벽한 해결책은 아닙니다. 그러나 이 메커니즘은 대다수 명령의 키 이름 인수 추출을 가능하게 해야 합니다.
notes
적용 가능한 경우, 자명하지 않은 키 스펙 고려사항에 대한 참고 사항.
flags
키 스펙은 키에 대한 더 많은 세부 정보를 제공하는 추가 플래그를 가질 수 있습니다. 이 플래그들은 아래 설명과 같이 세 그룹으로 나뉩니다.
접근 타입 플래그 (Access type flags)
다음 플래그들은 명령이 키의 값 또는 메타데이터에 사용하는 접근 타입을 선언합니다. 키 메타데이터에는 LRU/LFU 카운터, 타입, 카디널리티가 포함됩니다. 이 플래그들은 클라이언트에 보내는 응답과는 무관합니다.
모든 키 스펙은 다음 플래그 중 정확히 하나를 가집니다:
RW: 읽기-쓰기 플래그. 명령이 키 값 또는 메타데이터에 저장된 데이터를 수정함. 명확히 삭제, 덮어쓰기, 읽기-전용이 아닌 모든 작업을 표시RO: 읽기-전용 플래그. 명령이 키의 값만 읽음(반드시 반환하는 것은 아님)OW: 덮어쓰기 플래그. 명령이 키 값에 저장된 데이터를 덮어씀RM: 제거 플래그. 명령이 키를 삭제함
논리 연산 플래그 (Logical operation flags)
다음 플래그들은 키 값과 그 TTL(있으면)에 저장된 데이터에 대해 수행되는 연산 타입을 선언합니다(메타데이터는 아님). 이 플래그들은 명령이 입력 인수에 따라 데이터에 실행하는 논리 연산을 설명합니다. 메타데이터(키 타입, 카디널리티, 존재 같은)의 수정·반환과는 무관합니다.
모든 키 스펙은 다음 플래그를 포함할 수 있습니다:
access: 접근 플래그. 명령이 키에 저장된 사용자 데이터를 반환, 복사, 또는 어떻게든 사용함을 나타냄
추가로 스펙은 다음 중 정확히 하나를 포함할 수 있습니다:
update: 갱신 플래그. 명령이 키 값에 저장된 데이터를 갱신함. 새 값은 이전 값에 의존할 수 있음. 명확히 삽입이나 삭제가 아닌 모든 작업을 표시insert: 삽입 플래그. 명령이 값에 데이터를 추가만 함; 기존 데이터는 수정·삭제되지 않음delete: 삭제 플래그. 명령이 키에 저장된 값에서 데이터를 명시적으로 삭제함
기타 플래그 (Miscellaneous flags)
키 스펙은 다음 플래그를 가질 수 있습니다:
not_key: 지정된 인수가 키가 아님을 나타냄. Redis 클러스터에서 명령이 할당되어야 할 슬롯을 계산할 때는 이 인수를 키처럼 취급함. 그 외 모든 목적으로는 키로 간주해서는 안 됨incomplete: 아래에서 설명variable_flags: 아래에서 설명
incomplete
일부 명령은 키를 지정하는 방법이 이색적이라 추출이 어렵습니다. 예를 들어 AUTH 절의 인수로 리터럴 문자열 "KEYS"를 포함하는 MIGRATE 호출에서 무슨 일이 일어날지 생각해 보세요. 키 스펙은 빗나가고, 추출이 잘못된 인덱스에서 시작할 것입니다.
따라서 키 스펙이 불완전해 모든 키를 추출하지 못할 수 있음을 인지합니다. 그러나 명령이 문법적으로 올바르다면, 불완전한 스펙조차 결코 잘못된 키 이름을 내놓지 않는다는 것을 보장합니다.
MIGRATE의 경우 검색이 끝에서 시작합니다(startfrom 값이 -1). "KEYS"라는 이름의 키를 만나면 그 뒤의 키 이름 인수 하위 집합만 추출합니다. 그래서 MIGRATE가 키 스펙에 incomplete 플래그를 갖는 이유입니다.
불완전성의 또 다른 경우는 SORT 명령입니다. 여기서 begin_search와 find_keys가 unknown 타입입니다. 클라이언트는 네이티브 구현 없이 인수에서 키 이름을 추출하려면 COMMAND GETKEYS 명령 호출로 폴백해야 합니다. 예를 들어 문자열 "STORE"가 SORT의 키워드(토큰)이자 유효한 리터럴 인수이기 때문에 어려움이 발생합니다.
참고: 불완전한 키 스펙을 가진 유일한 명령은 SORT와 MIGRATE입니다. 앞으로 이런 명령이 추가될 것이라고 기대하지 않습니다.
variable_flags
일부 명령에서 같은 키 이름 인수의 플래그가 다른 인수에 의존할 수 있습니다. 예를 들어 SET 명령과 선택적 GET 인수를 고려하세요. GET 인수 없이 SET은 쓰기-전용이지만, 그것이 있으면 읽기-쓰기 명령이 됩니다. 이 플래그가 있으면 키 스펙 플래그가 모든 가능한 옵션을 덮지만, 유효 플래그는 다른 인수에 의존함을 의미합니다.
예제
SET 키 스펙
1) 1) "flags"
2) 1) RW
2) access
3) update
3) "begin_search"
4) 1) "type"
2) "index"
3) "spec"
4) 1) "index"
2) (integer) 1
5) "find_keys"
6) 1) "type"
2) "range"
3) "spec"
4) 1) "lastkey"
2) (integer) 0
3) "keystep"
4) (integer) 1
5) "limit"
6) (integer) 0
ZUNION 키 스펙
1) 1) "flags"
2) 1) RO
2) access
3) "begin_search"
4) 1) "type"
2) "index"
3) "spec"
4) 1) "index"
2) (integer) 1
5) "find_keys"
6) 1) "type"
2) "keynum"
3) "spec"
4) 1) "keynumidx"
2) (integer) 0
3) "firstkey"
4) (integer) 1
5) "keystep"
6) (integer) 1
더 알아보기 (Learn more)
- Redis 명령 팁 (Command tips)
- Redis 클러스터 확장 (Scaling with Redis Cluster)
- Redis 클라이언트 라이브러리로 연결하기