상세 컨텐츠

본문 제목

Redis 개념 및 특징

Ops/Redis

by 크리두 2021. 11. 19. 17:58

본문

반응형
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등 대부분의 언어를 지원한다

 

REDIS(REmote Dictionary Server)는 메모리 기반의 “키-값” 구조 데이터 관리 시스템이며, 모든 데이터를 메모리에 저장하고 조회하기에 빠른 Read, Write 속도를 보장하는 비 관계형 데이터베이스이다.

레디스는 크게 5가지< String, Set, Sorted Set, Hash, List >의 데이터 형식을 지원한다.

Redis는 빠른 오픈 소스 인 메모리 키-값 데이터 구조 스토어이며, 다양한 인 메모리 데이터 구조 집합을 제공하므로 사용자 정의 애플리케이션을 손쉽게 생성할 수 있다.

그렇다면 레디스의 특징과 유사한 Memcahed와 비교하고 싶다.

Memcached의 기본적인 특징

  • 처리 속도가 빠르다.(데이터가 메모리에만 저장되므로 빠르다. 즉, 속도가 느린 Disk를 거치지 않는다.)
  • 데이터가 메모리에만 저장된다.(프로세스가 죽거나 장비가 Shutdown되면 데이터가 사라진다.)
  • 만료일을 지정하여 만료가 되면 자동으로 데이터가 사라진다.(Cache이기에)
  • 저장소 메모리 재사용( 만료가 되지 않았더라도 더 이상 데이터를 넣을 메모리가 없으면 LRU(Least recently used) 알고리즘에 의해 데이터가 사라진다.)

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

 

레디스(Redis) 특징

  • 영속성을 지원하는 인메모리 데이터 저장소.
  • 읽기 성능 증대를 위한 서버 측 복제를 지원한다.

(Redis가 실행중인 서버가 충돌하는 경우 장애 조치 처리와 함께 더 높은 읽기 성능을 지원하기 위해 슬레이브가 마스터에 연결하고 전체 데이터베이스의 초기 복사본을 받는 마스터 / 슬레이브 복제를 지원한다. 마스터에서 쓰기가 수행되면 슬레이브 데이터 세트를 실시간으로 업데이트하기 위해 연결된 모든 슬레이브로 전송된다.)

  • 쓰기 성능 증대를 위한 클라이언트 측 샤딩(Sharding)을 지원한다.

샤딩(Sharding)이란??? 파티셔닝(Partitionong)과 동일하다. 같은 테이블 스키마를 가진 데이터를 다수의 데이터베이스에 분산하여 저장하는 방법을 의미한다.

  • 문자열, 리스트, 해시, 셋, 정렬된 셋과 같은 다양한 데이터형을 지원한다.

레디스(Redis)의 장점

  • 리스트, 배열과 같은 데이터를 처리하는데 유용하다.

value 값으로 문자열, 리스트, Set, Sorted set, Hash 등 여러 데이터 형식을 지원하기에, 다양한 방식으로 데이터를 활용할 수 있다.

  • 리스트형 데이터 입력과 삭제가 MySQL에 비해서 10배정도 빠르다고 한다.

여러 프로세스에서 동시에 같은 key에 대한 갱신을 요청할 경우, Atomic 처리로 데이터 부정합 방지 Atomic처리 함수를 제공한다.(원자성을 잘 지킨다)

  • 메모리를 활용하면서 영속적인 데이터 보존

명령어로 명시적으로 삭제, expires를 설정하지 않으면 데이터가 삭제되지 않는다.

스냅샷(기억장치) 기능을 제공하여 메모리의 내용을 *.rdb 파일로 저장하여 해당 시점으로 복구할 수 있다.

  • Redis Server는 1개의 싱글 쓰레드로 수행되며, 따라서 서버 하나에 여러개의 서버를 띄우는 것이 가능하다.

Master — Slave 형식으로 구성이 가능함, 데이터 분실 위험을 없애주는 것이 바로 Master — Slave 방식이다.

 

Redis 운영

