사내 서비스 중 Redis 에서 Lua 를 많이 사용하여 이번 기회에 Lua 메모리 관련하여 정리해 보았습니다.

 

Lua 스크립트란 ?

  • 스크립트 언어로써, 문자열 함수와 수학 함수를 제공
  • 그래픽 시뮬레이션을 위한 스크립트 언어로 개발된 언어로써 타 스크립트 언어보다 빠른 성능을 제공
  • 변수를 제거하거나 미리 선언을 위한 별도의 처리가 필요 없음

 

Redis 에서 Lua 스크립트

  • 프로그래밍 방식 제어구조를 사용하고 db에 access 하여 실행하는 대부분의 명령을 사용 가능
    • redis.call('set', key, value) 형태
  • 지역 변수를 사용해야 함
    • ex) 변수 선언 시 : local src = keys[1]
  • eval 명령어를 이용하여 수행하고자 하는 스크립트를 redis로 전송하여 사용 가능
  • script load 명령을 이용하여 redis server에 등록 시킨 후 사용 가능
    • 데이터가 존재하는 곳에서 실행되기 때문에 전체 대기 시간 뿐만 아니라 네트워크 리소스 절약 가능
    • Application 로직의 일부를 Redis 내에서 실행이 가능하며 여러키에 걸쳐 조건부 업데이트 수행 가능하며 다른 데이터 유형을 함께 처리도 가능
  • Script는 Lua 엔진(Lua5.1) 에 의해 실행
  • 기본적으로 Eval script는 클라이언트 일부로 간주하기 때문에 서버에 persistence 하게(영구) 저장이 되지 않기에(단순 Caching-휘발성), Redis server가 재시작 되거나 한다면 re-Load 해야 함
    • 7.0에서 부터는 redis function 추가 프로그래밍 로직으로 서버 자체를 확장할 수 있는 프로그래밍 가능성에 의해 persitence 하게 저장이 가능 (모든 client에서 사용이 가능)
    • 7.0 부터는 read-only script 가 가능 (read replica에서 지원)
    • https://redis.io/docs/manual/programmability/
  • 메모리 각 내용
    • used_memory_lua :   Lua 엔진에 의해 사용된 메모리 크기 (byte)
    • used_memory_scripts :  5.0 추가   (mh->lua_caches) 생성된 루아 스크립트가 사용하는 메모리 양
      • 모니터링 진행 할 때 used_memory_scripts  를 확인하면 되며, set 명령어만 이루어진 스크립트는 별도로 used_memory_scripts  영역이 변경되지 않음
    • redis server에서 실행되는 lua script는 원자성(Atomicity)하게 처리된다. (lua가 실행되는 동안 다른 레디스 명령어는 실행 안되는 것을 의미-다른 모든 명령어 차단)
      • 이 부분은 single thread 때문이 아닐까...
    • 스크립트 내용이 동일한 동작!!!을 하더라도, 조금이라도 다르다면 다른 스크립트로 인식 하기 때문에, 의미만 변경되는 스크립트 들에 대해서는 변수 처리로 하여 사용하면 캐싱 절약 효과를 얻을 수 있음
#아래는 동일한 동작을 하지만 내용이 다르기 때문에 서로 다른 내용으로 인식하여 used_memory_lua / used_memory_scripts 값 둘다 변경
eval "return 'hellow world?'" 0
eval "return 'hellow world????'" 0

#아래는 동일한 내용을 호출한 경우 캐싱되어 있기 때문에 memory 변화값이 없음을 확인
eval "return 'hellow world????'" 0
eval "return 'hellow world????'" 0

 

테스트 1.

 

이번에는 재밌는 테스트를 진행 하였다.
동일한 redis 구문이지만, return 을 하고 안하고의 차이 이다.
둘다 명령어는 get 명령어로 값을 리턴을 하지만, 이것을 결국 client까지 return을 하느냐 안 하느냐 차이일 것 같은데, 스크립트는 역시 이것을 다른 script로 인식을 하는 것을 확인

