redis data design by usecase

38
Redis data design by usecase

Upload: kris-jeong

Post on 06-Dec-2014

2.368 views

Category:

Design


9 download

DESCRIPTION

Redis data design by usecase 예제를 통한 레디스 데이터 디자인에 관한 슬라이드. Facebook SSAG webinar 2014-09-03

TRANSCRIPT

Page 1: Redis data design by usecase

Redisdata design by usecase

Page 2: Redis data design by usecase

1. 메시지 읽음 처리2. 인증 토큰 발행3. Redis data 설계 방법4. 데이터 설계와 고려 사항

목차

Page 3: Redis data design by usecase

메시지 읽음 처리

Page 4: Redis data design by usecase

이렇게 생긴거요 .

Page 5: Redis data design by usecase

읽음 처리 요구 사항

1. 메시지 창에서 메시지의 읽음 횟수 출력 .a. 몇 명의 사용자가 메시지를 읽었는지 조회 .b. 메시지 아이디에 대한 읽음 건수 저장 .c. 메시지가 삭제되면 메시지 읽음 건수도 삭제 .

Page 6: Redis data design by usecase

읽음 건수 데이터 설계 ( 논리 )

1. 사용자 번호 , 방 번호로 Hash 를 구성 .2. 메시지 번호를 필드로 하여 건수 저장 .3. 읽음 건수 조회는 hget 또는 hmget 을 사용 .4. 메세지 삭제 시 읽음 건수 삭제도 같이 이루어져야 함 .

Page 7: Redis data design by usecase

읽음 건수 데이터 설계 ( 물리 )

Name KeyName Data type 포함정보

메시지 읽음 rcnt:<user>:<room> hash {message seq, read count}

Page 8: Redis data design by usecase

구현 1. 메시지 읽음 횟수 저장 . - hincrby rcnt:<user>:<room> <message Seq> 1 2. 특정 메시지의 읽음 횟수 조회 . - hget rcnt:<user>:<room> <message Seq>3. 여러 메시지의 읽음 횟수 조회 . - hmget rcnt:<user>:<room> <message Seq> ...4. 특정 방의 메시지 읽음 횟수 조회 . - hgetall rcnt:<user>:<room>

Page 9: Redis data design by usecase

That’s all???

Page 10: Redis data design by usecase

배포된 바이너리에 버그가 있어서 사용자가 창을 열 때마다 API 가

호출되요 !!!!

헐 ..

Page 11: Redis data design by usecase

!!!???

Page 12: Redis data design by usecase

읽음 처리 요구 사항 변경

1. 메시지 창에서 메시지의 읽음 횟수 출력 .a. 몇 명의 사용자가 메시지를 읽었는지 조회 .b. 메시지 아이디에 대한 읽음 건수 저장 .c. 메시지가 삭제되면 메시지 읽음 건수도 삭제 .

2. 동일한 사용자가 API 를 여러 번 호출하더라도 읽음 횟수는 단 1 회만 증가 !

Page 13: Redis data design by usecase

읽음 건수 데이터 설계 v2 ( 논리 )

1. 방 번호 , 메시지 번호로 구성된 키로 Set생성 .2. Set 에 메시지를 읽은 사용자의 사용자 번호 저장 .3. 데이터의 조회는 scard 명령을 사용 .

Page 14: Redis data design by usecase

읽음 건수 데이터 설계 ( 물리 )

Name KeyName Data type 포함정보

메시지 읽음 rcnt:<user>:<room>:<message seq>

set {read user}

Page 15: Redis data design by usecase

구현 v2(2/2)

1. 메시지 읽음 횟수 저장 - sadd rcnt:<user>:<room>:<message seq> <read user>2. 특정 메시지의 읽음 횟수 조회 - scard rcnt:<user>:<room>:<message seq>3. 여러 메시지의 읽음 횟수 조회 - scard rcnt:<user>:<room>:<message seq1> - scard rcnt:<user>:<room>:<message seq2>

Page 16: Redis data design by usecase

구현 v2(2/2)

4. 특정 방의 읽음 횟수 조회 - scard rcnt:<user>:<room>:<message seq1> - scard rcnt:<user>:<room>:<message seq2> - scard rcnt:<user>:<room>:<message seq3> ……. ????????????

Page 17: Redis data design by usecase

인증토큰 발행

Page 18: Redis data design by usecase

토큰 발행 요구사항

1. 만료가 가능한 토큰을 발행한다 .2. 만료일은 발행 시간으로부터 3 일로 지정한다3. 새로운 토큰이 발행되면 이전 토큰은 만료 전까지 사용 가능하다 .4. 토큰은 부가적인 인증 정보를 가진다 .(ex. email, nickname, token issue date)

Page 19: Redis data design by usecase

토큰 데이터 설계 ( 논리 )

