Redis 키와 값
Redis 키와 값 (Keys and values)
Redis 데이터베이스에 저장하는 모든 데이터 객체에는 고유한 키(key) 가 있어요. 키는 Redis 명령에 전달해서 해당 객체를 검색하거나 데이터를 수정하는 데 쓰는 문자열입니다. 특정 키와 연관된 데이터 객체를 값(value) 이라고 하고, 둘을 합쳐 키-값 쌍(key-value pair) 이라고 해요.
출처: 공식문서
키의 내용
키는 보통 데이터 모델 안에서 어떤 의미를 가진 텍스트상의 이름이에요. 프로그래밍 언어의 변수 이름과 달리 Redis 키는 형식에 대한 제한이 거의 없어서, 공백이나 구두점 문자가 있는 키(예: "1st Attempt", "% of price in $")도 대부분 괜찮아요. Redis는 키에 대한 네임스페이스나 다른 범주를 지원하지 않으므로, 이름 충돌을 피하는 데 주의해야 해요. 하지만 콜론 ":" 문자로 키를 섹션으로 나누는 관례가 있어요(예: "person:1", "person:2", "office:London", "office:NewYork:1"). 이것을 키를 범주로 모으는 간단한 방법으로 쓸 수 있어요.
키는 보통 텍스트지만, Redis는 실제로 바이너리 안전(binary-safe) 키를 구현하므로 JPEG 파일이나 애플리케이션의 구조체 값 같은 어떤 바이트 시퀀스도 유효한 키로 쓸 수 있어요. 빈 문자열도 Redis에서 유효한 키입니다.
키에 대해 염두에 둬야 할 몇 가지가 더 있어요:
- 매우 긴 키는 좋은 생각이 아니에요. 예를 들어 1024바이트 키는 메모리 측면에서도 나쁘지만, 데이터셋에서 키를 조회할 때 여러 번의 비싼 키 비교가 필요할 수 있기 때문이에요. 당면한 작업이 큰 값을 존재 여부를 맞추는 것일 때도, 특히 메모리와 대역폭 관점에서 (예: SHA1로) 해싱하는 것이 더 좋은 아이디어예요.
- 매우 짧은 키도 흔히 좋은 생각이 아니에요. "u1000flw" 대신 "user:1000:followers"라고 쓸 수 있다면 그게 낫습니다. 후자가 더 읽기 쉽고, 추가 공간은 키 객체 자체와 값 객체가 쓰는 공간에 비해 미미해요. 짧은 키가 당연히 메모리를 조금 덜 소비하지만, 여러분의 일은 올바른 균형을 찾는 것입니다.
- 스키마를 고수하세요. 예를 들어 "object-type:id"는 "user:1000"처럼 좋은 아이디어예요. 여러 단어 필드에는 점이나 대시를 자주 쓰는데, "comment:4321:reply.to" 또는 "comment:4321:reply-to"처럼요.
- 키의 최대 크기는 512MB입니다.
해시태그
Redis는 해싱을 써서 키와 연관된 값을 매우 효율적으로 검색합니다. 해싱은 키의 raw 바이트 값을 결합해 정수 인덱스 번호를 생성하는 것을 수반합니다. 그 인덱스는 키의 값이 저장된 해시 슬롯(hash slot) 을 찾는 데 쓰입니다.
보통 키 전체가 해시 인덱스를 계산하는 데 쓰이지만, 키의 일부만 해싱해야 하는 상황이 있어요. 중괄호 {...} 쌍으로 해시태그(hashtag) 를 만들어 해싱할 키 섹션을 선택할 수 있어요. 예를 들어 키 person:1과 person:2는 다른 해시 인덱스를 만들지만 {person}:1과 {person}:2는 같은 인덱스를 만들어요. 중괄호 안의 person 해시태그 부분만 해시 계산에 쓰이기 때문입니다.
해시태그의 일반적인 용도는 클러스터된 데이터베이스에서 다중 키 연산을 허용하는 것입니다(자세한 내용은 Database clustering 참고). 클러스터된 데이터베이스에서 모든 키가 같은 해시 인덱스를 만들지 않으면 Redis는 대부분의 다중 키 연산을 허용하지 않아요. 예를 들어 SINTER 명령은 두 개의 서로 다른 set 값의 교집합을 구합니다. 즉 다음 명령은
SINTER group:1 group:2
클러스터된 데이터베이스에서는 동작하지 않지만
SINTER {group}:1 {group}:2
은 동작하는데, 해시태그가 두 키가 같은 해시 인덱스를 만들도록 보장하기 때문이에요.
해시태그는 특정 경우에 유용하지만, 일반적으로 습관처럼 쓰면 안 된다는 점에 주의하세요. 같은 해시 슬롯에 매핑된 키가 너무 많으면 결국 데이터베이스 성능을 해치게 됩니다. 해시태그 사용법에 대한 자세한 내용은 Database clustering을 참조하세요.
키스페이스 변경 및 조회
특정 타입에 정의되지 않았지만 키의 공간과 상호작용하는 데 유용해서, 어떤 타입의 키와도 함께 쓸 수 있는 명령들이 있어요.
예를 들어 EXISTS 명령은 주어진 키가 데이터베이스에 존재하는지 여부를 알리기 위해 1 또는 0을 반환하고, DEL 명령은 값에 상관없이 키와 연관된 값을 삭제해요.
> set mykey hello
OK
> exists mykey
(integer) 1
> del mykey
(integer) 1
> exists mykey
(integer) 0
예시에서 DEL 자체가 키가 제거됐는지(존재했음) 또는 아니었는지(그 이름의 키가 없었음)에 따라 1 또는 0을 반환하는 것도 볼 수 있어요.
키스페이스 관련 명령은 많지만, 위 두 가지가 지정된 키에 저장된 값의 종류를 반환하는 TYPE 명령과 함께 필수적인 것들이에요:
> set mykey x
OK
> type mykey
string
> del mykey
(integer) 1
> type mykey
none
키 만료(expiration)
계속하기 전에, 저장하는 값의 타입과 무관하게 동작하는 중요한 Redis 기능을 살펴봐야 해요. 바로 키 만료입니다. 키 만료는 키에 대한 타임아웃을 설정하게 해주는데, "time to live" 또는 "TTL"이라고도 해요. time to live가 지나면 키는 자동으로 파괴됩니다.
키 만료에 관한 몇 가지 중요한 점:
- 초 단위나 밀리초 단위 정밀도로 설정할 수 있어요.
- 하지만 만료 시간 해상도는 항상 1밀리초예요.
- 만료에 대한 정보는 복제되고 디스크에 영속화되며, 시간은 Redis 서버가 정지된 동안에도 사실상 흐릅니다(즉 Redis는 키가 만료될 날짜를 저장한다는 뜻이에요).
EXPIRE 명령으로 키의 만료를 설정하세요:
> set key some-value
OK
> expire key 5
(integer) 1
> get key (immediately)
"some-value"
> get key (after some time)
(nil)
두 번째 GET 호출이 5초보다 더 지연됐으므로 키는 두 호출 사이에 사라졌어요. 위 예시에서 만료를 설정하기 위해 EXPIRE를 썼어요(이미 만료가 있는 키에 다른 만료를 설정하는 데에도 쓸 수 있고, PERSIST는 만료를 제거하고 키를 영구적으로 만드는 데 쓸 수 있어요). 하지만 다른 Redis 명령을 써서 만료가 있는 키를 만들 수도 있어요. 예를 들어 SET 옵션으로요:
> set key 100 ex 10
OK
> ttl key
(integer) 9
위 예시는 문자열 값 100을 가진 키를 10초의 만료와 함께 설정해요. 나중에 TTL 명령이 키의 남은 time to live를 확인하는 데 호출됩니다.
밀리초로 만료를 설정·확인하려면 PEXPIRE와 PTTL 명령, 그리고 SET 옵션 전체 목록을 확인하세요.
키스페이스 탐색
Scan
Redis 데이터베이스의 키를 효율적으로 점진적으로 순회하려면 SCAN 명령을 쓸 수 있어요.
SCAN은 점진적 순회를 허용해서 호출당 소수의 요소만 반환하므로, 큰 키·요소 컬렉션에 대해 호출될 때 서버를 오랫동안(몇 초까지도) 블로킹할 수 있는 KEYS나 SMEMBERS 같은 명령의 단점 없이 프로덕션에서 쓸 수 있어요.
하지만 SMEMBERS 같은 블로킹 명령은 주어진 순간에 Set의 일부인 모든 요소를 제공할 수 있어요. 반면 SCAN 명령족은, 점진적으로 순회하는 컬렉션이 순회 과정 중에 변할 수 있으므로, 반환된 요소에 대해 제한적인 보장만 제공합니다.
Keys
키스페이스를 순회하는 또 다른 방법은 KEYS 명령을 쓰는 것이지만, KEYS는 모든 키가 반환될 때까지 Redis 서버를 블로킹하므로 이 접근법은 주의해서 써야 해요.
경고: KEYS는 극도로 주의해서 프로덕션 환경에서만 사용해야 하는 명령으로 간주하세요.
KEYS는 큰 데이터베이스에 대해 실행하면 성능을 망칠 수 있어요. 이 명령은 디버깅과 특수 연산(키스페이스 레이아웃 변경 같은)을 위한 것입니다. 일반 애플리케이션 코드에서는 KEYS를 쓰지 마세요. 키스페이스의 부분집합에서 키를 찾는 방법을 찾고 있다면 SCAN 또는 sets을 고려하세요.
지원되는 glob 스타일 패턴:
h?llo은hello,hallo,hxllo와 일치h*llo은hllo와heeeello와 일치h[ae]llo은hello와hallo,와 일치하지만hillo와는 불일치h[^e]llo은hallo,hbllo, ...와 일치하지만hello와는 불일치h[a-b]llo은hallo와hbllo와 일치
특수 문자를 있는 그대로 일치시키려면 \로 이스케이프하세요.
더 알아보기 (Learn more)
- 다중 키 연산
- Redis 데이터 타입
- Redis 공식 키와 값 문서