eval "redis.call('get', 'lua_test_2555')" 0
eval "return redis.call('get', 'lua_test_2555')" 0
  • 당연히 get 명령어이고 lua script를 호출이기 때문에 used_memory_scripts / used_memory_lua 모두 값이 변경 된 것을 확인할 수 있다.

  • 이번에는 명령어는 동일하지만 return 을 하는 명령어 실행
    • used_memory_scripts / used_memory_lua 모두 값이 변경 된 것을 확인할 수 있다.

  • 당연하겠지만, 기존에 캐싱되어 있는 영역을 다시 조회 시
    • used_memory_scripts / used_memory_lua 모두 값이 변경 되지 않은 것을 확인

  • 결국은 lua 는 내부 모두 동일해야 동일한 script로 인식하여 캐싱 여부를 사용할지 정하는 척도
    • 데이터 변경이 일어나는 곳이라면 당연히 파라메터로 작성하여 사용 하는 것을 의미하며 이렇게 사용할 것을 권고

테스트 2.

  • 추가로 set 명령어는 lua 엔진을 사용할 뿐, used_memory_scripts 의 값이 변경 되는 내역은 없음
    • 기존 get 명령어나 return 하는 명령어의 경우 used_memory_scripts  값이 변경 되는 것을 확인할 수 있으나, 오로지 set 명령어의 경우 lua engine 의 값만 변경(used_memory_lua ) 되는 것을 확인 할  수 있다.
local src = KEYS[1]  
for i=1, src, 2 do  
	local test_key = 'lua_test_' .. i  
	redis.call('set', test_key, i)  
end;  
-> 한마디로 set lua_test_홀수번호 홀수번호  
EVAL "local src = KEYS[1] for i=1, src, 2 do local test_key = 'lua_test_' .. i redis.call('set', test_key, i) end;"
  1. 초기 값 확인
    1. used_memory_lua : 32768 / used_memory_scripts : 0 / number_of_cached_scripts : 0  
  2. lua 스크립트로 캐싱 진행
    1. used_memory_lua : 33792 / used_memory_scripts : 216 / number_of_cached_scripts : 1
    2. lua 엔진 및 메모리에 적재 된 것을 확인 (스크립트 등록 시 기본 동작 하는 것으로 확인)
  3. lua 스크립트 실행
    1. used_memory_lua : 63488 / used_memory_scripts : 216 / number_of_cached_scripts : 1
    2. lua 엔진은 사용하였지만, get 명령어 같이 조회 하거나 하는 것이 아니기 때문에 lua 메모리 쪽에 적재 되는 것은 없는 것으로 확인
  4. 다시 한번 lua 스크립트 실행
    1. 동일하게 lua 엔진은 사용하였지만, memory 는 사용 하지 않은 것을 확인
    2. 바로 lua 로 실행 하여도 동일하게  engine 은 사용하지만, memory는 변경 되지 않는 것을 확인 완료

결론

  • 동일한 의미로 보이는 Lua 스크립트라고 하더라도, 내용이 조금이라도 다르면 서로 다른 스크립트로 인식
  • 동일한 명령어 이라고 하더라도, return  의 유무에 따라 위의 의미와 같이 서로 다른 스크립트로 인식
  • set 명령어로만 이루어진 lua  스크립트는, 별도의 메모리를 사용하지 않음 (lua 엔진만 메모리 사용)
  • 그 외 메모리 사용률을 확인 하기 위해서는 used_memory_scripts  를 모니터링 하며, used_memory_lua 는 평소와 비슷한지 체크하면 좋을 듯 합니다.
  • Elasticache 를 이용한다면, Lua script 내용이 get 형태의 읽기로만 이루어진 내용이라면, read를 이용하는 것을 추천합니다.(Lua의 수행속도가 오래 걸린다면 write 뿐만 아니라 redis 자체가 싱글 스레드로 동작하기 때문에 대기를 하게 되지만, 적어도 read를 이용한다면 write에 대해서만큼은 영향을 덜 미치기 때문 / 하지만 Lua 성능 최적화는 꼭 합시다.)

그외

AWS 의 경우 Cloudwatch 상에서 Elasticache 지표에서는 used_momory_scripts / lua 등을 제공을 하지 않기 때문에 BytesUsedForCache 와 FreeableMemory 의 변화로 모니터링 하는 것으로 우회 하거나, 해당 지표를 직접 조회하여 모니터링 하는 것을 추천 드립니다.

 

참고

다양한 샘플을 참고 할 수 있음 : https://bstar36.tistory.com/348
https://redis.io/docs/manual/programmability/eval-intro/
AWS  Support 최원 님 도움 주셔서 감사합니다.

반응형

한번 더 말씀드리지만 저는 redis에 대해서 거의 모릅니다...

