SlideShare une entreprise Scribd logo
1  sur  189
Télécharger pour lire hors ligne
우아한 Redis
charsyam@naver.com
목차
● Redis 소개
● 왜 Collection이 중요한가?
● Redis Collections
● Redis 운영
● Redis 데이터 분산
● Redis Failover
오늘 발표에서 다루지 않는 것들
● Redis Persistence(RDB, AOF)
● Redis Pub/Sub
● Redis Stream
● 확률적 자료구조
○ Hyperloglog
● Redis Module
Redis 소개
● In-Memory Data Structure Store
● Open Source(BSD 3 License)
● Support data structures
○ Strings, set, sorted-set, hashes, list
○ Hyperloglog, bitmap, geospatial index
○ Stream
● Only 1 Committer
Redis 를 소개하기 전에
Cache 먼저~~~
Cache 가 무엇일까요?
Cache의 정의
● Cache 는 나중에 요청올 결과를 미리 저장해두었다가 빠르게
서비스를 해주는 것을 의미
Factorial
Factorial 의 계산
● 10! = 10 * 9! = 10 * 9 * 8! = 10 * 9 * 8 * 7!
● 19! = 19 * 18 * 17 * 16 * 15 * 14 * 13 * 12 * 11 * 10!
● 팩토리얼 숫자가 크다면?
○ 20880!, 20881! 를 매번 계산해야 한다면?
20880! 를 계산해 두고
어딘가에 저장해 뒀다면
20881! 계산은 금방!!!!
접근 속도가 다를 때...
CPU Cache
어디서 많이 사용하나요?
아주 추상적인 웹서비스 구조
Client Web Server DB
DB 안에는 많은 데이터들이 있고, 이 때 주로
디스크에 내용이 저장되게 됩니다.
파레토 법칙
전체 요청의 80%는
20%의 사용자
Cache 구조 #1 - Look aside Cache
Client Web Server DB
Memory Cache를 이용하게 되면 훨씬 더
빠른 속도로 서비스가 가능합니다.
Cache
1. Web Server 는 데이터가 존재하는지
Cache를 먼저 확인
2. Cache에 데이터가 있으면 Cache에서
가져온다.
3. Cache에 데이터가 없다면 DB에서
읽어온다.
4. DB에서 읽어온 데이터를 Cache에
다시 저장한다.
Cache 구조 #2 - Write Back
Client Web Server DB
Memory Cache를 이용하게 되면 훨씬 더
빠른 속도로 서비스가 가능합니다.
Cache
1. Web Server 는 모든 데이터를
Cache에만 저장
2. Cache에 특정 시간동안의 데이터가
저장
3. Cache에 있는 데이터를 DB에
저장한다.
4. DB에 저장된 데이터를 삭제한다.
왜 Collection 이 중요한가?
● 개발의 편의성
● 개발의 난이도
개발의 편의성
랭킹 서버를 직접 구현한다면?
개발의 편의성
● 가장 간단한 방법
○ DB에 유저의 Score를 저장하고 Score 로 order by로
정렬 후 읽어오기.
개발의 편의성
● 가장 간단한 방법
○ DB에 유저의 Score를 저장하고 Score 로 order by로
정렬 후 읽어오기.
○ 개수가 많아지면 속도에 문제가 발생할 수 있음.
■ 결국은 디스크를 사용하므로
개발의 편의성
● In-Memory 기준으로 랭킹 서버의 구현이 필요함.
○ 능력자면, 금방 만드실....(?)
개발의 편의성
● Redis의 Sorted Set을 이용하면, 랭킹을 구현 할 수 있음.
○ 덤으로, Replication도 가능…
○ 다만 가져다 쓰면 거기의 한계에 종속적이 됨.
■ 랭킹에 저장해야할 id가 1개당 100byte라고 했을때
● 10명 1K
● 10000명 1M
● 10000000명 1G
● 10000000000 명 1TB
개발의 난이도
친구 리스트를 관리해봅시다.
개발의 난이도
● 친구 리스트를 KEY/VALUE 형태로 저장해야 한다면?
○ 현재 유저 123의 친구 Key는 friends:123, 현재 친구 A가
있는 중
T1(친구 B를 추가)
● 친구 리스트 friends:123 을 읽는다.
● friends:123 의 끝에 친구 B를 추가한다.
● 해당 값을 friend:123 에 저장한다.
T1(친구 C를 추가)
● 친구 리스트 friends:123 을 읽는다.
● friends:123 의 끝에 친구 C를 추가한다.
● 해당 값을 friend:123 에 저장한다.
개발의 난이도
● 어떤 문제가 발생할 수 있을까요?
T1(친구 B를 추가)
● 친구 리스트 friends:123 을 읽는다.
● friends:123 의 끝에 친구 B를 추가한다.
● 해당 값을 friend:123 에 저장한다.
T1(친구 C를 추가)
● 친구 리스트 friends:123 을 읽는다.
● friends:123 의 끝에 친구 C를 추가한다.
● 해당 값을 friend:123 에 저장한다.
개발의 난이도
● 어떤 문제가 발생할 수 있을까요?
시간순서 T1(친구 B 추가) T2(친구 C 추가) 최종상태
1 friends:123 읽기 A
2 친구 B 추가 A
3 friends:123 쓰기 A, B
4 friends:123 읽기 A, B
5 친구 C 추가 A, B
6 friends:123 쓰기 A, B, C
개발의 난이도
● Race Condition
시간순서 T1(친구 B 추가) T2(친구 C 추가) 최종상태
1 friends:123 읽기 A
2 friends:123 읽기 A
3 친구 B 추가 A
4 친구 C 추가 A
5 friends:123 쓰기 A, B
6 friends:123 쓰기 A, C
개발의 난이도
● Race Condition
시간순서 T1(친구 B 추가) T2(친구 C 추가) 최종상태
1 friends:123 읽기 A
2 friends:123 읽기 A
3 친구 B 추가 A
4 친구 C 추가 A
5 friends:123 쓰기 A, C
6 friends:123 쓰기 A, B
개발의 난이도
● Redis의 경우는 자료구조가 Atomic 하기 때문에, 해당 Race
Condition 을 피할 수 있습니다.
○ 그래도 잘못짜면 발생함.
왜 Collection 이 중요한가?
● 외부의 Collection을 잘 이용하는 것으로, 여러가지 개발
시간을 단축시키고, 문제를 줄여줄 수 있기 때문에 Collection
이 중요.
Redis는 실행했는데
어디에 써야 하죠?
Redis 사용 처
● Remote Data Store
○ A서버, B서버, C서버에서 데이터를 공유하고 싶을때
● 한대에서만 필요한다면, 전역 변수를 쓰면 되지 않을까?
○ Redis 자체가 Atomic을 보장해준다.(싱글 스레드라…)
● 주로 많이 쓰는 곳들
○ 인증 토큰 등을 저장(Strings 또는 hash)
○ Ranking 보드로 사용(Sorted Set)
○ 유저 API Limit
○ 잡 큐(list)
Redis Collections
Redis Collections
● Strings
● List
● Set
● Sorted Set
● Hash
Strings
Key/Value
Strings - 단일 Key
● 기본 사용법
○ Set <key> <value>
○ Get <key>
● Set token:1234567 abcdefghijklmn
● Get token:1234567
Strings - 멀티 Key
● 기본 사용법
○ mset <key1> <value1> <key2> <value2> …… <keyN> <valueN>
○ mget <key1> <key2> …… <keyN>
● mset token:1234567 abcdefghijklmn email:1234567 charsyam@naver.com
● mget token:1234567 email:1234567
Strings - 간단한 SQL을 대체한다면?
● Insert into users(name, email) values(‘charsyam’, ‘charsyam@naver.com’);
● Using Set
○ Set name:charsyam charsyam
○ Set email:charsyam charsyam@naver.com
● Using mset
○ Mset name:charsyam charsyam email:charsyam charsyam@naver.com
List
List : insert
● 기본 사용법
○ Lpush <key> <A>
■ Key: (A)
○ Rpush <key> <B>
■ Key: (A, B)
○ Lpush <key> <C>
■ Key: (C, A, B)
○ Rpush <key> <D, A>
■ Key: (C, A, B, D, A)
List : pop
● 기본 사용법
○ Key: (C, A, B, D, A)
○ LPOP <key>
■ Pop C, Key: (A, B, D, A)
○ RPOP <key>
■ Pop A, Key: (A, B, D)
○ RPOP <key>
■ Pop D, Key: (A, B)
List : lpop, blpop, rpop, brpop
● 기본 사용법
○ Key: ()
○ LPOP <key>
■ No Data
○ BLPOP <key>
■ 누가 데이터를 Push 하기 전까지 대기
Set
Set : 데이터가 있는지 없는지만 체크하는 용도
● 기본 사용법
○ SADD <Key> <Value>
■ Value가 이미 Key에 있으면 추가되지 않는다.
○ SMEMBERS <Key>
■ 모든 Value를 돌려좀
○ SISMEMBER <key> <value>
■ value가 존재하면 1, 없으면 0
● 특정 유저를 Follow 하는 목록을 저장해둔다면
Sorted Sets
Sorted Sets : 랭킹에 따라서 순서가 바뀌길 바란다면
● 기본 사용법
○ ZADD <Key> <Score> <Value>
■ Value가 이미 Key에 있으면 해당 Score로 변경된다.
○ ZRANGE <Key> <StartIndex> <EndIndex>
■ 해당 Index 범위 값을 모두 돌려줌
■ Zrange testkey 0 -1
● 모든 범위를 가져옴.
● 유저 랭킹 보드로 사용할 수 있음.
● Sorted sets의 score 는 double 타입이기 때문에, 값이 정확하지 않을 수 있다.
○ 컴퓨터에서는 실수가 표현할 수 없는 정수값들이 존재.
Sorted Sets - 정렬이 필요한 값이 필요하다면?
● select * from rank order by score limit 50, 20;
○ zrange rank 50 70
● Select * from rank order by score desc limit 50, 20;
○ Zrevrange rank 50 70
Sorted Sets - Score 기준으로 뽑고 싶다면?
● select * from rank where score >= 70 and score < 100;
○ zrangebyscore rank 70 100
● Select * from rank where score > 70;
○ Zrangebyscore rank (70 +inf
Hash
Hash: Key 밑에 sub key가 존재
● 기본 사용법
○ Hmset <key> <subkey1> <value1> <subkey2> <value2>
○ Hgetall <key>
■ 해당 key의 모든 subkey와 value를 가져옴
○ Hget <key> <subkey>
○ Hmget <key> <subkey1> <subkey2> …… <subkeyN>
Hash - 간단한 SQL을 대체한다면?
● Insert into users(name, email) values(‘charsyam’, ‘charsyam@naver.com’);
● hmset charsyam name charsyam email charsyam@naver.com
Collection
주의 사항
Collection 주의 사항
● 하나의 컬렉션에 너무 많은 아이템을 담으면 좋지 않음
○ 10000개 이하 몇천개 수준으로 유지하는게 좋음.
● Expire는 Collection의 item 개별로 걸리지 않고 전체 Collection에 대해서만 걸림
○ 즉 해당 10000개의 아이템을 가진 Collection에 expire가 걸려있다면 그 시간 후에
10000개의 아이템이 모두 삭제.
Redis 운영
Redis 운영
● 메모리 관리를 잘하자.
● O(N) 관련 명령어는 주의하자.
● Replication
● 권장 설정 Tip
메모리 관리를 잘하자!
메모리 관리
● Redis 는 In-Memory Data Store.
● Physical Memory 이상을 사용하면 문제가 발생
○ Swap 이 있다면 Swap 사용으로 해당 메모리 Page
접근시 마다 늦어짐.
○ Swap이 없다면?
● Maxmemory를 설정하더라도 이보다 더 사용할 가능성이 큼.
● RSS 값을 모니터링 해야함.
메모리 관리
● 많은 업체가 현재 메모리를 사용해서 Swap을 쓰고 있다는 것을
모를때가 많음(T.T)
메모리 관리
● 큰 메모리를 사용하는 instance 하나보다는 적은 메모리를
사용하는 instance 여러개가 안전함.
● CPU 4 Core, 32GB Memory
24 GB Instance
8 GB Instance
8 GB Instance
8 GB Instance
메모리 관리
● Redis는 메모리 파편화가 발생할 수 있음. 4.x 대 부터 메모리
파현화를 줄이도록 jemlloc에 힌트를 주는 기능이 들어갔으나,
jemalloc 버전에 따라서 다르게 동작할 수 있음.
● 3.x대 버전의 경우
○ 실제 used memory는 2GB로 보고가 되지만 11GB의
RSS를 사용하는 경우가 자주 발생
● 다양한 사이즈를 가지는 데이터 보다는 유사한 크기의 데이터를
가지는 경우가 유리.
메모리가 부족할 때는?
● Cache is Cash!!!
○ 좀 더 메모리 많은 장비로 Migration.
○ 메모리가 빡빡하면 Migration 중에 문제가 발생할수도…
● 있는 데이터 줄이기.
○ 데이터를 일정 수준에서만 사용하도록 특정 데이터를 줄임.
○ 다만 이미 Swap을 사용중이라면, 프로세스를 재시작
해야함.
메모리를 줄이기 위한 설정
● 기본적으로 Collection 들은 다음과 같은 자료구조를 사용
○ Hash -> HashTable을 하나 더 사용
○ Sorted Set -> Skiplist와 HashTable을 이용.
○ Set -> HashTable 사용
○ 해당 자료구조들은 메모리를 많이 사용함.
● Ziplist 를 이용하자.
Ziplist 구조
● In-Memory 특성 상, 적은 개수라면 선형 탐색을 하더라도
빠르다.
● List, hash, sorted set 등을 ziplist로 대체해서 처리를 하는
설정이 존재
○ hash-max-ziplist-entries, hash-max-ziplist-value
○ list-max-ziplist-size, list-max-ziplist-value
○ zset-max-ziplist-entries, zset-max-ziplist-value
zlbytes zltail zllen entry entry ... entry zlend
O(N) 관련 명령어는 주의하자.
O(N) 관련 명령어는 주의하자.
● Redis 는 Single Threaded.
○ 그러면 Redis가 동시에 여러 개의 명령을 처리할 수
있을까?
○ 참고로 단순한 get/set의 경우, 초당 10만 TPS 이상
가능(CPU속도에 영향을 받습니다.)
Redis is Single Threaded.
processInputBuffer
packet
processCommand
packet packetpacket
Packet 으로 하나의 Command가 완성되면
processCommand 에서 실제로 실행됨
Single Threaded 의 의미
● Redis 는 Single Threaded.
○ 그러면 Redis가 동시에 여러 개의 명령을 처리할 수
있을까?
○ 참고로 단순한 get/set의 경우, 초당 10만 TPS 이상
가능(물리 서버기준, CPU속도에 영향을 받습니다.)
Single Threaded 의 의미
● 한번에 하나의 명령만 수행 가능
○ 그럼 긴 시간이 필요한 명령을 수행하면?
망합니다!!!
대표적인 O(N) 명령들
● KEYS
● FLUSHALL, FLUSHDB
● Delete Collections
● Get All Collections
대표적인 실수 사례
● Key가 백만개 이상인데 확인을 위해 KEYS 명령을 사용하는
경우
○ 모니터링 스크립트가 일초에 한번씩 keys를 호출하는
경우도...
● 아이템이 몇만개 든 hash, sorted set, set에서 모든
데이터를 가져오는 경우
● 예전의 Spring security oauth RedisTokenStore
KEYS 는 어떻게 대체할 것인가?
● scan 명령을 사용하는 것으로 하나의 긴 명령을 짧은 여러번의
명령으로 바꿀 수 있다.
redis 127.0.0.1:6379> scan 0
1) "17"
2) 1) "key:12"
2) "key:8"
3) "key:4"
redis 127.0.0.1:6379> scan 17
1) "0"
2) 1) "key:5"
2) "key:18"
3) "key:0"
7) "key:6"
8) "key:9"
9) "key:11"
Collection의 모든 item을 가져와야 할 때?
● Collection의 일부만 가져오거나…
○ Sorted Set
● 큰 Collection을 작은 여러개의 Collection으로 나눠서 저장
○ Userranks -> Userrank1, Userrank2, Userrank3
○ 하나당 몇천개 안쪽으로 저장하는게 좋음.
Spring security oauth RedisTokenStore 이슈
● Access Token의 저장을 List(O(N)) 자료구조를 통해서
이루어짐.
○ 검색, 삭제시에 모든 item을 매번 찾아봐야 함.
■ 100만개 쯤 되면 전체 성능에 영향을 줌.
○ 현재는 Set(O(1))을 이용해서 검색, 삭제를 하도록
수정되어있음.
Spring security oauth RedisTokenStore 이슈
● https://charsyam.wordpress.com/2018/05/11/입-개발-spring-security-oauth의-redistokenstore의-사용은-서비스에-
적합하지-않/
Redis Replication
Redis Replication
● Async Replication
○ Replication Lag 이 발생할 수 있다.
● “Replicaof’(>= 5.0.0) or ‘slaveof’ 명령으로 설정 가능
○ Replicaof hostname port
● DBMS로 보면 statement replication가 유사
Redis Replication
● Replication 설정 과정
○ Secondary에 replicaof or slaveof 명령을 전달
○ Secondary는 Primary에 sync 명령 전달
○ Primary는 현재 메모리 상태를 저장하기 위해
■ Fork
○ Fork 한 프로세서는 현재 메모리 정보를 disk에 dump
○ 해당 정보를 secondary 에 전달
○ Fork 이후의 데이터를 secondary에 계속 전달
Redis Replication 시 주의할 점
● Replication 과정에서 fork 가 발생하므로 메모리 부족이
발생할 수 있다.
● Redis-cli --rdb 명령은 현재 상태의 메모리 스냅샷을
가져오므로 같은 문제를 발생시킴
● AWS나 클라우드의 Redis는 좀 다르게 구현되어서 좀더 해당
부분이 안정적.
Redis Replication 시 주의할 점
● 많은 대수의 Redis 서버가 Replica를 두고 있다면
○ 네트웍 이슈나, 사람의 작업으로 동시에 replication이
재시도 되도록 하면 문제가 발생할 수 있음.
○ ex) 같은 네트웍안에서 30GB를 쓰는 Redis Master
100대 정도가 리플리케이션을 동시에 재시작하면 어떤 일이
벌어질 수 있을까?
권장 설정 Tip(redis.conf)
redis.conf 권장 설정 Tip
● Maxclient 설정 50000
● RDB/AOF 설정 off
● 특정 commands disable
○ Keys
○ AWS의 ElasticCache는 이미 하고 있음.
● 전체 장애의 90% 이상이 KEYS와 SAVE 설정을 사용해서
발생.
● 적절한 ziplist 설정
Redis 데이터 분산
Redis 데이터 분산
● 데이터의 특성에 따라서 선택할 수 있는 방법이 달라진다.
○ Cache 일때는 우아한 Redis(정말?)
○ Persistent 해야하면 안 우아한 Redis!!!
■ Open the hellgate!!!
데이터 분산 방법
데이터 분산 방법
● Application
○ Consistent Hashing
■ twemproxy 를 사용하는 방법으로 쉽게 사용 가능
○ Sharding
● Redis Cluster
Consistent Hashing
WHY?
There was data
In the beginning.
1
2
3 4
5
6
7
89
How do you distribute data
pairly into 3 servers?
Considering the future.
1
2
3
4
5
6
7
8
9
Sequence
1 2 3
4 5 6
7 8 9
Modular
If you add one server, or
remove one server
What happened?
1
2
3
4
5
6
Add one server for Sequence
7
8
9
Add one server for Modular
1 2 3
4 5 6
7 8 9
How do you redistribute
these data?
Redistribute by Modular
1 2 3 4
5 6 7 8
9
Most of data is
redistributed!
Redistribution is
Burden.
What is a good way
to reduce redistribution?
Consistent Hashing
Can Do!!!
Consistent Hashing
redistribute
only N/K data
N = data size K = servers
Key Concept is
Hash
What is main
concept of hash
If you use
The same hash function?
The result is always the same.
hash(“abc”) = 1
hash(“abc1”) = 2
hash(“abc”) = 1
You have 3 servers.
10.0.1.1
10.0.1.2
10.0.1.3
There is a hash function.
y = hash(x)
You hash 3 servers
hash(“10.0.1.1”) = 100
hash(“10.0.1.2”) = 400
hash(“10.0.1.3”) = 700
Just Giving server address as key
Just define a rule.
We will store a key in
hash(key) is higher and the
nearest one.
hash(key) Hash value
hash(“10.0.1.1”) 100
hash(“10.0.1.2”) 400
hash(“10.0.1.3”) 700
There is key “redis”
hash(“redis”) = 200
Where we store it?
hash(key) Hash value
hash(“10.0.1.1”) 100
hash(“redis”) 200 in hash(“10.0.1.2”)
hash(“10.0.1.2”) 400
hash(“10.0.1.3”) 700
There is key “charsyam”
hash(“charsyam”) = 450
Where we store it?
hash(key) Hash value
hash(“10.0.1.1”) 100
hash(“redis”) 200 in hash(“10.0.1.2”)
hash(“10.0.1.2”) 400
hash(“charsyam”) 450 in hash(“10.0.1.3”)
hash(“10.0.1.3”) 700
There is key “udemy”
hash(“udemy”) = 50
Where we store it?
hash(key) Hash value
hash(“udemy”) 50 in hash(“10.0.1.1”)
hash(“10.0.1.1”) 100
hash(“redis”) 200 in hash(“10.0.1.2”)
hash(“10.0.1.2”) 400
hash(“charsyam”) 450 in hash(“10.0.1.3”)
hash(“10.0.1.3”) 700
There is key “web”
hash(“web”) = 1000
Where we store it?
There is no server has
higher hash value 1000.
Where we can store it?
Think it is Circle
hash(key) Hash value
hash(“udemy”) 50 in hash(“10.0.1.1”)
hash(“10.0.1.1”) 100
hash(“redis”) 200 in hash(“10.0.1.2”)
hash(“10.0.1.2”) 400
hash(“charsyam”) 450 in hash(“10.0.1.3”)
hash(“10.0.1.3”) 700
hash(“web”) 1000 in hash(“10.0.1.1”)
Key “web” is stored in
First Server.
If we add new server
It is “10.0.1.4”.
And hash(“10.0.1.4”) = 500
hash(key) Hash value
hash(“udemy”) 50 in hash(“10.0.1.1”)
hash(“10.0.1.1”) 100
hash(“redis”) 200 in hash(“10.0.1.2”)
hash(“10.0.1.2”) 400
DELETED hash(“charsyam”) 450
hash(“10.0.1.4”) 500
hash(“10.0.1.3”) 700
hash(“web”) 1000 in hash(“10.0.1.1”)
After adding “10.0.1.4”
Key “charsyam” is
missing
But other keys are
never changed.
You can still find key
“udemy” in “10.0.1.1”
There is key “charsyam”
hash(“charsyam”) = 450
Where we store it?
hash(key) Hash value
hash(“udemy”) 50 in hash(“10.0.1.1”)
hash(“10.0.1.1”) 100
hash(“redis”) 200 in hash(“10.0.1.2”)
hash(“10.0.1.2”) 400
hash(“charsyam”) 450 in hash(“10.0.1.4”)
hash(“10.0.1.4”) 500
hash(“10.0.1.3”) 700
hash(“web”) 1000 in hash(“10.0.1.1”)
A
Add A Server
A
B
Add B Server
A
BC
Add C Server
A
BC
Add Key 1
1
A
BC
Add Key 2
1
2
A
BC
Add Key 3
1
2
3
A
BC
Add Key 4
1
2
3
4
A
BC
Add Key 5
1
2
3
4
5
A
C
Fail B Server
2
3
4
5
A
C
Add Key 1
2
3
4
5
1
서버 주소를 해싱하는 것보다
Nickname으로 해싱 하는 것이
더 변동이 적음
Sharding
데이터를 어떻게 나눌것인가?
데이터를 어떻게 찾을것인가?
하나의 데이터를 모든 서버에서
찾아야 하면?
상황마다 샤딩 전략이 달라짐
Range
● 그냥 특정 Range를 정의하고 해당 Range에 속하면 거기에
저장.
○ Key 500 은 어디에 저장되어야 할까?
1~1000 1001~2000 2001~3000
Range
● 특정 Range 서버에만 부하가 몰릴 가능성이 높다.
○ 활동량이 많은 유저가 많은 서버는?
■ 이벤트 때문에 가입한 유저들.
Modular
● N % K 로 서버의 데이터를 결정
● Range 보다 데이터를 균등하게 분배할 가능성이 높다.
1
3
5
7
2
4
6
8
Modular
● 서버 한대가 추가될 때 재분배 양이 많아진다.
1
4
7
2
5
8
3
6
Indexed
● 해당 Key가 어디에 저장되어야 할 관리 서버가 따로 존재
1000
10001
1
200
Index
Server
2
3
1. Where is 2?
2. 2 is on Server 3
client
Redis Cluster
Redis Cluster
● Hash 기반으로 Slot 16384 로 구분
○ Hash 알고리즘은 CRC16을 사용
○ Slot = crc16(key) % 16384
○ Key가 Key{hashkey} 패턴이면 실제 crc16에
hashkey가 사용된다.
○ 특정 Redis 서버는 이 slot range를 가지고 있고, 데이터
migration은 이 slot 단위의 데이터를 다른 서버로
전달하게 된다.(migrateCommand 이용)
Redis Cluster
Primary #1
Primary #2
Primary #3
Secondary #1
Secondary #2
Secondary #3
Client
Redis Cluster
Primary #1
Primary #2
Primary #3
Secondary #1
Primary #2
Secondary #3
Client
Redis Cluster
Primary #1
Primary #2
Primary #3
Secondary #1
Secondary #2
Secondary #3
Client
Slot: 0~5555
Slot: 5556~11000
Slot: 11001~16383
Set Slot0_key abc
Redis Cluster
Primary #1
Primary #2
Primary #3
Secondary #1
Secondary #2
Secondary #3
Client
Slot: 0~5555
Slot: 5556~11000
Slot: 11001~16383
+OK
Redis Cluster
Primary #1
Primary #2
Primary #3
Secondary #1
Secondary #2
Secondary #3
Client
Slot: 0~5555
Slot: 5556~11000
Slot: 11001~16383
Set Slot5506_key abc
Redis Cluster
Primary #1
Primary #2
Primary #3
Secondary #1
Secondary #2
Secondary #3
Client
Slot: 0~5555
Slot: 5556~11000
Slot: 11001~16383
-MOVED Primary #2
Redis Cluster의 장점/단점
● 장점
○ 자체적인 Primary, Secondary Failover.
○ Slot 단위의 데이터 관리.
● 단점
○ 메모리 사용량이 더 많음
○ Migration 자체는 관리자가 시점을 결정해야 함.
○ Library 구현이 필요함.
Redis Failover
Redis Failover
● Coordinator 기반 Failover
● VIP/DNS 기반 Failover
● Redis Cluster 의 사용
Coordinator 기반
● Zookeeper, etcd, consul 등의 Coordinator 사용
API Server
Redis #1 : P
Redis #2 : S
Coordinator: current Redis is Redis #1
Health
Checker
Coordinator 기반
API Server
Redis #1 : P
Redis #2 : S
Coordinator: current Redis is Redis #1
Health
Checker
Coordinator 기반
API Server
Redis #1 : P
Redis #2 : P
Coordinator: current Redis is Redis #1
Health
Checker
Health Checker는 Redis #2를 Primary
로 승격시킨다.
Coordinator 기반
API Server
Redis #1 : P
Redis #2 : P
Coordinator: current Redis is Redis #2
Health
Checker
Health Checker는 Redis #2를 Primary
로 승격시킨다.
Health Checker는 Coordinator에 current
Redis가 Redis #2라고 업데이트 한다.
Coordinator 기반
API Server
Redis #1 : P
Redis #2 : P
Coordinator: current Redis is Redis #2
Health
Checker
Health Checker는 Redis #2를 Primary
로 승격시킨다.
Health Checker는 Coordinator에 current
Redis가 Redis #2라고 업데이트 한다.
Coordinator는 API Server에 current Redis
가 변경되었다고 알려준다.
Coordinator 기반
● Coordinator 기반으로 설정을 관리한다면 동일한 방식으로
관리가 가능.
● 해당 기능을 이용하도록 개발이 필요하다.
VIP 기반
API Server Redis #1 : P
Redis #2 : S
Health
Checker
VIP: 10.0.1.1.
API Server는 10.0.1.1로만 접속
VIP 기반
API Server Redis #1 : P
Redis #2 : S
Health
Checker
VIP: 10.0.1.1.
API Server는 10.0.1.1로만 접속
VIP 기반
API Server Redis #1 : P
Redis #2 : P
Health
Checker
VIP: 10.0.1.1.
API Server는 10.0.1.1로만 접속
Health Checker는 Redis #2를 Primary
로 승격시킨다.
VIP 기반
API Server Redis #1 : P
Redis #2 : P
Health
Checker
VIP: 10.0.1.1.
API Server는 10.0.1.1로만 접속
Health Checker는 Redis #2를 Primary
로 승격시킨다.
Health Checker는 VIP 10.0.1.1 을 Redis #2
로 할당한다.
VIP 기반
API Server Redis #1 : P
Redis #2 : P
Health
Checker
VIP: 10.0.1.1.
API Server는 10.0.1.1로만 접속
Health Checker는 Redis #2를 Primary
로 승격시킨다.
Health Checker는 VIP 10.0.1.1 을 Redis #2
로 할당한다.
Health Checker는 Redis #1에 있던 기존 연결을
모두 끊어준다.(클라이언트의 재접속 유도)
DNS 기반
API Server Redis #1 : P
Redis #2 : S
Health
Checker
DNS: redis-primary.svc.io
API Server는 redis-primary.svc.io로만 접속
DNS 기반
API Server Redis #1 : P
Redis #2 : S
Health
Checker
DNS: redis-primary.svc.io
API Server는 redis-primary.svc.io로만 접속
DNS 기반
API Server Redis #1 : P
Redis #2 : P
Health
Checker
DNS: redis-primary.svc.io
API Server는 redis-primary.svc.io로만 접속
Health Checker는 Redis #2를 Primary
로 승격시킨다.
DNS 기반
API Server Redis #1 : P
Redis #2 : P
Health
Checker
DNS: redis-primary.svc.io
API Server는 redis-primary.svc.io로만 접속
Health Checker는 Redis #2를 Primary
로 승격시킨다.
DNS 기반
API Server Redis #1 : P
Redis #2 : P
Health
Checker
DNS: redis-primary.svc.io
API Server는 redis-primary.svc.io로만 접속
Health Checker는 Redis #2를 Primary
로 승격시킨다.
Health Checker는 DNS: redis-primary.svc.io
을 Redis #2 로 할당한다.
DNS 기반
API Server Redis #1 : P
Redis #2 : P
Health
Checker
DNS: redis-primary.svc.io
API Server는 redis-primary.svc.io로만 접속
Health Checker는 Redis #2를 Primary
로 승격시킨다.
Health Checker는 DNS: redis-primary.svc.io
을 Redis #2 로 할당한다.
Health Checker는 Redis #1에 있던 기존 연결을
모두 끊어준다.(클라이언트의 재접속 유도)
VIP/DNS 기반
● 클라이언트에 추가적인 구현이 필요없다.
● VIP 기반은 외부로 서비스를 제공해야 하는 서비스 업자에 유리
(예를 들어 클라우드 업체)
● DNS 기반은 DNS Cache TTL을 관리해야 함.
○ 사용하는 언어별 DNS 캐싱 정책을 잘 알아야 함
○ 툴에 따라서 한번 가져온 DNS 정보를 다시 호출 하지 않는
경우도 존재
Monitoring
Monitoring Factor
● Redis Info를 통한 정보
○ RSS
○ Used Memory
○ Connection 수
○ 초당 처리 요청 수
● System
○ CPU
○ Disk
○ Network rx/tx
CPU가 100%를 칠 경우
● 처리량이 매우 많다면?
○ 좀 더 CPU 성능이 좋은 서버로 이전
○ 실제 CPU 성능에 영향을 받음
■ 그러나 단순 get/set은 초당 10만 이상 처리가능
● O(N) 계열의 특정 명령이 많은 경우.
○ Monitor 명령을 통해 특정 패턴을 파악하는 것이 필요
○ Monitor 잘못쓰면 부하로 해당 서버에 더 큰 문제를
일으킬 수도 있음.(짧게 쓰는게 좋음)
결론
결론
● 기본적으로 Redis는 매우 좋은 툴
● 그러나 메모리를 빡빡하게 쓸 경우, 관리하기가 어려움
○ 32기가 장비라면 24기가 이상 사용하면 장비 증설을
고려하는 것이 좋음.
○ Write가 Heavy 할 때는 migration도 매우 주의해야함.
● Client-output-buffer-limit 설정이 필요.
Redis as Cache
● Cache 일 경우는 문제가 적게 발생
○ Redis 가 문제가 있을 때 DB등의 부하가 어느정도
증가하는 지 확인 필요.
○ Consistent Hashing도 실제 부하를 아주 균등하게
나누지는 않음. Adaptive Consistent Hashing 을
이용해 볼 수도 있음.
Redis as Persistent Store
● Persistent Store의 경우
○ 무조건 Primary/Secondary 구조로 구성이 필요함
○ 메모리를 절대로 빡빡하게 사용하면 안됨.
■ 정기적인 migration이 필요.
■ 가능하면 자동화 툴 을 만들어서 이용
○ RDB/AOF가 필요하다면 Secondary에서만 구동
감사합니다.

