2016. 12. 21. 20:52 카테고리 없음

redis

http://www.joinc.co.kr/w/man/12/REDIS/IntroDataType


발표 자료 작성중~
centos 7.2

1 시작하기
 1) Redis란
 - Remote Dictionary Server. 2006년 살바토르 산필리포가 C로 개발
 - 고성능 키-값 데이터 저장소인 NoSQL(Not Only SQL).
 - String, Hash, List, Set, Sorted Set, Bitmap, HyperLogLog와 같은 강력한 데이터 타입을 가지고 있음
 - 모든 데이터를 메모리에 저장하기 때문에 읽기와 쓰기 명령이 매우 빠름
 2) 설치
 - aws EC2 인스턴스 생성, Centos 7.2 설치
 - wget http://download.redis.io/releases/redis-3.2.6.tar.gz
   tar xzvf redis-3.2.6.tar.gz   
   sudo make install
   실패해서 yum -y install gcc-c++ 설치 후 make clean 실행하면
   jemalloc/jemalloc.h: No such file or directory 실패 오류가 남
   sudo make distclean
   sudo make install
 3) 실행파일
  - 여러 실행 파일을 제공하지만 아래 두가지에 초점을 맞춤
  가. redis-server
   - 레디스의 실제 저장소. 클러스터 모드 또는 독립 실행형 모드로 실행
    



  나. redis-cli
   - 레디스 커맨드를 실행할 수 있는 커맨드라인 인터페이스
   - 레디스 서버에 접속하는 방법을 보여줌
    


     SET 으로 키-값을 저장하고 GET 으로 key를 사용하여 값을 취득
     KEYS t* KEYS 커맨드는 패턴과 일치하는 모든 키를 리턴. t로 시작하는 저장된 모든 키 이름
   - 디버깅과 테스트를 위해 임시로 사용. 실제 사례와 애플리케이션에서는 다른것 사용
 4) 예제 실행을 위한 노드 설치
  - EPEL (Extra Packages for Enterprise Linux) repository을 통해 설치
    yum install epel-release
    yum install nodejs
    yum install npm(노드 의존 바이너리와 라이브러리 관리와 설치를 책임지는 Node Package Manager)
  - npm install redis
    npm 에서는 지역과 전역이라는 두가지 설치 모드가 있는데 생략하고...
    node에서 필요로 하는 redis 모듈을 설치한다.
    /usr/lib/node_modules/redis 가 설치됨

 5) node와 redis를 이용한 Hello World

  - vi hello.js

var redis = require("redis");        // import
var client = redis.createClient();    // redis client 객체 생성
client.set("my_key", "Hello World using Node.js and Redis");
client.get("my_key", redis.print);
client.quit();

>node hello.js 를 실행하니... Error: Cannot find module 'redis' 오류가 발생

이유를 한참 찾아보니.... node npm 설치를 잘못했음

/usr/lib/node_modules/redis

이 디렉토리에서 hello.js를 만들고 실행해야 가능함

npm uninstall redis 하고 node home 디렉토리로 이동후

npm install redis 하니 node 홈 밑에 node_modules가 생김