공부해 가는 단계지만 그래도 한글로 된 내용이 거의 없어서 공유해 봅니다.

(제가 못 찾은게 맞는듯 싶습니다.)


각설하고 이제 공유 진행하겠습니다.




AWS ec2 에 올린 redis4.0을 백업과 모니터링 문제로 고민하다가

Elasticache 로 옮기는 것에 대해 고민하게 되었다.


정확하게는 내가 아닌 다른 팀에 의해서.


redis의 r도 모르는 내가 직접 찾아보면서 관련 내용은 좀 있어 보이나,

제대로 이해하기도 힘들었고, 한글로 된 내용도 없어서 애를 좀 먹었다.


아래 github 자료의 도움으로 무사히 테스트까지 완료 할 수 있었다.


https://github.com/p/redis-dump-load


참고로 해당 스크립트는 python으로 개발 되었으며 나는 오로지 가지고 사용하기만 했다..ㅠ


내용은 아래와 같다.

1. redis에서 dump를 받아 해당 내용을 json 으로 추출

2. json 파일로 추출된 내용을 Elasticache로 Load 진행

>> json 파일가지고 커스터 마이징을 한다면 다른 DB로 Import도 가능할 것으로 예상


사용방법은 잘 나와있지만, 공유 차원으로...


Export (현재 redis에서 실행하는데, -d 옵션은 해당 추출하고자 하는 DB 를 뜻함)

$ python redisdl.py -H localhost -d 1 > susun_dump.json


Import (Elasticache 로 진행 / H옵션은 elasticache로 다이렉트 접속이 안되기 때문에 ec2에서 elasticache로 접속할 때 해당 주소host  / d옵션으로 2번 DB에 import 하였으며, -l 옵션을 사용하여 import 한다고 명령)

$ python redisdl.py -H apn2.cache.amazonaws.com -d 2 -l < susun_dump.json


내 과제는 python 커스터 마이징 하는것이 나의 또다른 과제..


반응형

Redis를 기존에는 개발자들이 관리 하였지만,

이제는 DBA가 관리하는게 더 수월할 것 같아서 관리하기에 앞서 선행 학습중이다.


이리저리 접속 진행해 보았지만,

관리자는 콘솔에서도 작업이 기본!!!이라고 생각하기에


콘솔로 접속 후 데이터 확인을 하기 시작했다.


기본 명령어도 모르니 확인하는건 불가능....


여러모로 찾다가 노하우를 찾아 공유해 본다.


여러 redis 블로그를 보면 기본적으로 사용 방법만 나와있지,

어떻게 확인하는지는 못찾아서 꺼이꺼이 찾아서 공유해 본다.


1. select 로 db??? 선택

(rdbms는 db를 생성하지만 redis는 정해져 있다. 1 ~ 15까지 / select 1 또는 select 15 이런식으로 선택)


2. RANDOMKEY 를 사용하여 또는 KEYS * 를 사용하여 해당 KEY들 검색


 - keys * 를 하게 되면 모든 키가 검색된다.

 - 10만개의 데이터를 테스트로 저장했기에 만건이 표시된다.

..

중략...

..


3. 확인하고 싶은 KEY 의 type 확인을 위해 type 키내용 확인

- string으로 저장했기에...(단순히 set 으로 INSERT 하였다)


4. 해당 Key 타입에 맞는 명령어를 찾아 내용확이

- 명령어를 모른다면 아래 참조 사이트에서 찾아보자..


명령어 참고 사이트 : http://redisgate.kr/redis/command/commands.php


하아....정말 가급적 관리자가 아니라면 RedisDesktopManager 를 설치해서 간편하게 확인하는 것이 편할 듯 싶다.



반응형

★ Redis Replication 구성 방법은 아래 블로그 참조

- 정말 쉽게 작성하여서 나도 쉽게 구성을 완료 하였다.

- 아쉽게도 replication 관련해서 check 방법에 대해서는 잘 나와 있지 않아 아쉬움 부분이 있다.

http://jdm.kr/blog/157


★ Redis HA 구성 방법은 동일 블로그 내에 참조

- 아직 진행은 하지 않았지만 별 문제 없이 가능하도록 잘 설명되어 있음

http://jdm.kr/blog/159


★ 주요 설정값

http://jdm.kr/blog/139

maxmemory 2mb
maxmemory-policy allkeys-lru