메모리 관리를 잘하자

  • Physical Memory 이상을 사용하면 문제가 발생
    - Swap이 있다면 Swap 사용으로 해당 메모리 Page 접근시 마다 늦어짐.
    • Swap이 없다면 OOM
    • Maxmemory를 설정하더라도 메모리 할당 구현체에 메모리 관리 의존, 따라서 레디스는 정확한 메모리 사용량을 알 수없어 이보다 더 사용할 가능성이 큼.
    • 큰 메모리의 instance 하나보다 적은 메모리 instance 여러개가 안전
      -레디스는 FORK를 하는데, copy on wirte기반이라 write가 헤비한 레디스는 최대 메모리 두배까지 쓸 수 있다.
    • 메모리 파편화가 발생할 수 있음.
    • 다양한 사이즈를 가지는 데이터보다는 유사한 크기의 데이터를 저장하는 경우가 유리

메모리가 부족할 때는?

  • 좀 더 메모리 많은 장비로 Migration -> 메모리가 빡빡하면 Migration중에 문제가 발생 할 수도 (60~70% 사용중이면 이전 고려)
  • 기본적으로 Collection 들은 다음과 같은 자료구조 사용
    - Hash -> HashTable을 하나 더 사용
    • Srted Set -> Skiplist와 Hash Table을 이용
    • Set -> HashTable 사용
  • 위 자료구조들은 메모리들을 생각보다 많이 사용함, 그래서 Ziplist를 활용하는 방법도 있다.
    • Ziplist는 선형으로 저장, In-Memory 특성 상, 적은 개수라면 선형탐색을 하더라도 빠르다.

O(N) 관련 명령어는 주의하자

  • Redis는 Single Thread라 하나의 요청이 병목되면 뒤에 요청들도 계속 기다려야한다.단순한 get/set의 경우 초당 10만 TPS 이상 가능

  • Packet 단위로 받아 하나의 Command가 완성되면 실행되는 구조.

대표적인 O(N) 명령 및 사례

  • KEYS, FLUSHALL, FLUSHDB, Delete COlLECTIONS, Get All Collections
  • 모니터링 스크립트가 일초에 한번씩 keys 호출..
  • 큰 컬렉션의 데이터를 다 가져오는 경우
  • Spring security oauth RedisTokenStore(최신 버전은 패치됨)
    - Access Token 저장을 List(O(N)) 자료구조를 통해서 이루어짐 -> 삭제시에 모든 item을 찾아봐야함, 최근에는 Set을 통해 가져오도록 패치됨
  • keys는 scan 명령어로 사용하는 것으로 하나의 긴명령을 짧은 여러 명령으로 변경 가능

Redis Replication

  • Async Replication -> Replication Lag이 발생 할 수 있다.
  • DBMS로 보면 statement replication과 유사 --> 쿼리가 직접 간다.

Replication 설정 과정

  • Secondary에 replicaof or slaveof 명령 전달
  • Secondary는 Primary에 sync 명령 전달
  • Primary는 현재 메모리 상태를 저장하기 위해 Fork요 과정에서 copy on wirte가 발생 할 수 있음
  • Fork 한 프로세서는 현재 메모리 정보를 disk에 dump (disk 대신 메모리에서 바로 줄 수도 있음)
  • Fork 이후의 데이터를 secondary에 계속 전달AWS나 클라우드의 Redis는 다르게 구현되어 있어서 좀 더 안정적일 수 있다.

redis.conf 권장설정

  • Maxclient 설정 50000
  • Maxclient 수만큼만 접속 가능
  • RDB/AOF 설정 off
  • 특정 commands disable
  • 전체 장애의 90% 이상이 KEYS와 SAVE 설정을 사용해서 발생save 설정은 1초안에 키가 ~~개 바뀌면 dump 해!라는 설정

Redis 데이터 분산

Consistent Hashing

  • 일반 모듈러 해싱은 서버가 장애/추가 될 때마다 여러 서버에서 걸쳐 데이터 리밸런싱이 일어난다.
  • Consistent Hashing은 자기 해시보다 크고 가장 근접한 해시를 가진 서버 찾아간다. 따라서 서버 장애/추가 될 때에 N분의 1만큼만 이동하게 된다.