node 홈 밑에 test 디렉토리를 만들고.... hello.js 파일을 생성 실행하니 잘 됨

 6) Redis 데이터 타입
  가. 문자열
   - 레디스에서 가장 다양한 데이터 타입, 512MB까지
     정수, 부동소수점, 바이너리 데이터(비디오, 이미지등)와 같은 어떠한 종류의 데이터도 저장가능
   - 캐시 메카니즘, 자동 만료되는 캐시, 계수 계산(페이지뷰, 비디오 뷰 등) 
   - redis-cli를 활용한 문자열 예제
     127.0.0.1:6379> SET current_chapter "Chapter 1"
    OK
    127.0.0.1:6379> EXPIRE current_chapter 60           // 만료 시간을 60초
    (integer) 1
    127.0.0.1:6379> GET current_chapter
    "Chapter 1"
    127.0.0.1:6379> TTL current_chapter                 // 생존 시간을 리턴, -2 만료되거나 존재하지 않으면, -1키가 존재하지만 만료 시간을 저장하지 않음
    (integer) 50
   - 레디스는 싱글 스레드 기반으로 동작한다.
     counter 키 값이 1이고 A와 B가 동시에 증가를 시키면 A는 2, B는 3을 얻음
   - 노드를 이용해 문자열로 투표 시스템 개발하기
     articles-popularity.js 참조
  나. 리스트
   - collection, stack, queue와 같이 동작, 많은 이벤트 시스템은 리스트 커멘트가 원자적인 특성을 갖고 있어
     병열 시스템이 큐에서 엘리먼트를 얻어낼때 중복으로 얻지 않도록 보장해 주기때문에 레디스 리스트를 queue로 사용
     이벤트 큐 : Resque, Celery, Logstash를 포함한 많은 툴
     최근 사용자 글 저장하기 : 트위트는 사용자의 최근 트윗을 저장할 때 리스트를 사용
   - 리스트에 블로킹(blocking) 커멘드가 존재하면 linked list라서 처음, 끝에서의 추가, 삭제시 항상 O(1), 일정시간을 가짐
   - 최대 개수는 2(32승) - 1개, 40억개 이상의 엘리먼트를 가질 수 있음
   - 사용예제
    127.0.0.1:6379> LPUSH books "Clean Code"                  // 리스트의 맨 처음에 입력
    (integer) 1
    127.0.0.1:6379> RPUSH books "JavaScript Pattern & Test"   // 리스트의 맨 마지막에 입력
    (integer) 2
    127.0.0.1:6379> LPUSH books "한글테스트"
    (integer) 3
    127.0.0.1:6379> LRANGE books 0 -1                         // index는 0, 1로 증가... -1은 맨 마지막
    1) "\xed\x95\x9c\xea\xb8\x80\xed\x85\x8c\xec\x8a\xa4\xed\x8a\xb8"       // 한글이 깨짐... 찾아봐야 함
    2) "Clean Code"
    3) "JavaScript Pattern & Test"
    127.0.0.1:6379>
   - 일반적인 큐 시스템 구현
    queue.js, consumer-worker.js, product-worker.js 참조
  다. 해시
   - 필드를 값으로 매핑, 필드 이름과 값이 문자열. 메모리 최적화(장점)
   - hash-max-ziplist-entries 와 hash-max-ziplist-value 설정을 기반
   - 예제
    127.0.0.1:6379> HSET movie "title" "test1"
    (integer) 1
    127.0.0.1:6379> HMSET movie "year" 1927 "watchers" 1000000
    OK
    127.0.0.1:6379> HGET movie "title"
    "test1"
    127.0.0.1:6379> HINCRBY movie "watchers"
    (error) ERR wrong number of arguments for 'hincrby' command
    127.0.0.1:6379> HINCRBY movie "watchers" 3
    (integer) 1000003
    127.0.0.1:6379>
   - 해시와 노드를 이용한 투표 시스템
    hash-voting-system.js 참조


  2 고급 데이터 타입
 1) 셋
  - 순서가 없고 동일한 문자열이 없는 콜렉션
  - 데이터 필터링, 데이터 그룹핑, 엘리먼트십 확인 등에 사용
  가. redis-cli를 이용한 셋 예제
   - SADD, SINTER, SDIFF, SUNION,SRANDMEMBER, SISMEMBER, SREM, SCARD 등
   - 예제
    127.0.0.1:6379> SADD user:max:favorite_artists "Arcade File" "Arctic Monkeys" "Bell & Sebastian" "Lenine"
    (integer) 4
    127.0.0.1:6379> SADD user:hugo:favorite_artists "Daft Punk" "The Kooks" "Arctic Monkeys"
    (integer) 3
   - 딜 추적 시스템 개발 : 이미 등록된 회원이면... 안 보내고, 미등록 회원이면 메일 보내고 등록
    deal_metrics.js
 2) 정렬된 셋
  - 셋과 비슷하지만, 모든 엘리먼트는 연관 점수를 가지는 점수로 정렬된, 중복 문자열이 없는 콜렉션
    점수가 동일할 경우 사전 편집 순으로 정렬
  가. redis-cli를 이용한 정렬된 셋 예제 
   - ZADD 는 정렬된 셋에 하나 이상의 엘리먼트를 추가
     ZADD leaders 100 "Alice"
     ZADD leaders 100 "Zero"
     ZADD leaders 102 "Hugo"
     ZADD leaders 101 "Max"
     ZREVRANGE : 높은 점수에서 낮은 점수로 Hugo > Max > Zero > Alice
     ZREM : 엘리먼트 삭제, ZEM leaders "Hugo"
     ZSCORE : 점수를 리턴, ZSCORE leaders "Max" -----> 101
     ZRANK : 낮은 순에서 높은순의 등수를 리턴, ZRANK leaders "Max" ------> 2
     예제) 나중에 시간되면 하자.
 3) 비트맵
  - 실제 데이터 타입이 아니며, 내부적으로 문자열이다.
    문자열의 비트 연산자 집합이라고 말할 수 있다.
    setbit로 bit를 설정할 수 있고, getbit로 bit 설정여부를 확인할 수 있다.
    가장 큰 장점은 0과 1의 상태를 가지는 아이템들을 대단히 효율적으로 저장하고 읽을 수 있다는데 있다.
   가. redis-cli를 이용한 비트맵 예제
    - 하루 방문자를 계산해 보자. 사용자가 방문을 하면 해당 사용자 아이디에 매핑하는 bit값을 1로 세팅
      이때 필요한 메모리는 단지 1bit이기 때문에 512M로 40억(512 * 1024 * 1024 * 8) 유저의 방문정보를 기록 가능
      setbit visitor 10 1    // 10번 사용자
      setbit visitor 17 1    // 10번 사용자
      setbit visitor 19 1    // 10번 사용자
      setbit visitor 102 1    // 10번 사용자
      setbit visitor 107 1    // 10번 사용자
      getbit visitor 17       // 17번 고객 방문여부, 1 리턴
      getbit visitor 20       // 20번 고객 방문여부, 0 리턴
      bitcounter visitor      // 방문 유저수 5
      예제) 나중에 시간되면 하자.
 4) 하이퍼로그로그
  - 실제 데이터 타입이 아니며 개념적으로는 알고리즘이다.
    어떤 데이터셋 집합에서 유일한 원소의 개수를 검사하기 우해서 사용하는 알고리즘이다. 약간의 오차를(0.81퍼센트의 표준오차, 100개중에 99.19개 정확) 허용하는 대신 매우 작은
    메모리로 유니크한 원소의 개수를 검사할 수 있다.
    웹사이트 고유 방문자수, 특정 날짜 시간의 웹사이트 검색 고유 키워드, 책의 고유단어 개수 등
    PFADD는 하나 이상의 문자열을 하이퍼 로그로그에 추가함
    127.0.0.1:6379> PFADD nickname "gt1000" "test" "gt1003" "gt1005"        // nickname에 4개의 키워드가 등록
    (integer) 1
    127.0.0.1:6379> PFADD nickname "gt1000" "gt1003"                        // 이미 존재 0
    (integer) 0
    127.0.0.1:6379> PFCOUNT nickname
    (integer) 4
  - 예제) 나중에 시간되면 하자.