추후 MongoDB 진행하면서 이 분 블로그 참조하면 빨리 익힐 수 있을 듯 싶다.



다음 참조하면 좋을 블로그(사이트)

★ redis 구성 시 어떤 부분을 유의하면서 실무에 적용하면 좋을 지 설명하는 내용

http://redisgate.kr/redis/configuration/replication.php


오랜만에 블로그 하는 만큼 좋은 정보를 공유해야 하는데...퍼온 거라니...에휴...ㅠ


sql server 나름 한것들에 대해서 공유도 해야 하지만...이건 정리하는게 삼만리라...포기..ㅠ


다음으로는 mongo DB를 R&D 하는 것이며, 다음 게임 프로젝트는 mongoDB를 고려해볼까 한다....

반응형

Redis를 직접 관리하기 위해 MongoDB와 함께 nosql 에 대해 공부를 시작하였다.


그 중 현재 사용하였던 redis 내용을 보기 위해 접속을 진행 하였다.


개발자 분들에 의해 관리가 되어 오다 보니, 


히스토리도 없었으며, 알고 계시는 분이 거의 없었다.


redis를 테스트DB에서 설치하여 진행하다가 실무에 사용된 redis를 접속하려고 했더니


접속이 거절되었다.

$redis-cli

Could not connect to Redis at 127.0.0.1:6379: Connection refused

not connected>


왜 접속이 안되는거야!!!


몇번의 검색을 해도 나오지를 않아서 mysql 처럼 IP접속 권한과 비슷하지 않을까 해서 시도 했더니

정상적으로 접속이 되었다.


-- 혹시나 해서 redis 가 down 되어 있는지 확인


$ ps -ef | grep redis

redis     1204     1  0 Jan04 ?        01:04:04 /usr/bin/redis-server 192.168.1.101:6379

root    13423 12834  0 13:35 pts/0    00:00:00 grep redis


--redis가 정상적으로 올라와 있구나..
-- 혹시나 해서 -h 옵션을 사용해서 아이피를 적어 봤다.

$ redis-cli -h 로컬아이피

로컬아이피:6379>


ex) $ redis-cli -h 192.168.1.101

192.168.1.101:6379>


접속이 되는구나!!!



사소한 것일지 모르겠지만 모르는 사람에게는 순간 당황할 수 있는 상황...


깨알 지식 공유

반응형
Redis 관련해서 기초 이해하기 위해 아래 블로그도 많은 도움이 되었다.
물론 해당 내용이 2012년도? 내용이기에 변경된 부분도 조금 있다.

아래 내용의 경우 현재 Cluster 가 개발되어 있다.

