data type (1)

안녕하세요, 케이치입니다.


지난 레디스 데이타 타입 포스팅을 보셨다면 아시겠지만 레디스는 기본적으로 다섯 가지의 데이타 타입을 지원합니다.


이번 포스팅에서는 레디스 데이타 타입 별 명령어 목록 및 기능 제 1편으로 스트링 타입에 대한 설명을 하려합니다.


Redis Strings

레디스 스트링 타입은 제일 기본적인 타입입니다. Memcached의 유일한 데이터 타입인 스트링을 지원하기 때문에 레디스를 새로 배우는 사람들에게도 어렵지 않죠. 뭐 스트링은 모든 프로그래밍 언어에서 제공하는 개발자들이 가장 많이 사용하는 타입 중에 하나니까요.

레디스의 키가 바로 스트링이기 때문에 값을 스트링 타입으로 저장한다는 것은 하나의 스트링을 또다른 스트링에 매핑한다는 의미입니다. 스트링 데이타 타입은 정말 많은 용도로 사용될 수 있습니다. 예를들어 HTML 일부나 페이지 전체를 캐싱할 수도 있죠.

스트링 타입을 다루는 예제를 한번 보면서 더 알아보도록 하죠. 

레디스 프롬프트 창에서 아래처럼 입력해보세요.

> set mykey somevalue
OK
> get mykey
"somevalue"

위 예제는 SET 명령어를 이용하여 mykey라는 키에 somevalue라는 값을 매핑시킵니다.  여기서 중요한 점은 SET 명령어는  동일한 키가 이미 존재한다면 그 키에 해당하는 값을 덮어쓴다는 것입니다. 그 값이 어떤 타입이냐는 상관없이 무조건 덮어쓰니 주의하시기 바랍니다. 다시말하면 SET 명령어는 자바 프로그래밍의 = 과 같이 특정 키에 특정 값을 할당해주는 기능을 합니다.

키에 할당할 수 있는 값은 어떠한 스트링이라도 가능합니다. 바이너리 데이타 역시 가능하죠. JPEG 이미지의 바이너리 데이타도 저장이 가능합니다. 하지만 여기서 또 중요한 점이 있습니다. 어떤 값이든 그 크기가 512MB를 넘을 수는 없다는 것이죠.

SET 명령어에 옵션을 줄 수도 있습니다. 예를들어 이미 해당 키가 존재하면 실패하도록 할 수도 있고 그 반대로 이미 키가 존재할 때에만 SET하도록 할 수도 있습니다. 아래와 같이 말이죠.

> set mykey newval nx
(nil)
> set mykey newval xx
OK

스트링이 레디스의 정말 기본적인 값을 나타내는 데이터 형식이지만 여러 실용적인 기능들이 있습니다. atomic increment 가 그 한 예입니다. atomic increment가 뭔지 잘 모르신다면 atomic이 뭘 의미하는지 찾아보시면 될겁니다. 여기서 그에 대한 설명은 하지 않겠습니다.

> set counter 100
OK
> incr counter
(integer) 101
> incr counter
(integer) 102
> incrby counter 50
(integer) 152

 INCR 명령어는 스트링으로 저장된 값을 숫자형태로 변환한 뒤 1을 증가시킵니다. 그리고 그렇게 증가된 값을 다시 스트링 형태로 저장합니다. 이와 비슷하게 INCRBYDECR 그리고 DECRBY 와 같은 명령어들을 레디스는 제공하고 있습니다. 이 명령어들은 내부적으로 모두 동일하게 동작합니다. 아주 미묘한 차이만 있을 뿐이죠.

INCR 가 atomic이라는게 무슨 의미냐구요? 여러명의 사용자가 동일한 키에 대해서 INCR명령어를 요청한다고 했을 때, 요청한 사용자들이 절대로 race condition에 빠질 수 없다라는 의미입니다. 즉, 사용자 1 이 10이라는 값을 읽고, 사용자 2 역시 동일한 키에 대해서 10이라는 값을 읽은 뒤 두 사용자가 1씩 값을 증가시켰을 때 최종 결과가 11이 될 수 없다는 것이죠. 최종 결과는 항상 무조건 절대로 12 가 된다는 것을 레디스는 보장해주고 있습니다. 쉽게말하면 값을 읽고, 1 증가하고, 다시 저장하는 과정이 모두 한명의 사용자가 요청했을 때 이루어지고 그 사이에 다른 사용자가 끼어들 수 없다는 말이죠.

이 외에도 스트링을 다루기 위한 여러 명령어들이 있습니다.  GETSET 명령어는 키에 존재하는 값을 읽고 새로운 값을 세팅한뒤 읽어들인 기존값을 반환합니다. 이 명령어는 방문자수를 기록할 때 사용할 수 있겠죠. 일별로 방문자수를 기록을 해야한다면 자정이 되었을 때 GETSET 명령어로 오늘 방문자수를 읽어오고 0으로 세팅해주면 되는거죠.