3 시계열(관찰 집합)
 - 이건... .그냥 예제 소개... 나중에 시간이 남으면 하던지 하자.

4 커맨드(괴물들이 사는 나라)
 1) Pub/Sub
  - 메시지를 특정 수신자에게 직접 발송하지 못하는 곳에서 쓰이는 패턴 Publish(발송)-Subscribe(구독)의 약자.
    메시지를 발송하고 채널에서 구독하는 커맨드를 제공함
    뉴스와 날씨 대시보드, 채팅 어플리케이션, 지하철 지연경고 등의 푸시 알림등에서 사용됨
  - 예제 118page
 2) 트랜잭션
  - 레디스의 트랜잭션은 순서대로 원자적으로 실행되는 커맨드의 열이다.
    MULTI 커맨드는 트랜잭션의 시작을 표시하고, EXEC 커맨드는 트랜잭션의 마지막을 표시한다.
    MULTI 커맨드와 EXEC 커맨드간의 모든 커맨드는 직렬화되고 원자적으로 실행
    레디스는 트랜잭션의 처리 도중에 다른 클라이언트의 요청에 응하지 않음
  - 트랜잭션의 모든 커맨드는 클라이언트의 큐에 쌓이고, EXEC 커맨드가 실행되면 서버로 전달
    DISCARD 커맨드를 사용하면 트랜잭션은 실행되지 않음
  - 레디스 트랜잭션은 과정을 실행하다가 실패하더라도 롤백하지 않음
  - 단점은 모든 커맨드가 큐에 쌓이기 때문에 트랜잭션 내부에서 어떠한 결정도 내릴 수 없음
   예)
 3) 파이프라인
  - 다중 커맨드를 서버에 한꺼번에 보내는 방법을 말하며, 개별 응답을 기다리지 않고 클라이언트에 의해 응답을
    한번에 읽을 수 있음
    레디스 클라이언트가 커맨드를 보내고 레디스 서버로부터 응답을 받는데 걸리는 시간을 Round Trip Time 이라 함
    열개의 커맨드를 파이프라인으로 이용하면 하나의 RTT가 됨
    예)
    var redis = require("redis");
    var client = redis.createClient();
    client.set("key1", "value1");
    client.set("key2", "value2");
    client.set("key3", "value3");
    127 page 그림
 4) 스크립트
  - 레디스 확장을 위해서는 루아 언어가 필요
  - 이건..... 오버인거 같아서 보류
 5) 기타 커맨드
  - info 커맨드는 레디스 버전과 운영체제, 연결된 클라이언트, 메모리 사용량, 자정소, 복제본, 카스페이스에 대한 정보를
    포함한 모든 레디스 서버 통계를 리턴
    ex) info momory
  - DBSIZE는 레디스 서버에 존재하는 키 개수를 리턴
  - DEBUG SEGFAULT는 올바르지 않은 메모리 접근을 수행해 레디스 서버 종료.
    애플리케이션 개발 중에 버그를 시뮬레이션 할때 유용
  - MONITOR는 서버가 처리하는 모든 커맨드를 실시간으로 보여줌
    레디스 서버가 얼마나 바쁜지 확인할 때 유용
    디버깅시 매우 유용하지만 비용이 소모됨
    레디스 공식 문서 페이지에는 비과학적인 벤치마크 테스트에서 MONITOR 커맨드가 레디스의 성능을 50% 이상까지 떨어뜨릴수
    있다고 언급
  - CLIENT LIST는 클라이언트에 대한 관련 정보와 통계뿐 아니라 서버에 연결된 모든 클라이언트 목록을 리턴
  - client setname 는 클라언트의 이름을 변경. 디버깅 목적시 유용
  - CLIENT KILL 클라이언트 연결 종료. IP, 포트, ID, 타입으로 가능
    ex) CLIENT KILL ADDR 127.0.0.1:12345
  - FLUSHALL 레디스의 모든 키를 삭제. 삭제된 키는 복구 불가
  - RANDOMKEY 존재하는 키 이름 중 무작위로 선택한 하나의 키 이름을 리턴
  - EXPIRE 특정키의 타임아웃을 초 단위로 설정. 레디스는 명세한 초가 지난 후에 키를 삭제
    음수의 타임아웃은 키를 바로 삭제
  - EXPIREAT 유닉스 타임스탬프를 기반으로 특정 키의 타임아웃을 설정함. 설정한 타임스탬프가 과거라면 즉시 키를 삭제
  - TTL 타임아웃 값이 있는 키의 남아있는 생존 시간을 초 단위로 리턴
  - PTTL TTL 커맨드와 동일하지만 리턴값은 초가 아니라 밀리초
  - PERSIST 특정키에 주어진 현존 타임아웃을 제거. 새로운 타임아웃을 설정하지 않으면 키는 만료되지 않음
    키의 타임아웃을 삭제하면 1을 리턴, 키의 타임아웃이 존재하지 않으면 0을 리턴
  - SETEX  특정키에 값을 저장할때 만료 시간도 함께 원자적으로 설정함
    SET 커맨드와 EXPIRE 커맨드의 조합
  - DEL 하나 이상의 키를 레디스에서 삭제하고 삭제된 키의 개수를 리턴함
  - EXISTS 특정 키가 존재하면 1을 리턴하고, 특정키가 존재하지 않으면 0을 리턴
  - PING 'PONG" 문자열을 리턴, 서버/클리이언트 연결 테스트.
  - MIGRATE 특정 키를 대상 레디스 서버로 옮긴다. 원자적이어서 키를 옮기는 동안 원본 레디스 서버와 키를 저장할 레디스 서버가
    둘다 블록, 키를 저장할 서버에 키가 이미 존해하면 실패함
  - SELECT 다중 데이터베이스 개념. 기본 16개, 0에서 15까지의 숫자로 식별
    하나의 서버를 사용하는 것보다 여러개의 redis-server 프로세스를 사용하는 것이 좋음
  - AUTH  레디스에 연결할 수 있는 클라이언트의 허가하는데 사용.
  - SCRIPT KILL 스크립트가 더 이상 쓰기 작업을 수행하지 않으면 루아 스크립트 실행을 종료.
  - SHUTDOWN 모든 클라이언트를 종료하고 최대한 데이터를 저장하려고 한 후 레디스 서버를 종료
  - OBJECT ENCODING 커맨드는 주어진 키에서 사용 중인 인코딩 값을 리턴
 6) 데이터 타입의 최적화
  - 문자열
   int : 64b 비트 부호있는 정수로 문자열을 표현할때 int가 사용됨
   set str1 1234
   embstr : 40바이트 이하 작은 문자열
   set str2 "an embstr is small"
   object encoding str2
   raw : 40 바이트보다 큰 문자열을 표기
   set str3 " a raw encoded string is anything greater than 39 bytes"
   object encodeing str3
   "raw"
  - 리스트
   ziplist : 리스트 크기의 엘리먼트가 list-max-ziplist-entries 설정보다 작고, 리스트의 개별 엘리먼크의 바이트가
   list-max-ziplist-value 설정보다 작다면 ziplist가 사용
   linkedlist : 리스크 크기의 엘리먼트가 list-max-ziplist-entries 설정보다 크거나
   리스트의 개별 엘리먼트의 바이트가 list-max-ziplist-value 설정보다 크면 연결리스트가 사용됨
  - 셋
   intset : 모든 엘리먼트가 정수고, 셋의 개수가 set-max-interset-entries 설정보다 작으면 인트셋이 사용
   hashtable : 엘리먼트중 하나라도 정수가 아니거나, 셋의 개수가 set-max-interset-entries 설정보다 크면 사용
  - 해시
   집리스트 : 해시의 필드 개수가 hash-max-ziplist-entiries 설정보다 작고 해시의 필드 이름과 값이
   hash-max-ziplist-value 설정보다 작으면 집리스트가 사용
   해시테이블 : 해시의 필드 개수가 hash-max-ziplist-entries 설정보다 크거나 해시의 필드값 중 하나라도
   hash-max-ziplist-value 설정보다 크면 해시테이블이 사용됨
  - 정렬된 셋
   집리스트 : 정렬된 셋의 개수가 set-max-ziplist-entries 설정보다 작고, 정렬된 셋의 엘리먼트 값이 모드 zset-max-ziplist-value
   설정보다 작으면 집리스트가 사용
   스킵리스트와 해시테이블 : 정렬된 셋의 개수가 set-max-ziplist-entries 설정보다 크거나 정렬된 셋의 엘리먼트 값 중
   하나라도 zset-max-ziplist-value 설정보다 크면 스킵리스트와 해시테이블이 사용

 

http://projects.spring.io/spring-data-redis/

이거 정리해야 함

Posted by gt1000

블로그 이미지
gt1000

태그목록

공지사항

어제
오늘

달력

 « |  » 2024.4
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함