Contenu connexe

Tendances

mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교Woo Yeong Choi
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유Hyojun Jeon
 
Maria db 이중화구성_고민하기
Maria db 이중화구성_고민하기Maria db 이중화구성_고민하기
Maria db 이중화구성_고민하기NeoClova
 
서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)수보 김
 
클라우드 기반 AWS 데이터베이스 선택 옵션 - AWS Summit Seoul 2017
클라우드 기반 AWS 데이터베이스 선택 옵션 - AWS Summit Seoul 2017 클라우드 기반 AWS 데이터베이스 선택 옵션 - AWS Summit Seoul 2017
클라우드 기반 AWS 데이터베이스 선택 옵션 - AWS Summit Seoul 2017 Amazon Web Services Korea
 
로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법Jeongsang Baek
 
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...Amazon Web Services Korea
 
Cloud DW technology trends and considerations for enterprises to apply snowflake
Cloud DW technology trends and considerations for enterprises to apply snowflakeCloud DW technology trends and considerations for enterprises to apply snowflake
Cloud DW technology trends and considerations for enterprises to apply snowflakeSANG WON PARK
 
ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기Yungon Park
 
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개if kakao
 
[2019] 200만 동접 게임을 위한 MySQL 샤딩
[2019] 200만 동접 게임을 위한 MySQL 샤딩[2019] 200만 동접 게임을 위한 MySQL 샤딩
[2019] 200만 동접 게임을 위한 MySQL 샤딩NHN FORWARD
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)Hyojun Jeon
 
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?Juhong Park
 