현재 버전 2.4.15에서는 Clustering을 지원하지 않아서 Sharding을 사용할 수 밖에 없지만 2012년 내에 Clustering기능이 포함된다고 하니, 확장성에 대해서 기대해볼만하다. redis가 지원할 clustering 아키텍쳐는 ( http://redis.io/presentation/Redis_Cluster.pdf ) 를 참고하기 바란다.

Redis Cluster

Link : http://www.redisgate.com/redis/cluster/cluster.php


조만간에 Redis 설치 테스트 하여 업로드할 계획이다.

여러가지를 이것저것 해보는 것이 좋을 수도 있지만...너무 조급심을 내고 있지 않는가 걱정도 된다.




출처 : http://bcho.tistory.com/654


redis Introduction


Intro
Redis는 "REmote DIctionary System"의 약자로 메모리 기반의 Key/Value Store 이다.
Cassandra나 HBase와 같이 NoSQL DBMS로 분류되기도 하고, memcached와 같은 In memory 솔루션으로 분리되기도 한다.
성능은 memcached에 버금가면서 다양한 데이타 구조체를 지원함으로써 Message Queue, Shared memory, Remote Dictionary 용도로도 사용될 수 있으며, 이런 이유로 인스탄트그램, 네이버 재팬의 LINE 메신져 서비스, StackOverflow,Blizzard,digg 등 여러 소셜 서비스에 널리 사용되고 있다.
BSD 라이센스 기반의 오픈 소스이며 최근 VMWare에 인수되어 계속해서 업그레이드가 되고 있다.
16,000 라인정도의 C 코드로 작성되었으며, 클라이언트 SDK로는
Action Script,C,C#,C++,Clojure,Erlang,Java,Node.js,Objective-C,Perl,PHP,Python,Smalltalk,Tcl등 대부분의 언어를 지원한다. (참고 : http://www.redis.io/clients )

이번 글에서는 Redis란 무엇인지, 그리고 대략적인 내부 구조에 대해서 살펴보도록 한다.

1. Key/Value Store
Redis는 기본적으로 Key/Value Store이다. 특정 키 값에 값을 저장하는 구조로 되어 있고 기본적인 PUT/GET Operation을 지원한다.

단, 이 모든 데이타는 메모리에 저장되고, 이로 인하여 매우 빠른 write/read 속도를 보장한다. 그래서 전체 저장 가능한 데이타 용량은 물리적인 메모리 크기를 넘어설 수 있다. (물론 OS의 disk swapping 영역등을 사용하여 확장은 가능하겠지만 성능이 급격하게 떨어지기 때문에 의미가 없다.)
데이타 억세스는 메모리에서 일어나지만 server restart 와 같이 서버가 내려갔다가 올라오는 상황에 데이타를 저장을 보장하기 위해서 Disk를 persistence store로 사용한다.

2. 다양한 데이타 타입
단순한 메모리 기반의 Key/Value Store라면 이미 memcached가 있지 않은가? 그렇다면 어떤 차이가 있길래 redis가 유행하는 것일까?
redis가 Key/Value Store이기는 하지만 저장되는 Value가 단순한 Object가 아니라 자료구조를 갖기 때문에 큰 차이를 보인다.
redis가 지원하는 데이타 형은 크게 아래와 같이 5가지가 있다.

1) String
일반적인 문자열로 최대 512mbyte 길이 까지 지원한다.
Text 문자열 뿐만 아니라 Integer와 같은 숫자나 JPEG같은 Binary File까지 저장할 수 있다.

2) Set
set은 string의 집합이다. 여러개의 값을 하나의 Value 내에 넣을 수 있다고 생각하면 되며 블로그 포스트의 태깅(Tag)등에 사용될 수 있다.
재미있는 점은 set간의 연산을 지원하는데, 집합인 만큼 교집합, 합집합, 차이(Differences)를 매우 빠른 시간내에 추출할 수 있다.

3) Sorted Set
set 에 "score" 라는 필드가 추가된 데이타 형으로 score는 일종의 "가중치" 정도로 생각하면 된다.
sorted set에서 데이타는 오름 차순으로 내부 정렬되며, 정렬이 되어 있는 만큼 score 값 범위에 따른 쿼리(range query), top rank에 따른 query 등이 가능하다.


4) Hashes
hash는 value내에 field/string value 쌍으로 이루어진 테이블을 저장하는 데이타 구조체이다.
RDBMS에서 PK 1개와 string 필드 하나로 이루어진 테이블이라고 이해하면 된다.


5) List
list는 string들의 집합으로 저장되는 데이타 형태는 set과 유사하지만, 일종의 양방향 Linked List라고 생각하면 된다. List 앞과 뒤에서 PUSH/POP 연산을 이용해서 데이타를 넣거나 뺄 수 있고, 지정된 INDEX 값을 이용하여 지정된 위치에 데이타를 넣거나 뺄 수 있다. 


6) 데이타 구조체 정리
지금까지 간략하게 redis가 지원하는 데이타 구조체들에 대해서 살펴보았다.
redis의 데이타 구조체의 특징을 다시 요약하자면
  • Value가 일반적인 string 뿐만 아니라, set,list,hash와 같은 집합형 데이타 구조를 지원한다.
  • 저장된 데이타에 대한 연산이나 추가 작업 가능하다. (합집합,교집합,RANGE QUERY 등)
  • set은 일종의 집합, sorted set은 오름차순으로 정렬된 집합, hash는 키 기반의 테이블, list는 일종의 링크드 리스트 와 같은 특성을 지니고 있다.
이러한 집합형 데이타 구조 (set,list,hash)등은 redis에서 하나의 키당 총 2^32개의 데이타를 이론적으로 저장할 수 있으나, 최적의 성능을 낼 수 있는 것은 일반적으로 1,000~5,000개 사이로 알려져 있다.

데이타 구조에 따른 저장 구조를 정리해서 하나의 그림에 도식화해보면 다음과 같다.