1. 토큰의 만료는 redis 의 expire 를 사용 .2. 인증토큰의 부가 정보는 json 문자열로 저장 .3. token 은 사용자의 id 와 발행 시점의 timestamp 를 조합한 문자열에 sha-256 해시를 수행한 값을 사용 .4. 문자열에 token 을 키로 하여 인증 정보를 저장

Page 20: Redis data design by usecase

토큰 데이터 설계 ( 물리 )

Name KeyName Data type 포함정보

인증토큰 token:<token string>

String {email, userno, nick}

Page 21: Redis data design by usecase

구현1. Token 발행 - String token = sha256(id + timestamp) - setex token:<token> {'mail':'[email protected]','nick':'test','userNo':'1046'} 2592002. token 검증 - get token:<token>

Page 22: Redis data design by usecase

어때요 ? 참 쉽죠 ?

Page 23: Redis data design by usecase

BUT!!! 그러나 !!!

Page 24: Redis data design by usecase

토큰발행 변경 요구사항

id 별 활성 token 을 조회할 수 있게 해주세요

Page 25: Redis data design by usecase

토큰 데이터 설계 v2 ( 논리 )

1. 만료기능은 redis 의 expire 를 사용2. 인증과 관련된 추가 정보는 json 문자열로 저장 .3. token 은 사용자의 id 와 발행 시점의 timestamp 를 조합한 문자열에 sha-256 해시를 수행한 값을 사용 .4. 문자열에 token 을 키로 하여 인증 정보를 저장 .5. 사용자 번호로 hash 를 생성 .6. hash 에 사용자 token 과 timestamp 를 저장 .

Page 26: Redis data design by usecase

토큰 데이터 설계 v2 ( 물리 )

Name KeyName Data type

포함정보

인증토큰 token:<token string>

String {email, userno, nick}

토큰목록 tokenlist:<userNo>

hash {token, expire date}

Page 27: Redis data design by usecase

구현 v2(1/2)

1. Token 발행 (use multi command) - String token = sha256(id + timestamp) - setex expire <token> {"email":"[email protected]","nickName":"test","userNo":"1046"} 259200 - hset <userid>, <token>, timestamp

Page 28: Redis data design by usecase

구현 v2(2/2)

2. token 검증 - get token:<token>3. 활성 token 조회 - hgetall <userid> - timestamp 를 기준으로 출력 여부 결정 .

Page 29: Redis data design by usecase

수정이 완료 되었군요 . 운영서버로 ㄱㄱ

Page 30: Redis data design by usecase

BUT!!! 또 그러나 !!!

Page 31: Redis data design by usecase

HASH 내부에 만료된 token 은 언제 삭제하지 ?

Page 32: Redis data design by usecase

redis 2.8 의 새 기능 Keyspace events

Page 33: Redis data design by usecase

Redis Keyspace Notifications

1. 키의 변경이 발생하면 PUB/SUB 을 통해서 확인가능 . - 즉 , expire 된 키의 이름을 알 수 있음 . - config set notify-keyspace-events Ex - psubscribe "__keyevent@*"※ SUB 을 받아서 처리하는 별도의 프로그램 작성 필요 .※ 더 많은 내용 http://redis.io/topics/notifications 참조K Keyspace events, published with __keyspace@<db>__ prefix.

E Keyevent events, published with __keyevent@<db>__ prefix.

g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...

...

Page 34: Redis data design by usecase

이렇게 하여 인증 토큰을자알 구현했습니다 .

끄읕 ~~

Page 35: Redis data design by usecase

Redis data 설계 주안점 (1/2)

1. 모든 데이터를 키에 저장할 수 있는가 ? - 키 만 조회 하여 업무를 처리할 수 있도록 구성 .2. 자료구조 Set, Hash, List 등으로 구현이 가능한가 ? - 여러개의 명령을 사용하더라도 실행시간이 O(1) 인지 . - 우리에겐 Lua 가 있다 .4. 데이터 사용 성향에 따라 다른 데이터 구조 선택 필요 . - 빠른 쓰기가 필요한지 빠른 읽기가 필요한지 - Hash 와 Sorted set 에 대한 trade 가능하면 Hash 로 .

Page 36: Redis data design by usecase

Redis data 설계 주안점 (2/2)

5. 단순한 데이터 조회 패턴을 가지는가 ? - RDB 의 where 필터링은 불가 !!!6. 숫자 데이터가 많은가 ? - 카운터와 같은 숫자 데이터 저장에 강함 .3. Lua 사용시 전체 시간복잡도는 O(log n) 을 초과 하지 않도록 하라 .

Page 37: Redis data design by usecase

Lua 사용 주의사항

1. 예측 불가능한 Loop 문을 사용하지 말것 . - ex) while(true) ※ Lua 스크립트의 실행은 원자성을 가짐 .

2. 에러 처리에 신경쓸것 . - ex) 조회한 데이터가 존재하는지 확인 .

Page 38: Redis data design by usecase