여러개의 키-값 페어를 저장하거나 조회하고 싶을 때에는 MSET 와 MGET 명령어를 사용하면 됩니다.

> mset a 10 b 20 c 30
OK
> mget a b c
1) "10"
2) "20"
3) "30" 

MSET은 한번에 여러 키-값 페어를 저장하는 명령어이고

 MGET 은 값의 배열을 반환합니다.

Altering and querying the key space ( 키 변경, 조회, 삭제 하기 )

레디스는 키와 관련된 여러 명령어들을 제공합니다. 키 이름 변경( 이것은 위에서 보셨죠? ), 키 목록 조회 및 존재여부 파악, 또는 삭제하기와 같은 명령어들을 말이죠.

 EXISTS 명령어는 1 또는 0 을 반환합니다. 키가 존재하거나 존재하지 않을때 말이죠.

그리고 DEL 명령어는 해당 키와 그 키에 할당된 값을 삭제합니다.

> set mykey hello
OK
> exists mykey
(integer) 1
> del mykey
(integer) 1
> exists mykey
(integer) 0

위 예제를 보시면 각 명령어가 어떻게 동작하는지 쉽게 이해가 되실겁니다.

이 명령어들 외에도 무수히 많은 key space 관련 명령어들이 있습니다. 위 두 명령어와 함께 자주 사용되는 명령어 중 하나가 바로  TYPE 명령어입니다. 이 명령어는 특정 키에 저장되어있는 값의 타입을 반환합니다. 아래 예제를 보시죠.

> set mykey x
OK
> type mykey
string
> del mykey
(integer) 1
> type mykey
none

처음에 set mykey x 로 키 mykey에 값 x를 등록했습니다. 그리고 type mykey 로 mykey에 저장된 값 x의 타입을 조회해 보니 string이 나왔네요. 그 다음엔 mykey를 삭제했습니다. 그리고 다시 조회를 해보니 none 이라고 나왔네요. 해당 키에 저장된 값이 없다는 얘기겠죠.

Redis 키에 TTL (Time To Live)설정하기 

이건 단지 스트링 타입 뿐만 아니라 모든 타입에 적용되는 것이긴 합니다만 다른 타입의 데이터를 얘기하기 전에 짚고 넘어가야 할 것 같습니다. 기본적으로 키에 타임아웃 시간을 설정할 수 있습니다. 설정된 타임아웃 시간이 지나면 자동으로 키는 삭제됩니다. 이때 삭제되는것은 사용자가 직접 DEL 명령어로 삭제하는 것과 완전히 동일하게 삭제가 되는 것입니다.

 Redis expires 와 관련하여 아래 내용을 숙지하시기 바랍니다.

  • 기본적으로 밀리초 단위로 동작한다.
  • 초 단위 또는 밀리 초 단위로 만료되기 까지의 시간을 설정할 수 있다.
  • 만료일시와 관련된 정보는 디스크에 복제되어 저장되고 레디스 서버가 멈춰도 재기동 될때 현재 일시와 비교하여 삭제한다.

만료일시를 지정하는 방법은 아주 쉽습니다. 아래 예제를 한번 보시죠.

> set key some-value
OK
> expire key 5
(integer) 1
> get key (위 명령어를 입력하자마자 바로 실행)
"some-value"
> get key (5초 뒤에 실행)
(nil)

위 예제는 어떤 값을 저장한 뒤 5초로 만료시간을 지정해주고 두 번의 GET 을 호출할 때 만료시간에 따라 값이 조회가 되는지 안되는지를 확인해본 것입니다. 5초 뒤에 만료되라고 지정해주었으니 5초 뒤에는 nil이라고 뜨는 것을 확인할 수 있었습니다. 

여기서는 EXPIRE 명령어를 이용해서 만료일시를 지정해주었는데 만약에 이 만료일시를 없애기 위해서는 PERSIST 명령어를 사용할 수 있습니다. 그리고 EXPIRE명령과 동일한 기능을 SET 명령어의 옵션을 이용해서 적용할 수도 있습니다.

> set key 100 ex 10
OK
> ttl key
(integer) 9

위 예제는 키 key에 값 100을 저장하는데 10초 후에 만료되어 파기하라는 옵션을 덧붙였습니다. 그리고나서  TTL 명령어로 키 key의 만료되기 전까지의 시간(초)을 조회를 해보니 9가 나왔네요. (참고로 TTL은 Time To Live 의 약자입니다.)

초 단위가 아닌 밀리초 단위로 설정을 하려면, PEXPIRE 와 PTTL 명령어를 참고하시면 됩니다. 또는 PEXPIRE대신 SET 명령어의 옵션을 이용할 수도 있습니다.



위 내용은 레디스 공식 문서에 나와있는 내용을 스터디 할 겸 개인적으로 번역한 내용입니다.