3. Persistence
앞서도 언급하였듯이, redis는 데이타를 disk에 저장할 수 있다. memcached의 경우 메모리에만 데이타를 저장하기 때문에 서버가 shutdown 된후에 데이타가 유실 되지만, redis는 서버가 shutdown된 후 restart되더라도, disk에 저장해놓은 데이타를 다시 읽어서 메모리에 Loading하기 때문에 데이타 유실되지 않는다.
redis에서는 데이타를 저장하는 방법이 snapshotting 방식과 AOF (Append on file) 두가지가 있다.

1) snapshotting (RDB) 방식
순간적으로 메모리에 있는 내용을 DISK에 전체를 옮겨 담는 방식이다.
SAVE와 BGSAVE 두가지 방식이 있는데,
SAVE는 blocking 방식으로 순간적으로 redis의 모든 동작을 정지시키고, 그때의 snapshot을 disk에 저장한다.
BGSAVE는 non-blocking 방식으로 별도의 process를 띄운후, 명령어 수행 당시의 메모리 snaopshot을 disk에 저장하며, 저장 순간에 redis는 동작을 멈추지 않고 정상적으로 동작한다.
  • 장점 : 메모리의 snapshot을 그대로 뜬 것이기 때문에, 서버 restart시 snapshot만 load하면 되므로 restart 시간이 빠르다.
  • 단점 : snapshot을 추출하는데 시간이 오래 걸리며, snapshot 추출된후 서버가 down되면 snapshot 추출 이후 데이타는 유실된다.
    (백업 시점의 데이타만 유지된다는 이야기)
2) AOF 방식
AOF(Append On File) 방식은 redis의 모든 write/update 연산 자체를 모두 log 파일에 기록하는 형태이다. 서버가 재 시작될때 기록된  write/update operation을 순차적으로 재 실행하여 데이타를 복구한다. operation 이 발생할때 마다 매번 기록하기 때문에, RDB 방식과는 달리 특정 시점이 아니라 항상 현재 시점까지의 로그를 기록할 수 있으며, 기본적으로 non-blocking call이다.
  • 장점 : Log file에 대해서 append만 하기 때문에, log write 속도가 빠르며, 어느 시점에 server가 down되더라도 데이타 유실이 발생하지 않는다.
  • 단점 : 모든 write/update operation에 대해서 log를 남기기 때문에 로그 데이타 양이 RDB 방식에 비해서 과대하게 크며, 복구시 저장된 write/update operation을 다시 replay 하기 때문에 restart속도가 느리다.
3) 권장 사항
RDB와 AOF 방식의 장단점을 상쇠하기 위해서 두가지 방식을 혼용해서 사용하는 것이 바람직한데
주기적으로 snapshot으로 백업하고, 다음 snapshot까지의 저장을 AOF 방식으로 수행한다.
이렇게 하면 서버가 restart될 때 백업된 snapshot을 reload하고, 소량의 AOF 로그만 replay하면 되기 때문에, restart 시간을 절약하고 데이타의 유실을 방지할 수 있다.


