우아한레디스

noname2048·2021년 2월 27일
0

우아한 테크세미나: 우아한 Redis 를 보고

1 Redis 소개

1.1 만든사람

1명, 커미터 1명, 우와
redis 수정해서 쓰는 사람이 있을까? - 몇몇 회사들

1.2 지원하는 자료구조

string, set, sorted-set, hashes, list, geospatial

1.3 캐시

팩토리얼 예제

2 Redis의 사용

2.1 사용 방법

2.1.1 Look aside Cache

캐시를 확인하고 DB를 탐색하기

2.1.2 Write Back

수정이 빈번한 데이터는 메모리에 담아 뒀다가 저장은 주기마다 하기

2.2 Collection

2.2.1 Memcached 와의 차이

Collection 의 제공 유무, Memcached는 제공하지 않는다.

2.2.2 C와 Python의 차이

Python이 제공하는 라이브러리가 많다. 마찬가지로 memcached 와 비교했을때 redis 가 제공하는게 많다

2.2.3 랭킹서버의 구현

DB 유저 Score 저장후 order by 접근
개수가 많아지면 느려져요
In-memory 들어가야하는데
redis의 sorted set 을 쓰자

2.2.4 친구리스트의 구현

트랜젝션(T1) B추가
트랜젝션(T2) C추가
그런데... 결과는 AB, AC가 될 수 있다
T1과 T2가 복합적으로 일어나면 안된다.
Redis 는 Race Condition을 피할 수 있다

2.2.5 Collection 이 중요한건

개발시간 단축, 문제 감소

2.3 용도

2.3.1 공유용 데이터 서버

2.3.2 인증토큰

2.3.3 Ranking 보드

2.3.4 API limit

2.3.5 job queue (celery)

2.4 collections 자료구조

2.4.1 string

key:value, prfix, postfix

2.4.2 list

lpush, rpush, lpop, rpop

2.4.3 set

sadd, smembers (모든 멤버 반환), ismember(1, 0)

2.4.4 sorted set

* redis 에서 많이 쓰는 자료구조중 하나
zadd, zrange
유저 랭킹보드로 활용
score 는 double 형태 이므로, 근사값이 들어가므로, 다른값이 들어갈 수 있다.
* 특히 js 에서 엄청 큰 수의 long 형태나, 실수를 전달하는 과정에서 오류가 많으므로 스트링으로 넣을 것을 권장
zreverange, zrangebyscore

2.4.5 hash

2.5 제한사항

하나의 collection 에 대해서 만개 이하, 수천개 수준으로 유지하라
expire 에 대해 collection 전체로만 사용 할 수 있다, 그리고 다 지워진다.

3 Redis 운영

3.1 메모리 관리를 잘하자

메모리가 꽉차서 죽어버리면... 더 이상 우아하지 않다
메모리가 부족해서 swap 이 일어나면 (redis 를 쓸 이유가 없다 1ms:100ms)

3.1.1 maxmemory 옵션

jmalloc 보다 malloc 관련한 알고리즘을 잘 짤 수 없는 사람은 없지만, 그럼에도 불구하고 jmalloc으로 인하여 메모리 사이즈가 정확하게 계산되지 않는다.
Page는 4096 단위 - 메모리 파편화문제 (여러개의 작은 메모리를 할당했지만 최소 단위인 가상 Page를 여러개 받은 상태)

3.1.2 모니터링

swap 상황을 모르는 사람이 많다. 모니터링 하자

3.1.3 하드웨어 관리

하나의 큰 메모리 보다 작은 인스턴스 여러대가 안전하다.
이유? read 가 많으면 상관이 없는데 write가 많으면 메모리가 2배까지 늘어날 수 있다. (write하기 위해 잠깐 복사하므로)
관리하기는 귀찮지만...

3.1.4 보고된 케이스

4.x 전까지 2GB 사용중인걸로 알았으나 11GB RSS 사용중임을 확인

3.1.5 해결책