[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영NAVER D2
 
MySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptxMySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptxNeoClova
 
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016Amazon Web Services Korea
 
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016Amazon Web Services Korea
 
Spark + S3 + R3를 이용한 데이터 분석 시스템 만들기
Spark + S3 + R3를 이용한 데이터 분석 시스템 만들기Spark + S3 + R3를 이용한 데이터 분석 시스템 만들기
Spark + S3 + R3를 이용한 데이터 분석 시스템 만들기AWSKRUG - AWS한국사용자모임
 
DynamoDB의 안과밖 - 정민영 (비트패킹 컴퍼니)
DynamoDB의 안과밖 - 정민영 (비트패킹 컴퍼니)DynamoDB의 안과밖 - 정민영 (비트패킹 컴퍼니)
DynamoDB의 안과밖 - 정민영 (비트패킹 컴퍼니)AWSKRUG - AWS한국사용자모임
 

Tendances (20)

mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교mongodb와 mysql의 CRUD 연산의 성능 비교
mongodb와 mysql의 CRUD 연산의 성능 비교
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유
 
Maria db 이중화구성_고민하기
Maria db 이중화구성_고민하기Maria db 이중화구성_고민하기
Maria db 이중화구성_고민하기
 
서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)
 
클라우드 기반 AWS 데이터베이스 선택 옵션 - AWS Summit Seoul 2017
클라우드 기반 AWS 데이터베이스 선택 옵션 - AWS Summit Seoul 2017 클라우드 기반 AWS 데이터베이스 선택 옵션 - AWS Summit Seoul 2017
클라우드 기반 AWS 데이터베이스 선택 옵션 - AWS Summit Seoul 2017
 