4. Pub/Sub Model
redis는 JMS나 IBM MQ 같은 메세징에 활용할 수 있는데, 1:1 형태의 Queue 뿐만 아니라 1:N 형태의 Publish/Subscribe 메세징도 지원한다.(Publish/Subscribe 구조에서 사용되는 Queue를 일반적으로 Topic이라고 한다.)
하나의 Client가 메세지를 Publish하면, 이 Topic에 연결되어 있는 다수의 클라이언트가 메세지를 받을 수 있는 구조이다. (※ Publish/Subscribe 형태의 messaging 에 대해서는 http://en.wikipedia.org/wiki/Pub/sub  를 참고하기 바란다.)


재미있는 것중에 하나는 일반적인 Pub/Sub 시스템의 경우 Subscribe 하는 하나의 Topic에서만 Subscribe하는데 반해서, redis에서는 pattern matching을 통해서 다수의 Topic에서 message 를 subscribe할 수 있다.
예를 들어 topic 이름이 music.pop music,classic 이라는 두개의 Topic이 있을때, "PSUBSCRIBE music.*"라고 하면 두개의 Topic에서 동시에 message를 subscribe할 수 있다.

5. Replication Topology
redis는 NoSQL 계열의 Key/Store Storage인데 반해서 횡적 확장성을 지원하지 않는다.
쉽게 말해서 2.4.15 현재 버전 기준으로는 클러스터링 기능이 없다. (향후 지원 예정)
그래서 확장성(scalability)과 성능에 제약사항이 있는데, 다행이도 Master/Slave 구조의 Replication(복제)를 지원하기 때문에 성능 부분에 있어서는 어느정도 커버가 가능하다.

Master/Slave replication
Master/Slave Replication이란, redis의 master node에 write된 내용을 복제를 통해서 slave node에 복제 하는 것을 정의한다.
1개의 master node는 n개의 slave node를 가질 수 있으며, 각 slave node도 그에 대한 slave node를 또 가질 수 있다.


이 master/slave 간의 복제는 Non-blocking 상태로 이루어진다. 즉 master node에서 write나 query 연산을 하고 있을 때도 background로 slave node에 데이타를 복사하고 있다는 이야기고, 이는 master/slave node간의 데이타 불일치성을 유발할 수 있다는 이야기이기도 하다.
master node에 write한 데이타가 slave node에 복제중이라면 slave node에서 데이타를 조회할 경우 이전의 데이타가 조회될 수 있다.

Query Off Loading을 통한 성능 향상
그러면 이 master/slave replication을 통해서 무엇을 할 수 있냐? 성능을 높일 수 있다. 동시접속자수나 처리 속도를 늘릴 수 있다. (데이타 저장 용량은 늘릴 수 없다.) 이를 위해서 Query Off Loading이라는 기법을 사용하는데
Query Off Loading은 master node는 write only, slave node는 read only 로 사용하는 방법이다.
단지 redis에서만 사용하는 기법이 아니라, Oracle,MySQL과 같은 RDBMS에서도 많이 사용하는 아키텍쳐 패턴이다.
대부분의 DB 트렌젝션은 웹시스템의 경우 write가 10~20%, read가 70~90% 선이기 때문에, read 트렌젝션을 분산 시킨다면, 처리 시간과 속도를 비약적으로 증가 시킬 수 있다. 특히 redis의 경우 value에 대한 여러가지 연산(합집합,교집합,Range Query)등을 수행하기 때문에, 단순 PUT/GET만 하는 NoSQL이나 memcached에 비해서 read에 사용되는 resource의 양이 상대적으로 높기 때문에 redis의 성능을 높이기 위해서 효과적인 방법이다.

Sharding 을 통한 용량 확장
redis가 클러스터링을 통한 확장성을 제공하지 않는다면, 데이타의 용량이 늘어나면 어떤 방법으로 redis를 확장해야 할까?
일반적으로 Sharding이라는 아키텍쳐를 이용한다. Sharding은 Query Off loading과 마친가지로, redis 뿐만 아니라 일반적인 RDBMS나 다른 NoSQL에서도 많이 사용하는 아키텍쳐로 내용 자체는 간단하다.
여러개의 redis 서버를 구성한 후에, 데이타를 일정 구역별로 나눠서 저장하는 것이다. 예를 들어 숫자를 key로 하는 데이타가 있을때 아래와 그림과 같이 redis 서버별로 저장하는 key 대역폭을 정해놓은 후에, 나눠서 저장한다.
데이타 분산에 대한 통제권은 client가 가지며 client에서 애플리케이션 로직으로 처리한다.

현재 버전 2.4.15에서는 Clustering을 지원하지 않아서 Sharding을 사용할 수 밖에 없지만 2012년 내에 Clustering기능이 포함된다고 하니, 확장성에 대해서 기대해볼만하다. redis가 지원할 clustering 아키텍쳐는 ( http://redis.io/presentation/Redis_Cluster.pdf ) 를 참고하기 바란다.

6. Expriation
redis는 데이타에 대해서 생명주기를 정해서 일정 시간이 지나면 자동으로 삭제되게 할 수 있다.
redis가 expire된 데이타를 삭제 하는 정책은 내부적으로 Active와 Passive 두 가지 방법을 사용한다.
Active 방식은 Client가 expired된 데이타에 접근하려고 했을 때, 그때 체크해서 지우는 방법이 있고
Passive 방식은 주기적으로 key들을 random으로 100개만 (전부가 아니라) 스캔해서 지우는 방식이 이다.
expired time이 지난 후 클라이언트에 의해서 접근 되지 않은 데이타는 Active 방식으로 인해서 지워지지 않고 Passive 방식으로 지워져야 하는데, 이 경우 Passive 방식의 경우 전체 데이타를 scan하는 것이 아니기 때문에, redis에는 항상 expired 되었으나 지워지지 않는 garbage 데이타가 존재할 수 있는 원인이 된다.

7. Redis 설치(윈도우즈)
https://github.com/rgl/redis/downloads 에서 최신 버전 다운로드 받은후
redis-server.exe를 실행

클라이언트는 redis-cli.exe를 실행
아래는 테스트 스크립트
    % cd src
    % ./redis-cli
    redis> ping
    PONG
    redis> set foo bar
    OK
    redis> get foo
    "bar"
    redis> incr mycounter
    (integer) 1
    redis> incr mycounter
    (integer) 2
    redis> 


참고 자료


반응형

Redis 란?? slide


[펌]

http://www.slideshare.net/krisjeong/this-is-redis-kor-slideshare?next_slideshow=1



[출처] http://blog.daum.net/smufu/4

업무때문에 스터디 하다가 스터디 하다가 세미나도 하고


너무 괜찮아 보여서 현재 서비스중인 Product에 적용을 위해서


작업중인 NoSQL되시겠다...


각설하고, 그럼 먼저 NoSQL이란 무었인가?


Not only SQL의 약자 되시겠다..


혹자는 No SQL이라고 생각할지도 모르나.. 그런 기우일랑 접어두고..


SQL만이 아닌 다른 저장소 쯤으로 이해 하면 되겠다..


여기에(http://www.slideshare.net/krisjeong/redis-intro) 내가 작성한 세미나 자료 있으니 한번 훑어 보시면 이해 하는데 큰 도움이 되리라 생각된다.


Redis는 자주 Memcached와 비교되는 in memory 저장소 이다.


Memcached의 기본적인 특징.

1. 처리 속도가 빠르다.

   - 당연히 데이터가 메모리에만 저장되므로 빠르다. 즉, 속도가 느린 Disk를 거치지 않는다.

2. 데이터가 메모리에만 저장된다.

   - 당연히 프로세스가 죽거나 장비가 Shutdown되면 데이터가 사라진다.

3. 만료일을 지정하여 만료가 되면 자동으로 데이터가 사라진다.

   - 이름에서도 느껴지듯이 Cache이다

4. 저장소 메모리 재사용

   - 만료가 되지 않았더라도  더이상 데이터를 넣을 메모리가 없으면 LRU(Least recently used) 알고리즘에 의해 데이터가 사라진다.


그래서, 보통 대형 포털들에서 Static page, 또는 검색 결과 등을 캐쉬하는데 많이 사용한다.


그런데!!!!


왜!!!!! REDIS가 자꾸 Memchche와 비교되는가?


눈치들 채셨겠지만 거의 98%이상 Memchche와 동일한 기능을 제공한다.(비슷 하니까 비교 하겠지~~~)


그럼 다른 2%는 뭐냐?


이제부터 설명 들어간다..


 Memcached REDIS

처리 속도가 빠르다.

   - 당연히 데이터가 메모리에만 저장되므로 빠르다. 즉, 속도가 느린 Disk를 거치지 않는다.

처리 속도가 빠르다.

   - 당연히 데이터가 메모리+Disk에 저장된다. 그러나, 속도는 Memcached와 큰 차이가 없다.

데이터가 메모리에만 저장된다.

   - 당연히 프로세스가 죽거나 장비가 Shutdown되면 데이터가 사라진다.

데이터가 메모리+Disk에 저장된다.

   - 프로세스가 죽거나 장비가 Shutdown되더라도 Data의 복구가 가능하다.

만료일을 지정하여 만료가 되면 자동으로 데이터가 사라진다.

   - 이름에서도 느껴지듯이 Cache이다

만료일을 지정하여 만료가 되면 자동으로 데이터가 사라진다.

   - 동일한 기능을 지원한다.

저장소 메모리 재사용

   - 만료가 되지 않았더라도  더이상 데이터를 넣을 메모리가 없으면LRU(Least recently used) 알고리즘에 의해 데이터가 사라진다.

저장소 메모리 재사용 하지 않는다.

   - 명시적으로만 데이터를 제거할 수 있다.
 문자열만 지원
문자열, Set, Sorted Set, Hash, List등의 다양한 Data Type을 지원.


.. 오늘은 여기까지 하고..


사내 세미나용으로 작성한 자료 첨부 하니 참고 하세요..




REDIS intro and how to use redis from Kris Jeong

반응형

+ Recent posts