REDIS는 BSD 라이센스 기반의 Key-value 캐쉬 & Store 소프트웨어다. String, hash, lists, sets, sorted set, bitmap, hyperloglogs 등 다양한 데이터 구조를 저장할 수 있기 때문에, data structure server라고 부르기도 한다.
메모리에 데이터를 쓰는 In memory 데이터베이스 그리고 NoSQL 데이터베이스로 분류된다. 데이터에 대한 읽기와 쓰기가 많은 서비스에 사용 할 수 있다. Memcached와 비슷한 스팩을 가지고 있는데, 다양한 유형의 데이터를 지원한다는게 장점이다.
일단 REDIS를 빠르게 설치하고, 몇몇 기능들을 테스트 한 다음에 곧바로 응용 프로그램을 만들어 볼 것이다.
# redis-server --version
Redis server v=2.8.13 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=cee0f9a49c3c27aa
Redis 클라이언트 설치
Redis-server를 테스트하기 위해서, redis-client에 redis 클라이언트 프로그램을 설치했다.
# apt-get install redis-tools
서버 연결 테스트
# redis-cli -h 192.168.57.2 ping
PONG
성공 !!!. 시작이 절반인데, 연결 테스트까지 했으니 75%는 끝난거라고 봐야 겠네.
Redis 자료구조 테스트
Redis-cli를 이용해서 자료구조를 테스트 한다.
# redis-cli -h 1972.168.57.2
>
Strings
키에 대한 값으로 문자열(string)를 저장한다. 단순한 타입으로, redis를 사용한다고 하면 가장 먼저 고려해볼만한 타입이다. JSON, XML등 문자열로 된 데이터들을 저장할 수 있다. 웹 서비스를 한다면, HTML 문서의 전체 혹은 일부분을 캐쉬하기 위해서 사용할 수 있다.
> set mykey myvalue
OK
> get mykey
"myvalue"
SET을 이용해서 값을 저장하고, GET을 이용해서 값을 가져올 수 있다. 이미 있는 key에 대해서 값을 설정하면, 값을 덮어쓴다.
특이한 점은 string이라고 해서 문자열만 저장하는게 아니고, 바이너리(binary) 데이터도 저장할 수 있다는 거다(그냥 바이너리 데이터를 저장할 수 있습니다 하면 좋았을 것을) png이미지를 저장하고, 읽는 테스트를 해봤다.
# cat test.png | redis-cli -h 192.168.57.2 -x set myimage
OK
# redis-cli -h 192.168.57.2 get myimage > ok.png
MSET과 MGET을 이용해서 한 번에 여러 개의 key, value를 저장하고 읽을 수 있다.
> MSET key1 "Hello" key2 "world"
OK
> get key1
"Hello"
> get key2
"world"
> mget key1 key2
1) "Hello"
2) "world"
리스트
LPUSH를 이용해서 리스트의 맨 앞(왼쪽-left)에, RPUSH를 이용해서 리스트의 맨 뒤에 값을 밀어넣을 수 있다. LRANGE로 일정 범위의 값을 읽을 수 있다.
> rpush mylist A
(integer) 1
> rpush mylist B
(integer) 2
> lrange mylist 0 -1
1) "A"
2) "B"
> lpush mylist first
(integer) 3
> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
LRANGE는 시작과 끝을 위한 두 개의 index 값이 필요하다. 인덱스가 마이너스(-)이면, 리스트의 끝(오른쪽)을 기준으로 인덱스 값을 메긴다. 오른쪽 끝의 인덱스는 -1이다. 따라서 "0 -1"은 0번째 부터 마지막 까지의 범위를 의미한다.
한번에 여러개의 값을 저장할 수도 있다.
ltirm을 이용해서 인덱스 0에서 2사이의 값만 남기고, 삭제해버렸다. 일반적인 경우에는 처음 값이 아닌, 마지막 값을 남기는게 더 유용할 것이다. 이런 류의 서비스를 위해서는 LPUSH와 LTRIM을 사용하면 된다.
LPUSH myliste <값들>
LTRIM mylist 0 99
이렇게 하면 최근 100개의 값만 유지할 수 있다.
Blocking operation on lists
REDIS는 list 데이터 타입에 대해서 Blocking operation을 지원한다.
list로 부터 값을 꺼내기(POP)위한 가장 방법은 주기적으로 rpop를 호출하는 것이다. 이 방식은 주기를 조절하는게 애매모호하기 때문에 그다지 좋아 보이지 않는다. POP을 호출하는 시점에 읽을 데이터가 없다면, 읽을 데이터가 준비될 때까지 blocking 되는게 깔끔해 보인다. 한번의 호출로 데이터를 읽을 수 있기 때문이다.
BRPOP과 BLPOP 명령을 이용하면, blocking 작업이 가능하다. 이들 명령을 호출하면, 데이터가 없을 경우 데이터가 준비될 때까지 block된다. 물론 block 시간 설정도 가능하다.
> brpop tasks 5
rpush로 데이터를 밀어 넣어보자.
> rpush tasks 1 2 3
(integer) 3
실행 결과 결과
> brpop tasks 5
1) "tasks"
2) "3"
(3.50s)
하나 이상의 리스트로 부터 가져오는 것도 가능하다.
> BRPOP list1 list2 5
그런데, Range로 가져올 수가 없어서 brpop만 사용하기에는 좀 애매모호하다. 예를들어 list에 한번에 10개의 값을 밀어 넣었을 경우, brpop를 10번을 연속 호출하게 된다. 이 문제는 brpop로 값을 가져온 후에, lrange 0, -1등을 호출하는 식으로 해결해야 할 것 같다. 혹은 결과를 모아서 하나의 리스트에 보내는 식의 소프트웨어 방법을 적용할 수 있을거다.
Hash
Hash는 값으로 field&value의 쌍으로 이루어진 테이블을 저장할 수 있는 데이터 타입이다.
ZADD의 사용법은 SADD와 비슷하다. 정렬에 사용 할 score 매개변수가 하나 더 추가된다는 것만 다르다. 이제 값을 가져 오면 score를 키로 정렬된 결과를 받아볼 수 있다. Sorted set은 값을 입력 할 때, 정렬이 되기 때문에, O(long(N))의 시간 복잡도를 가진다.
독립적인 데이터 타입이라고 하기에는 좀 애매모호 하다. 바이너리 데이터에 대한 bit 연산 기능이라고 봐야 겠다. setbit 로 bit를 설정할 수 있고, getbit로 bit 설정 여부(1인지)를 확인할 수 있다.
Bitmap의 가장 큰 장점은 0과 1의 상태를 가지는 아이템들을 대단히 효율적으로 저장하고, 읽을 수 있다는데 있다. 하루 동안의 유니크 방문자를 계산해야 한다고 가장해보자. 유저가 방문할 때, 유저 아이디에 해당하는 bit 값을 1로 만들어 주는 걸로 간단하게 유저의 방문여부를 알 수 있다. 이때 필요한 메모리는 단지 1bit이기 때문에 512MB의 메모리로 40억(512 * 1024 * 1024 * 8)의 유저의 방문정보를 기록할 수 있다.
> setbit visitor 10 1 # 10번 유저 방문
> setbit visitor 1000 1 # 1000번 유저 방문
> setbit visitor 101 1 # 101번
> setbit visitor 16
> getbit visitor 16 # 16번 고객 방문 여부
(integer) 1
> getbit visitor 15 # 15번 고객 방문 여부
(integer) 0
> bitcount visitor # 방문 유저 수
(integer) 4
HyperLogLogs
어떤 데이터셋에서 집합에서 유일한 원소의 갯수를 검사하기 위해서 사용하는 알고리즘이다. 세익스피어 전집에서 unique한 단어의 갯수를 계산하려면 매우 큰 메모리가 필요할 것이다. HyperLogLogs를 이용하면 약간의 오차를(대략 1billion에 대해서 2% 정도) 허용하는 대신 매우 작은 메모리로 유니크한 원소의 갯수를 검사할 수 있다. 셰액스 피어의 전집에 나오는 유일한 영어 단어 개수를 세는 것으로 비교하자면, HashSet을 이용할 경우 10,4447,016 크기의 메모리가 필요한 반면, HyperLogLogs는 512바이트가 필요하다. 물론 Hashet의 오차는 0%, HyperLogLogs는 3%의 오차가 발생한다.
Contents
REDIS 소개
REDIS 설치 및 테스트
환경
Redis 서버 설치
Redis 클라이언트 설치
Redis 자료구조 테스트
Strings
리스트
Capped Lists
Blocking operation on lists
Hash
Set
Sorted Set
Operation on ranges
Lexicographical scores
Bitmaps
HyperLogLogs
Redis 프로그래밍 테스트
참고
Recent Posts
Archive Posts
Tags