로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법
 
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
 
Cloud DW technology trends and considerations for enterprises to apply snowflake
Cloud DW technology trends and considerations for enterprises to apply snowflakeCloud DW technology trends and considerations for enterprises to apply snowflake
Cloud DW technology trends and considerations for enterprises to apply snowflake
 
ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기ECS+Locust로 부하 테스트 진행하기
ECS+Locust로 부하 테스트 진행하기
 
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개
 
[2019] 200만 동접 게임을 위한 MySQL 샤딩
[2019] 200만 동접 게임을 위한 MySQL 샤딩[2019] 200만 동접 게임을 위한 MySQL 샤딩
[2019] 200만 동접 게임을 위한 MySQL 샤딩
 
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)
[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)
 
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
 
[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영
 
MySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptxMySQL_MariaDB-성능개선-202201.pptx
MySQL_MariaDB-성능개선-202201.pptx
 
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
 
Scalable webservice
Scalable webserviceScalable webservice
Scalable webservice
 
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
 
Spark + S3 + R3를 이용한 데이터 분석 시스템 만들기
Spark + S3 + R3를 이용한 데이터 분석 시스템 만들기Spark + S3 + R3를 이용한 데이터 분석 시스템 만들기
Spark + S3 + R3를 이용한 데이터 분석 시스템 만들기
 
DynamoDB의 안과밖 - 정민영 (비트패킹 컴퍼니)
DynamoDB의 안과밖 - 정민영 (비트패킹 컴퍼니)DynamoDB의 안과밖 - 정민영 (비트패킹 컴퍼니)
DynamoDB의 안과밖 - 정민영 (비트패킹 컴퍼니)
 

Similaire à Redis

Intro KaKao ADT (Almighty Data Transmitter)
Intro KaKao ADT (Almighty Data Transmitter)Intro KaKao ADT (Almighty Data Transmitter)
Intro KaKao ADT (Almighty Data Transmitter)I Goo Lee
 
NDC 2016, [슈판워] 맨땅에서 데이터 분석 시스템 만들어나가기
NDC 2016, [슈판워] 맨땅에서 데이터 분석 시스템 만들어나가기NDC 2016, [슈판워] 맨땅에서 데이터 분석 시스템 만들어나가기
NDC 2016, [슈판워] 맨땅에서 데이터 분석 시스템 만들어나가기Wonha Ryu
 
일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항
일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항
일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항Minchul Jung
 
Vectorized processing in_a_nutshell_DeView2014
Vectorized processing in_a_nutshell_DeView2014Vectorized processing in_a_nutshell_DeView2014
Vectorized processing in_a_nutshell_DeView2014Gruter
 
if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04Klaytn
 
[자바카페] 람다 일괄처리 계층
[자바카페] 람다 일괄처리 계층[자바카페] 람다 일괄처리 계층
[자바카페] 람다 일괄처리 계층용호 최
 
DevRookie 메모리 최적화.pptx
DevRookie 메모리 최적화.pptxDevRookie 메모리 최적화.pptx
DevRookie 메모리 최적화.pptxMUUMUMUMU
 
[스마트스터디]모바일 애플리케이션 서비스에서의 로그 수집과 분석
[스마트스터디]모바일 애플리케이션 서비스에서의 로그 수집과 분석[스마트스터디]모바일 애플리케이션 서비스에서의 로그 수집과 분석
[스마트스터디]모바일 애플리케이션 서비스에서의 로그 수집과 분석smartstudy_official
 
[246] foursquare데이터라이프사이클 설현준
[246] foursquare데이터라이프사이클 설현준[246] foursquare데이터라이프사이클 설현준
[246] foursquare데이터라이프사이클 설현준NAVER D2
 
SQL performance and UDF
SQL performance and UDFSQL performance and UDF
SQL performance and UDFJAEGEUN YU
 
From MSSQL to MySQL
From MSSQL to MySQLFrom MSSQL to MySQL
From MSSQL to MySQLI Goo Lee
 
KGC 2014 가볍고 유연하게 데이터 분석하기 : 쿠키런 사례 중심 , 데브시스터즈
KGC 2014 가볍고 유연하게 데이터 분석하기 : 쿠키런 사례 중심 , 데브시스터즈KGC 2014 가볍고 유연하게 데이터 분석하기 : 쿠키런 사례 중심 , 데브시스터즈
KGC 2014 가볍고 유연하게 데이터 분석하기 : 쿠키런 사례 중심 , 데브시스터즈Minwoo Kim
 
The nosql echossytem
The nosql echossytemThe nosql echossytem
The nosql echossytem종석 박
 
DataWorks Summit 2017
DataWorks Summit 2017DataWorks Summit 2017
DataWorks Summit 2017Daesung Park
 
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)HYUNJEONG KIM
 
Giip kb-hadoop sizing
Giip kb-hadoop sizingGiip kb-hadoop sizing
Giip kb-hadoop sizingLowy Shin
 
[스마트스터디]MongoDB 의 역습
[스마트스터디]MongoDB 의 역습[스마트스터디]MongoDB 의 역습
[스마트스터디]MongoDB 의 역습smartstudy_official
 