메모리가 빡빡하면 migration 중에 문제가 생김
더 좋은 장비로 옮기기 (70%~80%), 빠르게 움직이기
있는 데이터 줄이기, 프로세스 재시작

3.1.5.1 메모리 줄이기 위한 설정

Hash는 HashTable 이용
sorted set 은 skiplist 와 hashtable 이용
set은 hashtable 이용
해당 자료구조는 메모리 사용
ziplist 를 쓰자

3.1.5.2 ziplist

in memory 구조에서는 적은 개수면 선형탐색해도 빠름. 100개 정도 (메모리 사용량은 20~30%)
몇 개까지는 ziplist를 쓰겠다.
넘어가면 원래 자료구조를 쓰겠다.

3.2 O(n) 명령어는 주의하자

3.2.1 Redis는 Single Threaded 이다

레디스는 한번에 한개를 처리한다.
단순한 get/set 은 초당 10만개 처리 가능
긴 시간을 필요한 명령을 쓰면 망한다!!!!

대표적인 3.2.2 O(N) 명령어

keys
flushall
flushdb
delete collections
get all collections
몇 백개는 상관이 없는데 1~2초간 아무것도 못하게 된다.

3.2.2.1 보고된 사례들

키가 백만개 이상인데 keys 명령을 사용하는 경우 ( 모니터링 스크립트가 일초에 한번씩 keys를 호출하는 경우)
spring security oauth redis tokenstore 이슈

3.2.3 keys의 대체

scan 을 쓰자 (나눠서 가져온다)

3.2.4 all get의 대체

collection 일부만 가져오거나, 처음부터 여러개로 나누어서 저장한다

4 redis Replication

4.1 replication 과정

비동기적으로 슬레이브에 명령 전달

4.2 만악의 근원 fork

4.2.1 fork하다가 메모리 터져서 데이터가 날라가면

못 고쳐요 (쉐엣)

4.2.2 AWS와 클라우드의 fork는 조금 다르게 구성되어있다.

문제가 조금 덜 한편

4.2.3 bandwith 문제

여러대의 replica 를 동시에 만들면 bandwith 초과로 네트워크 연결이 끊어질 수 있음

4.3 권장 설정

maxclient 50000 (디폴트 보다 높여주자)
RDB/AOF 설정은 끄자
특정 명령어를 끄자 (keys, save): 장애의 90% 을 담당, 특히 save 에서 1분에 만개가 업데이트 되면 dump 해 같은 명령어는 -> 실제 서비스에서 사실상 쓰지 말자
레플리카의 경우 RDB 킬수 있는데, 마스터는 절대 키지 말자
ziplist 를 발생

4.4 데이터분산

4.4.1 cache vs persistance

4.4.2 consistent hashing

rebalance 시 50% 이상의 데이터가 움직이게 되면 - 장애에 취약해진다
그러면 consist hashing은 무슨 개념인가?
장애가 일어나도 리밸런스 대상이 많이 일어나지 않도록 하는 개념

4.4.2.1 모듈러
4.4.2.2 인덱스서버

5 Redis Cluster

5.1 기본 개념

CRC16(key) 16384 가 최대
slot : 0 ~ 5555
slot : 5556 ~ 11000
slot : 11000 ~ 16384
죽으면 master 로 자동 승격

5.1 Redis Failover

5.1.1 코디네이터

다른 많은걸 동일한 방식으로 가동/개발필요

5.1.2 VIP/DNS

가상아이피 사용, 클러스트에 추가 구현 불필요, DNS TTL 관리

5.1.3 클러스터

죽으면 승격

6 Monitoring Factor

RSS
used memory
cpu
connection 수
초당 처리 요청 수

7 persistent store

무조건 pri/second 구조 필요
메모리 넉넉하게
migration 정기적으로
자동화 툴쓰세요
RDB/AOF 는 secondary 에서만 사용

profile
설명을 쉽게 잘하는 개발자를 꿈꾸는 웹 개발 주니어

0개의 댓글