Sharding

  • Range: 특정 Range를 정의하고 속하는 Range에 저장 --> 데이터가 일정 Range에 몰리거나 비어있을 수 있다.
  • Modular를 사용할 경우 하나씩 추가하면 데이터 리벨린싱이 빈번하게 발생함으로 *2만큼 늘려준다면, 규칙적으로 데이터들이 이동한다.
  • Indexed: 해당 key가 어디에 저장되어야 할 관리 서버가 따로 존재, 단 인덱스 서버가 죽으면 심각한 장애

Redis Cluster

  • Hash 기반으로 Slot 16384로 구분
  • slot = crc16(key) % 16384
  • Key가 Key{hashKey} 패턴이며 crc 16에 hash key가 적용된다. 따라서 key값 설정으로 보낼 서버를 정할 수도 있다.
  • Redis 서버는 slot range를 가지고 있기때문에 slot 단위로 데이터를 다른 서버로 전달하게 된다.
  • 자기 slot 외에 데이터가 들어오면 -Moved {서버} 에러를 보낸다. 라이브러리는 이 에러를 받고 해당하는 서버로 옮겨 줘야한다.

Redis Cluster 장단점

  • 장점
  • 자체적인 Primary, Secndary Failover.
  • Slot 단위의 데이터 관리
  • 단점
  • 메모리 사용량이 더 많음
  • Migration 자체는 관리자가 시점을 결정해야함
  • Library 구현이 필요함

Redis Failover

Redis Cluster

Coordinator 기반 Failover

  • Zookeeper, etcd 등의 코디네이터 사용
  • Coordinator 기반으로 설정을 관리한다면 동일한 방식으로 관리가 가능
  • 해당 기능을 이용하도록 개발이 필요

VIP(DNS) 기반

  • 서버가 죽으면 승격된 레디스에 죽은 서버의 vip를 할당해준다.
  • Health Checker는 죽은 서버의 연결을 모두 끊어 클라이언트의 재접속을 유도한다.
  • 클라이언트에 추가적인 구현이 필요없다
  • DNS 기반은 DNS Cache TTL을 관리해야한다.
  • 클라이언트가 DNS를 캐싱해버리면 접속이 안될 수 있다.
  • VIP 기반은 외부로 서비스를 제공해야하는 서비스 업자에 유리
  • DNS 변경은 VIP 변경보다 훨씬 간단하다.

Monitoring

  • Redis Info를 통한 정보
  • RSS : 피지컬 메모리를 얼마나 쓰고 있냐, OS가 보고 있는 지표
  • Used Memory: 레디스가 알고 있는 사용 메모리
  • Connection 수: 레디스는 싱글 스레드라 컨넥션을 계속 맺고 해제하면 성능이 급격하게 떨어질 수 있다.
  • 초당 처리 요청수
  • System
  • CPU: 초당 처리 요청수는 짧은 명령이라면 CPU에 영향을 받는다.
  • Disk
  • Network rt/tx: 스위치에서 너무 많은 데이터가 있으면 drop이 일어날 수 있어서 확인 필요
  • CPU가 100%를 칠 경우
  • 레디시는 싱글 스레드라 CPU 하나를 사용, 따라서 CPU 단일 성능을 높이는게 좋음
  • O(N) 계열의 특정 명령이 많은 경우
    • Monitor 명령을 통해 특정 패턴을 파악하는 것이 필요
    • Monitor 잘못쓰면 부하로 해당 서버에 더 큰 문제 발생 할 수 있음. 짧게 쓰는게 좋다Monitor는 명령어 패턴을 확인 할 수 있는 명령어

결론

Redis as Cache

  • 문제가 적게 발생
  • Redis가 문제가 있을 때 DB등의 부하가 어느정도 증가하는지 확인 필요
  • Consistent Hashing도 실제 부하를 아주 균등하게 나누지는 않음. Adaptive Consistent Hasing을 이용해 볼 수도 있음

Redis as persistance

  • 무조건 Primary/Secondary 구조로 구성이 필요
  • 메모리를 절대로 빡빡하게 사용하면 안됨
  • 정기적인 Migration이 필요
  • RDB/AOF가 필요하다면 Secondary에서만 구동
반응형

'Ops > Redis' 카테고리의 다른 글

Redis on K8S (operator) 설치  (0) 2023.03.16

관련글 더보기

댓글 영역