Webservice cache strategy
Webservice cache strategyWebservice cache strategy
Webservice cache strategyDaeMyung Kang
 
스프링 데이터 레디스 엘라스틱 발표자료
스프링 데이터 레디스 엘라스틱 발표자료스프링 데이터 레디스 엘라스틱 발표자료
스프링 데이터 레디스 엘라스틱 발표자료라한사 아
 

Similaire à Redis (20)

Intro KaKao ADT (Almighty Data Transmitter)
Intro KaKao ADT (Almighty Data Transmitter)Intro KaKao ADT (Almighty Data Transmitter)
Intro KaKao ADT (Almighty Data Transmitter)
 
NDC 2016, [슈판워] 맨땅에서 데이터 분석 시스템 만들어나가기
NDC 2016, [슈판워] 맨땅에서 데이터 분석 시스템 만들어나가기NDC 2016, [슈판워] 맨땅에서 데이터 분석 시스템 만들어나가기
NDC 2016, [슈판워] 맨땅에서 데이터 분석 시스템 만들어나가기
 
일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항
일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항
일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항
 
Vectorized processing in_a_nutshell_DeView2014
Vectorized processing in_a_nutshell_DeView2014Vectorized processing in_a_nutshell_DeView2014
Vectorized processing in_a_nutshell_DeView2014
 
if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04if kakao dev 2019_Ground X_Session 04
if kakao dev 2019_Ground X_Session 04
 
[자바카페] 람다 일괄처리 계층
[자바카페] 람다 일괄처리 계층[자바카페] 람다 일괄처리 계층
[자바카페] 람다 일괄처리 계층
 
DevRookie 메모리 최적화.pptx
DevRookie 메모리 최적화.pptxDevRookie 메모리 최적화.pptx
DevRookie 메모리 최적화.pptx
 
[스마트스터디]모바일 애플리케이션 서비스에서의 로그 수집과 분석
[스마트스터디]모바일 애플리케이션 서비스에서의 로그 수집과 분석[스마트스터디]모바일 애플리케이션 서비스에서의 로그 수집과 분석
[스마트스터디]모바일 애플리케이션 서비스에서의 로그 수집과 분석
 
[246] foursquare데이터라이프사이클 설현준
[246] foursquare데이터라이프사이클 설현준[246] foursquare데이터라이프사이클 설현준
[246] foursquare데이터라이프사이클 설현준
 
SQL performance and UDF
SQL performance and UDFSQL performance and UDF
SQL performance and UDF
 
From MSSQL to MySQL
From MSSQL to MySQLFrom MSSQL to MySQL
From MSSQL to MySQL
 
KGC 2014 가볍고 유연하게 데이터 분석하기 : 쿠키런 사례 중심 , 데브시스터즈
KGC 2014 가볍고 유연하게 데이터 분석하기 : 쿠키런 사례 중심 , 데브시스터즈KGC 2014 가볍고 유연하게 데이터 분석하기 : 쿠키런 사례 중심 , 데브시스터즈
KGC 2014 가볍고 유연하게 데이터 분석하기 : 쿠키런 사례 중심 , 데브시스터즈
 
The nosql echossytem
The nosql echossytemThe nosql echossytem
The nosql echossytem
 
DataWorks Summit 2017
DataWorks Summit 2017DataWorks Summit 2017
DataWorks Summit 2017
 
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
알고리즘 연합캠프 세미나 1-C (알고리즘 설계와 모델링 및 수학)
 
Giip kb-hadoop sizing
Giip kb-hadoop sizingGiip kb-hadoop sizing
Giip kb-hadoop sizing
 
[스마트스터디]MongoDB 의 역습
[스마트스터디]MongoDB 의 역습[스마트스터디]MongoDB 의 역습
[스마트스터디]MongoDB 의 역습
 
Redis acc 2015
Redis acc 2015Redis acc 2015
Redis acc 2015
 
Webservice cache strategy
Webservice cache strategyWebservice cache strategy
Webservice cache strategy
 
스프링 데이터 레디스 엘라스틱 발표자료
스프링 데이터 레디스 엘라스틱 발표자료스프링 데이터 레디스 엘라스틱 발표자료
스프링 데이터 레디스 엘라스틱 발표자료
 

Plus de DaeMyung Kang

How to use redis well
How to use redis wellHow to use redis well
How to use redis wellDaeMyung Kang
 
The easiest consistent hashing
The easiest consistent hashingThe easiest consistent hashing
The easiest consistent hashingDaeMyung Kang
 
How to name a cache key
How to name a cache keyHow to name a cache key
How to name a cache keyDaeMyung Kang
 
Integration between Filebeat and logstash
Integration between Filebeat and logstash Integration between Filebeat and logstash
Integration between Filebeat and logstash DaeMyung Kang
 
Data Engineering 101
Data Engineering 101Data Engineering 101
Data Engineering 101DaeMyung Kang
 
How To Become Better Engineer
How To Become Better EngineerHow To Become Better Engineer
How To Become Better EngineerDaeMyung Kang
 
Kafka timestamp offset_final
Kafka timestamp offset_finalKafka timestamp offset_final
Kafka timestamp offset_finalDaeMyung Kang
 
Kafka timestamp offset
Kafka timestamp offsetKafka timestamp offset
Kafka timestamp offsetDaeMyung Kang
 
Data pipeline and data lake
Data pipeline and data lakeData pipeline and data lake
Data pipeline and data lakeDaeMyung Kang
 
Internet Scale Service Arichitecture
Internet Scale Service ArichitectureInternet Scale Service Arichitecture
Internet Scale Service ArichitectureDaeMyung Kang
 
Redis From 2.8 to 4.x(unstable)
Redis From 2.8 to 4.x(unstable)Redis From 2.8 to 4.x(unstable)
Redis From 2.8 to 4.x(unstable)DaeMyung Kang
 
Redis From 2.8 to 4.x
Redis From 2.8 to 4.xRedis From 2.8 to 4.x
Redis From 2.8 to 4.xDaeMyung Kang
 

Plus de DaeMyung Kang (20)

Count min sketch
Count min sketchCount min sketch
Count min sketch
 
Ansible
AnsibleAnsible
Ansible
 
Why GUID is needed
Why GUID is neededWhy GUID is needed
Why GUID is needed
 
How to use redis well
How to use redis wellHow to use redis well
How to use redis well
 
The easiest consistent hashing
The easiest consistent hashingThe easiest consistent hashing
The easiest consistent hashing
 
How to name a cache key
How to name a cache keyHow to name a cache key
How to name a cache key
 
Integration between Filebeat and logstash
Integration between Filebeat and logstash Integration between Filebeat and logstash
Integration between Filebeat and logstash
 
Data Engineering 101
Data Engineering 101Data Engineering 101
Data Engineering 101
 
How To Become Better Engineer
How To Become Better EngineerHow To Become Better Engineer
How To Become Better Engineer
 
Kafka timestamp offset_final
Kafka timestamp offset_finalKafka timestamp offset_final
Kafka timestamp offset_final
 
Kafka timestamp offset
Kafka timestamp offsetKafka timestamp offset
Kafka timestamp offset
 
Data pipeline and data lake
Data pipeline and data lakeData pipeline and data lake
Data pipeline and data lake
 
Redis acl
Redis aclRedis acl
Redis acl
 
Coffee store
Coffee storeCoffee store
Coffee store
 
Number system
Number systemNumber system
Number system
 
Internet Scale Service Arichitecture
Internet Scale Service ArichitectureInternet Scale Service Arichitecture
Internet Scale Service Arichitecture
 
Bloomfilter
BloomfilterBloomfilter
Bloomfilter
 
Redis From 2.8 to 4.x(unstable)
Redis From 2.8 to 4.x(unstable)Redis From 2.8 to 4.x(unstable)
Redis From 2.8 to 4.x(unstable)
 
Redis From 2.8 to 4.x
Redis From 2.8 to 4.xRedis From 2.8 to 4.x
Redis From 2.8 to 4.x
 
Soma search
Soma searchSoma search
Soma search
 

Redis

  • 2. 목차 ● Redis 소개 ● 왜 Collection이 중요한가? ● Redis Collections ● Redis 운영 ● Redis 데이터 분산 ● Redis Failover
  • 3. 오늘 발표에서 다루지 않는 것들 ● Redis Persistence(RDB, AOF) ● Redis Pub/Sub ● Redis Stream ● 확률적 자료구조 ○ Hyperloglog ● Redis Module
  • 4. Redis 소개 ● In-Memory Data Structure Store ● Open Source(BSD 3 License) ● Support data structures ○ Strings, set, sorted-set, hashes, list ○ Hyperloglog, bitmap, geospatial index ○ Stream ● Only 1 Committer
  • 5. Redis 를 소개하기 전에 Cache 먼저~~~
  • 7. Cache의 정의 ● Cache 는 나중에 요청올 결과를 미리 저장해두었다가 빠르게 서비스를 해주는 것을 의미
  • 9. Factorial 의 계산 ● 10! = 10 * 9! = 10 * 9 * 8! = 10 * 9 * 8 * 7! ● 19! = 19 * 18 * 17 * 16 * 15 * 14 * 13 * 12 * 11 * 10! ● 팩토리얼 숫자가 크다면? ○ 20880!, 20881! 를 매번 계산해야 한다면?
  • 10. 20880! 를 계산해 두고 어딘가에 저장해 뒀다면 20881! 계산은 금방!!!!
  • 14. 아주 추상적인 웹서비스 구조 Client Web Server DB DB 안에는 많은 데이터들이 있고, 이 때 주로 디스크에 내용이 저장되게 됩니다.
  • 17. Cache 구조 #1 - Look aside Cache Client Web Server DB Memory Cache를 이용하게 되면 훨씬 더 빠른 속도로 서비스가 가능합니다. Cache 1. Web Server 는 데이터가 존재하는지 Cache를 먼저 확인 2. Cache에 데이터가 있으면 Cache에서 가져온다. 3. Cache에 데이터가 없다면 DB에서 읽어온다. 4. DB에서 읽어온 데이터를 Cache에 다시 저장한다.
  • 18. Cache 구조 #2 - Write Back Client Web Server DB Memory Cache를 이용하게 되면 훨씬 더 빠른 속도로 서비스가 가능합니다. Cache 1. Web Server 는 모든 데이터를 Cache에만 저장 2. Cache에 특정 시간동안의 데이터가 저장 3. Cache에 있는 데이터를 DB에 저장한다. 4. DB에 저장된 데이터를 삭제한다.
  • 19. 왜 Collection 이 중요한가? ● 개발의 편의성 ● 개발의 난이도
  • 20. 개발의 편의성 랭킹 서버를 직접 구현한다면?
  • 21. 개발의 편의성 ● 가장 간단한 방법 ○ DB에 유저의 Score를 저장하고 Score 로 order by로 정렬 후 읽어오기.
  • 22. 개발의 편의성 ● 가장 간단한 방법 ○ DB에 유저의 Score를 저장하고 Score 로 order by로 정렬 후 읽어오기. ○ 개수가 많아지면 속도에 문제가 발생할 수 있음. ■ 결국은 디스크를 사용하므로
  • 23. 개발의 편의성 ● In-Memory 기준으로 랭킹 서버의 구현이 필요함. ○ 능력자면, 금방 만드실....(?)
  • 24. 개발의 편의성 ● Redis의 Sorted Set을 이용하면, 랭킹을 구현 할 수 있음. ○ 덤으로, Replication도 가능… ○ 다만 가져다 쓰면 거기의 한계에 종속적이 됨. ■ 랭킹에 저장해야할 id가 1개당 100byte라고 했을때 ● 10명 1K ● 10000명 1M ● 10000000명 1G ● 10000000000 명 1TB
  • 26. 개발의 난이도 ● 친구 리스트를 KEY/VALUE 형태로 저장해야 한다면? ○ 현재 유저 123의 친구 Key는 friends:123, 현재 친구 A가 있는 중 T1(친구 B를 추가) ● 친구 리스트 friends:123 을 읽는다. ● friends:123 의 끝에 친구 B를 추가한다. ● 해당 값을 friend:123 에 저장한다. T1(친구 C를 추가) ● 친구 리스트 friends:123 을 읽는다. ● friends:123 의 끝에 친구 C를 추가한다. ● 해당 값을 friend:123 에 저장한다.
  • 27. 개발의 난이도 ● 어떤 문제가 발생할 수 있을까요? T1(친구 B를 추가) ● 친구 리스트 friends:123 을 읽는다. ● friends:123 의 끝에 친구 B를 추가한다. ● 해당 값을 friend:123 에 저장한다. T1(친구 C를 추가) ● 친구 리스트 friends:123 을 읽는다. ● friends:123 의 끝에 친구 C를 추가한다. ● 해당 값을 friend:123 에 저장한다.
  • 28. 개발의 난이도 ● 어떤 문제가 발생할 수 있을까요? 시간순서 T1(친구 B 추가) T2(친구 C 추가) 최종상태 1 friends:123 읽기 A 2 친구 B 추가 A 3 friends:123 쓰기 A, B 4 friends:123 읽기 A, B 5 친구 C 추가 A, B 6 friends:123 쓰기 A, B, C
  • 29. 개발의 난이도 ● Race Condition 시간순서 T1(친구 B 추가) T2(친구 C 추가) 최종상태 1 friends:123 읽기 A 2 friends:123 읽기 A 3 친구 B 추가 A 4 친구 C 추가 A 5 friends:123 쓰기 A, B 6 friends:123 쓰기 A, C
  • 30. 개발의 난이도 ● Race Condition 시간순서 T1(친구 B 추가) T2(친구 C 추가) 최종상태 1 friends:123 읽기 A 2 friends:123 읽기 A 3 친구 B 추가 A 4 친구 C 추가 A 5 friends:123 쓰기 A, C 6 friends:123 쓰기 A, B
  • 31. 개발의 난이도 ● Redis의 경우는 자료구조가 Atomic 하기 때문에, 해당 Race Condition 을 피할 수 있습니다. ○ 그래도 잘못짜면 발생함.
  • 32. 왜 Collection 이 중요한가? ● 외부의 Collection을 잘 이용하는 것으로, 여러가지 개발 시간을 단축시키고, 문제를 줄여줄 수 있기 때문에 Collection 이 중요.
  • 34. Redis 사용 처 ● Remote Data Store ○ A서버, B서버, C서버에서 데이터를 공유하고 싶을때 ● 한대에서만 필요한다면, 전역 변수를 쓰면 되지 않을까? ○ Redis 자체가 Atomic을 보장해준다.(싱글 스레드라…) ● 주로 많이 쓰는 곳들 ○ 인증 토큰 등을 저장(Strings 또는 hash) ○ Ranking 보드로 사용(Sorted Set) ○ 유저 API Limit ○ 잡 큐(list)
  • 36. Redis Collections ● Strings ● List ● Set ● Sorted Set ● Hash
  • 38. Strings - 단일 Key ● 기본 사용법 ○ Set <key> <value> ○ Get <key> ● Set token:1234567 abcdefghijklmn ● Get token:1234567
  • 39. Strings - 멀티 Key ● 기본 사용법 ○ mset <key1> <value1> <key2> <value2> …… <keyN> <valueN> ○ mget <key1> <key2> …… <keyN> ● mset token:1234567 abcdefghijklmn email:1234567 charsyam@naver.com ● mget token:1234567 email:1234567
  • 40. Strings - 간단한 SQL을 대체한다면? ● Insert into users(name, email) values(‘charsyam’, ‘charsyam@naver.com’); ● Using Set ○ Set name:charsyam charsyam ○ Set email:charsyam charsyam@naver.com ● Using mset ○ Mset name:charsyam charsyam email:charsyam charsyam@naver.com
  • 41. List
  • 42. List : insert ● 기본 사용법 ○ Lpush <key> <A> ■ Key: (A) ○ Rpush <key> <B> ■ Key: (A, B) ○ Lpush <key> <C> ■ Key: (C, A, B) ○ Rpush <key> <D, A> ■ Key: (C, A, B, D, A)
  • 43. List : pop ● 기본 사용법 ○ Key: (C, A, B, D, A) ○ LPOP <key> ■ Pop C, Key: (A, B, D, A) ○ RPOP <key> ■ Pop A, Key: (A, B, D) ○ RPOP <key> ■ Pop D, Key: (A, B)
  • 44. List : lpop, blpop, rpop, brpop ● 기본 사용법 ○ Key: () ○ LPOP <key> ■ No Data ○ BLPOP <key> ■ 누가 데이터를 Push 하기 전까지 대기
  • 45. Set
  • 46. Set : 데이터가 있는지 없는지만 체크하는 용도 ● 기본 사용법 ○ SADD <Key> <Value> ■ Value가 이미 Key에 있으면 추가되지 않는다. ○ SMEMBERS <Key> ■ 모든 Value를 돌려좀 ○ SISMEMBER <key> <value> ■ value가 존재하면 1, 없으면 0 ● 특정 유저를 Follow 하는 목록을 저장해둔다면
  • 48. Sorted Sets : 랭킹에 따라서 순서가 바뀌길 바란다면 ● 기본 사용법 ○ ZADD <Key> <Score> <Value> ■ Value가 이미 Key에 있으면 해당 Score로 변경된다. ○ ZRANGE <Key> <StartIndex> <EndIndex> ■ 해당 Index 범위 값을 모두 돌려줌 ■ Zrange testkey 0 -1 ● 모든 범위를 가져옴. ● 유저 랭킹 보드로 사용할 수 있음. ● Sorted sets의 score 는 double 타입이기 때문에, 값이 정확하지 않을 수 있다. ○ 컴퓨터에서는 실수가 표현할 수 없는 정수값들이 존재.
  • 49. Sorted Sets - 정렬이 필요한 값이 필요하다면? ● select * from rank order by score limit 50, 20; ○ zrange rank 50 70 ● Select * from rank order by score desc limit 50, 20; ○ Zrevrange rank 50 70
  • 50. Sorted Sets - Score 기준으로 뽑고 싶다면? ● select * from rank where score >= 70 and score < 100; ○ zrangebyscore rank 70 100 ● Select * from rank where score > 70; ○ Zrangebyscore rank (70 +inf
  • 51. Hash
  • 52. Hash: Key 밑에 sub key가 존재 ● 기본 사용법 ○ Hmset <key> <subkey1> <value1> <subkey2> <value2> ○ Hgetall <key> ■ 해당 key의 모든 subkey와 value를 가져옴 ○ Hget <key> <subkey> ○ Hmget <key> <subkey1> <subkey2> …… <subkeyN>
  • 53. Hash - 간단한 SQL을 대체한다면? ● Insert into users(name, email) values(‘charsyam’, ‘charsyam@naver.com’); ● hmset charsyam name charsyam email charsyam@naver.com
  • 55. Collection 주의 사항 ● 하나의 컬렉션에 너무 많은 아이템을 담으면 좋지 않음 ○ 10000개 이하 몇천개 수준으로 유지하는게 좋음. ● Expire는 Collection의 item 개별로 걸리지 않고 전체 Collection에 대해서만 걸림 ○ 즉 해당 10000개의 아이템을 가진 Collection에 expire가 걸려있다면 그 시간 후에 10000개의 아이템이 모두 삭제.
  • 57. Redis 운영 ● 메모리 관리를 잘하자. ● O(N) 관련 명령어는 주의하자. ● Replication ● 권장 설정 Tip
  • 59. 메모리 관리 ● Redis 는 In-Memory Data Store. ● Physical Memory 이상을 사용하면 문제가 발생 ○ Swap 이 있다면 Swap 사용으로 해당 메모리 Page 접근시 마다 늦어짐. ○ Swap이 없다면? ● Maxmemory를 설정하더라도 이보다 더 사용할 가능성이 큼. ● RSS 값을 모니터링 해야함.
  • 60. 메모리 관리 ● 많은 업체가 현재 메모리를 사용해서 Swap을 쓰고 있다는 것을 모를때가 많음(T.T)
  • 61. 메모리 관리 ● 큰 메모리를 사용하는 instance 하나보다는 적은 메모리를 사용하는 instance 여러개가 안전함. ● CPU 4 Core, 32GB Memory 24 GB Instance 8 GB Instance 8 GB Instance 8 GB Instance
  • 62. 메모리 관리 ● Redis는 메모리 파편화가 발생할 수 있음. 4.x 대 부터 메모리 파현화를 줄이도록 jemlloc에 힌트를 주는 기능이 들어갔으나, jemalloc 버전에 따라서 다르게 동작할 수 있음. ● 3.x대 버전의 경우 ○ 실제 used memory는 2GB로 보고가 되지만 11GB의 RSS를 사용하는 경우가 자주 발생 ● 다양한 사이즈를 가지는 데이터 보다는 유사한 크기의 데이터를 가지는 경우가 유리.
  • 63. 메모리가 부족할 때는? ● Cache is Cash!!! ○ 좀 더 메모리 많은 장비로 Migration. ○ 메모리가 빡빡하면 Migration 중에 문제가 발생할수도… ● 있는 데이터 줄이기. ○ 데이터를 일정 수준에서만 사용하도록 특정 데이터를 줄임. ○ 다만 이미 Swap을 사용중이라면, 프로세스를 재시작 해야함.
  • 64. 메모리를 줄이기 위한 설정 ● 기본적으로 Collection 들은 다음과 같은 자료구조를 사용 ○ Hash -> HashTable을 하나 더 사용 ○ Sorted Set -> Skiplist와 HashTable을 이용. ○ Set -> HashTable 사용 ○ 해당 자료구조들은 메모리를 많이 사용함. ● Ziplist 를 이용하자.
  • 65. Ziplist 구조 ● In-Memory 특성 상, 적은 개수라면 선형 탐색을 하더라도 빠르다. ● List, hash, sorted set 등을 ziplist로 대체해서 처리를 하는 설정이 존재 ○ hash-max-ziplist-entries, hash-max-ziplist-value ○ list-max-ziplist-size, list-max-ziplist-value ○ zset-max-ziplist-entries, zset-max-ziplist-value zlbytes zltail zllen entry entry ... entry zlend
  • 66. O(N) 관련 명령어는 주의하자.
  • 67. O(N) 관련 명령어는 주의하자. ● Redis 는 Single Threaded. ○ 그러면 Redis가 동시에 여러 개의 명령을 처리할 수 있을까? ○ 참고로 단순한 get/set의 경우, 초당 10만 TPS 이상 가능(CPU속도에 영향을 받습니다.)
  • 68. Redis is Single Threaded. processInputBuffer packet processCommand packet packetpacket Packet 으로 하나의 Command가 완성되면 processCommand 에서 실제로 실행됨
  • 69. Single Threaded 의 의미 ● Redis 는 Single Threaded. ○ 그러면 Redis가 동시에 여러 개의 명령을 처리할 수 있을까? ○ 참고로 단순한 get/set의 경우, 초당 10만 TPS 이상 가능(물리 서버기준, CPU속도에 영향을 받습니다.)
  • 70. Single Threaded 의 의미 ● 한번에 하나의 명령만 수행 가능 ○ 그럼 긴 시간이 필요한 명령을 수행하면?
  • 72. 대표적인 O(N) 명령들 ● KEYS ● FLUSHALL, FLUSHDB ● Delete Collections ● Get All Collections
  • 73. 대표적인 실수 사례 ● Key가 백만개 이상인데 확인을 위해 KEYS 명령을 사용하는 경우 ○ 모니터링 스크립트가 일초에 한번씩 keys를 호출하는 경우도... ● 아이템이 몇만개 든 hash, sorted set, set에서 모든 데이터를 가져오는 경우 ● 예전의 Spring security oauth RedisTokenStore
  • 74. KEYS 는 어떻게 대체할 것인가? ● scan 명령을 사용하는 것으로 하나의 긴 명령을 짧은 여러번의 명령으로 바꿀 수 있다. redis 127.0.0.1:6379> scan 0 1) "17" 2) 1) "key:12" 2) "key:8" 3) "key:4" redis 127.0.0.1:6379> scan 17 1) "0" 2) 1) "key:5" 2) "key:18" 3) "key:0" 7) "key:6" 8) "key:9" 9) "key:11"
  • 75. Collection의 모든 item을 가져와야 할 때? ● Collection의 일부만 가져오거나… ○ Sorted Set ● 큰 Collection을 작은 여러개의 Collection으로 나눠서 저장 ○ Userranks -> Userrank1, Userrank2, Userrank3 ○ 하나당 몇천개 안쪽으로 저장하는게 좋음.
  • 76. Spring security oauth RedisTokenStore 이슈 ● Access Token의 저장을 List(O(N)) 자료구조를 통해서 이루어짐. ○ 검색, 삭제시에 모든 item을 매번 찾아봐야 함. ■ 100만개 쯤 되면 전체 성능에 영향을 줌. ○ 현재는 Set(O(1))을 이용해서 검색, 삭제를 하도록 수정되어있음.
  • 77. Spring security oauth RedisTokenStore 이슈 ● https://charsyam.wordpress.com/2018/05/11/입-개발-spring-security-oauth의-redistokenstore의-사용은-서비스에- 적합하지-않/
  • 79. Redis Replication ● Async Replication ○ Replication Lag 이 발생할 수 있다. ● “Replicaof’(>= 5.0.0) or ‘slaveof’ 명령으로 설정 가능 ○ Replicaof hostname port ● DBMS로 보면 statement replication가 유사
  • 80. Redis Replication ● Replication 설정 과정 ○ Secondary에 replicaof or slaveof 명령을 전달 ○ Secondary는 Primary에 sync 명령 전달 ○ Primary는 현재 메모리 상태를 저장하기 위해 ■ Fork ○ Fork 한 프로세서는 현재 메모리 정보를 disk에 dump ○ 해당 정보를 secondary 에 전달 ○ Fork 이후의 데이터를 secondary에 계속 전달
  • 81. Redis Replication 시 주의할 점 ● Replication 과정에서 fork 가 발생하므로 메모리 부족이 발생할 수 있다. ● Redis-cli --rdb 명령은 현재 상태의 메모리 스냅샷을 가져오므로 같은 문제를 발생시킴 ● AWS나 클라우드의 Redis는 좀 다르게 구현되어서 좀더 해당 부분이 안정적.
  • 82. Redis Replication 시 주의할 점 ● 많은 대수의 Redis 서버가 Replica를 두고 있다면 ○ 네트웍 이슈나, 사람의 작업으로 동시에 replication이 재시도 되도록 하면 문제가 발생할 수 있음. ○ ex) 같은 네트웍안에서 30GB를 쓰는 Redis Master 100대 정도가 리플리케이션을 동시에 재시작하면 어떤 일이 벌어질 수 있을까?
  • 84. redis.conf 권장 설정 Tip ● Maxclient 설정 50000 ● RDB/AOF 설정 off ● 특정 commands disable ○ Keys ○ AWS의 ElasticCache는 이미 하고 있음. ● 전체 장애의 90% 이상이 KEYS와 SAVE 설정을 사용해서 발생. ● 적절한 ziplist 설정
  • 86. Redis 데이터 분산 ● 데이터의 특성에 따라서 선택할 수 있는 방법이 달라진다. ○ Cache 일때는 우아한 Redis(정말?) ○ Persistent 해야하면 안 우아한 Redis!!! ■ Open the hellgate!!!
  • 88. 데이터 분산 방법 ● Application ○ Consistent Hashing ■ twemproxy 를 사용하는 방법으로 쉽게 사용 가능 ○ Sharding ● Redis Cluster
  • 90. WHY?
  • 91. There was data In the beginning.
  • 93. How do you distribute data pairly into 3 servers? Considering the future.
  • 95. 1 2 3 4 5 6 7 8 9 Modular
  • 96. If you add one server, or remove one server What happened?
  • 97. 1 2 3 4 5 6 Add one server for Sequence 7 8 9
  • 98. Add one server for Modular 1 2 3 4 5 6 7 8 9
  • 99. How do you redistribute these data?
  • 100. Redistribute by Modular 1 2 3 4 5 6 7 8 9
  • 101. Most of data is redistributed!
  • 103. What is a good way to reduce redistribution?
  • 105. Consistent Hashing redistribute only N/K data N = data size K = servers
  • 108. If you use The same hash function? The result is always the same.
  • 109. hash(“abc”) = 1 hash(“abc1”) = 2 hash(“abc”) = 1
  • 110. You have 3 servers. 10.0.1.1 10.0.1.2 10.0.1.3
  • 111. There is a hash function. y = hash(x)
  • 112. You hash 3 servers hash(“10.0.1.1”) = 100 hash(“10.0.1.2”) = 400 hash(“10.0.1.3”) = 700 Just Giving server address as key
  • 113. Just define a rule. We will store a key in hash(key) is higher and the nearest one.
  • 114. hash(key) Hash value hash(“10.0.1.1”) 100 hash(“10.0.1.2”) 400 hash(“10.0.1.3”) 700
  • 115. There is key “redis” hash(“redis”) = 200 Where we store it?
  • 116. hash(key) Hash value hash(“10.0.1.1”) 100 hash(“redis”) 200 in hash(“10.0.1.2”) hash(“10.0.1.2”) 400 hash(“10.0.1.3”) 700
  • 117. There is key “charsyam” hash(“charsyam”) = 450 Where we store it?
  • 118. hash(key) Hash value hash(“10.0.1.1”) 100 hash(“redis”) 200 in hash(“10.0.1.2”) hash(“10.0.1.2”) 400 hash(“charsyam”) 450 in hash(“10.0.1.3”) hash(“10.0.1.3”) 700
  • 119. There is key “udemy” hash(“udemy”) = 50 Where we store it?
  • 120. hash(key) Hash value hash(“udemy”) 50 in hash(“10.0.1.1”) hash(“10.0.1.1”) 100 hash(“redis”) 200 in hash(“10.0.1.2”) hash(“10.0.1.2”) 400 hash(“charsyam”) 450 in hash(“10.0.1.3”) hash(“10.0.1.3”) 700
  • 121. There is key “web” hash(“web”) = 1000 Where we store it?
  • 122. There is no server has higher hash value 1000. Where we can store it?
  • 123. Think it is Circle
  • 124. hash(key) Hash value hash(“udemy”) 50 in hash(“10.0.1.1”) hash(“10.0.1.1”) 100 hash(“redis”) 200 in hash(“10.0.1.2”) hash(“10.0.1.2”) 400 hash(“charsyam”) 450 in hash(“10.0.1.3”) hash(“10.0.1.3”) 700 hash(“web”) 1000 in hash(“10.0.1.1”)
  • 125. Key “web” is stored in First Server.
  • 126. If we add new server It is “10.0.1.4”. And hash(“10.0.1.4”) = 500
  • 127. hash(key) Hash value hash(“udemy”) 50 in hash(“10.0.1.1”) hash(“10.0.1.1”) 100 hash(“redis”) 200 in hash(“10.0.1.2”) hash(“10.0.1.2”) 400 DELETED hash(“charsyam”) 450 hash(“10.0.1.4”) 500 hash(“10.0.1.3”) 700 hash(“web”) 1000 in hash(“10.0.1.1”)
  • 128. After adding “10.0.1.4” Key “charsyam” is missing
  • 129. But other keys are never changed.
  • 130. You can still find key “udemy” in “10.0.1.1”
  • 131. There is key “charsyam” hash(“charsyam”) = 450 Where we store it?
  • 132. hash(key) Hash value hash(“udemy”) 50 in hash(“10.0.1.1”) hash(“10.0.1.1”) 100 hash(“redis”) 200 in hash(“10.0.1.2”) hash(“10.0.1.2”) 400 hash(“charsyam”) 450 in hash(“10.0.1.4”) hash(“10.0.1.4”) 500 hash(“10.0.1.3”) 700 hash(“web”) 1000 in hash(“10.0.1.1”)
  • 143. 서버 주소를 해싱하는 것보다 Nickname으로 해싱 하는 것이 더 변동이 적음
  • 146. 하나의 데이터를 모든 서버에서 찾아야 하면?
  • 148. Range ● 그냥 특정 Range를 정의하고 해당 Range에 속하면 거기에 저장. ○ Key 500 은 어디에 저장되어야 할까? 1~1000 1001~2000 2001~3000
  • 149. Range ● 특정 Range 서버에만 부하가 몰릴 가능성이 높다. ○ 활동량이 많은 유저가 많은 서버는? ■ 이벤트 때문에 가입한 유저들.
  • 150. Modular ● N % K 로 서버의 데이터를 결정 ● Range 보다 데이터를 균등하게 분배할 가능성이 높다. 1 3 5 7 2 4 6 8
  • 151. Modular ● 서버 한대가 추가될 때 재분배 양이 많아진다. 1 4 7 2 5 8 3 6
  • 152. Indexed ● 해당 Key가 어디에 저장되어야 할 관리 서버가 따로 존재 1000 10001 1 200 Index Server 2 3 1. Where is 2? 2. 2 is on Server 3 client
  • 154. Redis Cluster ● Hash 기반으로 Slot 16384 로 구분 ○ Hash 알고리즘은 CRC16을 사용 ○ Slot = crc16(key) % 16384 ○ Key가 Key{hashkey} 패턴이면 실제 crc16에 hashkey가 사용된다. ○ 특정 Redis 서버는 이 slot range를 가지고 있고, 데이터 migration은 이 slot 단위의 데이터를 다른 서버로 전달하게 된다.(migrateCommand 이용)
  • 155. Redis Cluster Primary #1 Primary #2 Primary #3 Secondary #1 Secondary #2 Secondary #3 Client
  • 156. Redis Cluster Primary #1 Primary #2 Primary #3 Secondary #1 Primary #2 Secondary #3 Client
  • 157. Redis Cluster Primary #1 Primary #2 Primary #3 Secondary #1 Secondary #2 Secondary #3 Client Slot: 0~5555 Slot: 5556~11000 Slot: 11001~16383 Set Slot0_key abc
  • 158. Redis Cluster Primary #1 Primary #2 Primary #3 Secondary #1 Secondary #2 Secondary #3 Client Slot: 0~5555 Slot: 5556~11000 Slot: 11001~16383 +OK
  • 159. Redis Cluster Primary #1 Primary #2 Primary #3 Secondary #1 Secondary #2 Secondary #3 Client Slot: 0~5555 Slot: 5556~11000 Slot: 11001~16383 Set Slot5506_key abc
  • 160. Redis Cluster Primary #1 Primary #2 Primary #3 Secondary #1 Secondary #2 Secondary #3 Client Slot: 0~5555 Slot: 5556~11000 Slot: 11001~16383 -MOVED Primary #2
  • 161. Redis Cluster의 장점/단점 ● 장점 ○ 자체적인 Primary, Secondary Failover. ○ Slot 단위의 데이터 관리. ● 단점 ○ 메모리 사용량이 더 많음 ○ Migration 자체는 관리자가 시점을 결정해야 함. ○ Library 구현이 필요함.
  • 163. Redis Failover ● Coordinator 기반 Failover ● VIP/DNS 기반 Failover ● Redis Cluster 의 사용
  • 164. Coordinator 기반 ● Zookeeper, etcd, consul 등의 Coordinator 사용 API Server Redis #1 : P Redis #2 : S Coordinator: current Redis is Redis #1 Health Checker
  • 165. Coordinator 기반 API Server Redis #1 : P Redis #2 : S Coordinator: current Redis is Redis #1 Health Checker
  • 166. Coordinator 기반 API Server Redis #1 : P Redis #2 : P Coordinator: current Redis is Redis #1 Health Checker Health Checker는 Redis #2를 Primary 로 승격시킨다.
  • 167. Coordinator 기반 API Server Redis #1 : P Redis #2 : P Coordinator: current Redis is Redis #2 Health Checker Health Checker는 Redis #2를 Primary 로 승격시킨다. Health Checker는 Coordinator에 current Redis가 Redis #2라고 업데이트 한다.
  • 168. Coordinator 기반 API Server Redis #1 : P Redis #2 : P Coordinator: current Redis is Redis #2 Health Checker Health Checker는 Redis #2를 Primary 로 승격시킨다. Health Checker는 Coordinator에 current Redis가 Redis #2라고 업데이트 한다. Coordinator는 API Server에 current Redis 가 변경되었다고 알려준다.
  • 169. Coordinator 기반 ● Coordinator 기반으로 설정을 관리한다면 동일한 방식으로 관리가 가능. ● 해당 기능을 이용하도록 개발이 필요하다.
  • 170. VIP 기반 API Server Redis #1 : P Redis #2 : S Health Checker VIP: 10.0.1.1. API Server는 10.0.1.1로만 접속
  • 171. VIP 기반 API Server Redis #1 : P Redis #2 : S Health Checker VIP: 10.0.1.1. API Server는 10.0.1.1로만 접속
  • 172. VIP 기반 API Server Redis #1 : P Redis #2 : P Health Checker VIP: 10.0.1.1. API Server는 10.0.1.1로만 접속 Health Checker는 Redis #2를 Primary 로 승격시킨다.
  • 173. VIP 기반 API Server Redis #1 : P Redis #2 : P Health Checker VIP: 10.0.1.1. API Server는 10.0.1.1로만 접속 Health Checker는 Redis #2를 Primary 로 승격시킨다. Health Checker는 VIP 10.0.1.1 을 Redis #2 로 할당한다.
  • 174. VIP 기반 API Server Redis #1 : P Redis #2 : P Health Checker VIP: 10.0.1.1. API Server는 10.0.1.1로만 접속 Health Checker는 Redis #2를 Primary 로 승격시킨다. Health Checker는 VIP 10.0.1.1 을 Redis #2 로 할당한다. Health Checker는 Redis #1에 있던 기존 연결을 모두 끊어준다.(클라이언트의 재접속 유도)
  • 175. DNS 기반 API Server Redis #1 : P Redis #2 : S Health Checker DNS: redis-primary.svc.io API Server는 redis-primary.svc.io로만 접속
  • 176. DNS 기반 API Server Redis #1 : P Redis #2 : S Health Checker DNS: redis-primary.svc.io API Server는 redis-primary.svc.io로만 접속
  • 177. DNS 기반 API Server Redis #1 : P Redis #2 : P Health Checker DNS: redis-primary.svc.io API Server는 redis-primary.svc.io로만 접속 Health Checker는 Redis #2를 Primary 로 승격시킨다.
  • 178. DNS 기반 API Server Redis #1 : P Redis #2 : P Health Checker DNS: redis-primary.svc.io API Server는 redis-primary.svc.io로만 접속 Health Checker는 Redis #2를 Primary 로 승격시킨다.
  • 179. DNS 기반 API Server Redis #1 : P Redis #2 : P Health Checker DNS: redis-primary.svc.io API Server는 redis-primary.svc.io로만 접속 Health Checker는 Redis #2를 Primary 로 승격시킨다. Health Checker는 DNS: redis-primary.svc.io 을 Redis #2 로 할당한다.
  • 180. DNS 기반 API Server Redis #1 : P Redis #2 : P Health Checker DNS: redis-primary.svc.io API Server는 redis-primary.svc.io로만 접속 Health Checker는 Redis #2를 Primary 로 승격시킨다. Health Checker는 DNS: redis-primary.svc.io 을 Redis #2 로 할당한다. Health Checker는 Redis #1에 있던 기존 연결을 모두 끊어준다.(클라이언트의 재접속 유도)
  • 181. VIP/DNS 기반 ● 클라이언트에 추가적인 구현이 필요없다. ● VIP 기반은 외부로 서비스를 제공해야 하는 서비스 업자에 유리 (예를 들어 클라우드 업체) ● DNS 기반은 DNS Cache TTL을 관리해야 함. ○ 사용하는 언어별 DNS 캐싱 정책을 잘 알아야 함 ○ 툴에 따라서 한번 가져온 DNS 정보를 다시 호출 하지 않는 경우도 존재
  • 183. Monitoring Factor ● Redis Info를 통한 정보 ○ RSS ○ Used Memory ○ Connection 수 ○ 초당 처리 요청 수 ● System ○ CPU ○ Disk ○ Network rx/tx
  • 184. CPU가 100%를 칠 경우 ● 처리량이 매우 많다면? ○ 좀 더 CPU 성능이 좋은 서버로 이전 ○ 실제 CPU 성능에 영향을 받음 ■ 그러나 단순 get/set은 초당 10만 이상 처리가능 ● O(N) 계열의 특정 명령이 많은 경우. ○ Monitor 명령을 통해 특정 패턴을 파악하는 것이 필요 ○ Monitor 잘못쓰면 부하로 해당 서버에 더 큰 문제를 일으킬 수도 있음.(짧게 쓰는게 좋음)
  • 185. 결론
  • 186. 결론 ● 기본적으로 Redis는 매우 좋은 툴 ● 그러나 메모리를 빡빡하게 쓸 경우, 관리하기가 어려움 ○ 32기가 장비라면 24기가 이상 사용하면 장비 증설을 고려하는 것이 좋음. ○ Write가 Heavy 할 때는 migration도 매우 주의해야함. ● Client-output-buffer-limit 설정이 필요.
  • 187. Redis as Cache ● Cache 일 경우는 문제가 적게 발생 ○ Redis 가 문제가 있을 때 DB등의 부하가 어느정도 증가하는 지 확인 필요. ○ Consistent Hashing도 실제 부하를 아주 균등하게 나누지는 않음. Adaptive Consistent Hashing 을 이용해 볼 수도 있음.
  • 188. Redis as Persistent Store ● Persistent Store의 경우 ○ 무조건 Primary/Secondary 구조로 구성이 필요함 ○ 메모리를 절대로 빡빡하게 사용하면 안됨. ■ 정기적인 migration이 필요. ■ 가능하면 자동화 툴 을 만들어서 이용 ○ RDB/AOF가 필요하다면 Secondary에서만 구동