본문 바로가기
DBMS

NoSQL을 사용하는 이유와 Scale-out, Scale-up - 레디스(redis) vs 멤캐시드(memcached)

by developer's warehouse 2023. 11. 29.

웹 서비스에서 client가 증가하면 WAS와 DB 서버에 많은 부하를 가져옵니다. WAS에 부하가 몰려서 시스템 한계에 다다른 경우에는 WAS를 하나 더 복제하여 client를 분산해서 처리할 수 있습니다. WAS는 데이터를 가지지 않기 때문에 분산이 쉽습니다. 그러나 DBMS가 한계에 다다르면 골치아파집니다.

client 증가가 backend에 미치는 영향

client가 증가하면 먼저 제일 앞단에 있는 웹 서버와 WAS가 부하를 받습니다. 웹 서버와 WAS의 부하가 늘어나서 서비스 지연이 발생하거나 접속이 안되는 증상이 생기면 웹 서버와 WAS를 늘리면 됩니다. 웹 서버와 WAS는 앞 단의 로드 밸런서를 이용해서 서비스를 분산할 수 있어서 장비만 투자하면 쉽게 확장 가능합니다.

 

웹서비스 구조

 

mysql이나 postgresql의 경우에는 튜닝하는 것도 쉽지 않은데 튜닝을 해도 한계도 있습니다. mysql이나 postgresql 서버에서 답을 주지 않으면 tomcat과 같은 was에서 DB 연결을 끊어 버리고 서비스가 멈추게 되는 불상사가 발생합니다.

 

이때, 만약 failover같은 설정이 되어있어서 백업 mysql이나 postgresql로 was가 연결을 전환해도 원인이 dbms에 부하였기 때문에 금방 동일한 증상이 발생합니다.

 

client 증가는 두 가지 측면에서 부하를 줄 수 있습니다.

1. WAS

2. DBMS

WAS 장비에 부하가 심해서 서비스가 느려진 경우 WAS 서버를 늘려서 Load Balancer에 신규 노드를 추가해 주면 문제가 쉽게 해결됩니다. 하지만, DBMS 서버의 부하로인해서 서비스에 지장이 가는 경우에는 DBMS 서버의 하드웨어를 더 좋은 것으로 늘려야 합니다.

 

DBMS 서버의 처리량을 늘리는 방법

DBMS 서버의 부하로인해서 서비스에 지장이 생기는 경우에는 DBMS 서버를 더 좋은 장비로 교체해야합니다.

그런데, DBMS 서버의 하드웨어를 변경하려면 서비스 중단이 발생합니다.

또한, 실제 환경에서 DBMS 서버의 하드웨어를 더 좋은 장비로 scale-up(하드웨어 업그레이드)하는 경우 비용이 만만치 않습니다.

단일 서버의 성능을 증가시켜서 더 많은 요청을 처리하는 것을 Scale-up 이라고 합니. 반면 새로운 서버를 추가하여 서비스 처리율을 높이는 방법을 Scale-out이라고 합니다.

 

이 경우 서비스 중단을 최소화 하면서 DBMS 서버의 하드웨어를 업그레이드 하는 방법은 다음과 같습니다.

신규 하드웨어를 준비하고, 기존 DBMS에서 신규 장비로 데이터를 이전하고 이중화를 통해 복제를 진행한다.
부하가 줄어든 시점에 서비스를 잠시 지연시켜서 이중화 데이터가 복제될 시간을 주고 서비스를 신규 장비로 이전합니다.

 

DBMS 서버의 성능 문제로 서비스가 중단되면 하는 수 없이 기존 서버를 더 고가의 서버로 교체해야 하고, 할 때마다 데이터 마이그레이션과 이중화 작업 그리고 일시적이나마 서비스 중단이 필수적으로 발생합니다. client가 늘어나면 늘어날때마다 이런 작업을 반복해야할 수도 있습니다.

 

또한, 신규 서버로 이전 하고 남은 기존 서버는 사실상 쓸데 없는 장비가 되어버립니다.

마지막으로 가장 중요한 문제는 Scale-up은 한 서버의 장비를 업그레이드 하는 방법이기 때문에 한계가 명확히 존재합니다. 더 좋은 cpu가 없거나, 더 큰 용량의 메모리를 꽃을 수 없는 상황이 존재하기 때문입니다.

Scale-up vs Scale-out

앞에서 설명드린 내용 중 WAS의 경우 부하가 늘어나면 장비를 하나 더 추가한다고 설명드렸습니다. 이러한 형태로 서비스 부하를 감당하는 것이 Scale-out 입니다. 우리가 자주 사용하는 DBMS 제품들 중에는 장비를 늘려서 서비스 용량을 확장할 수 있는 형태가 늘어나고는 있지만, 아직까지는 활성화 되지 않은 것들이 많습니다. 오라클 RAC와 같은 비싼 제품을 구매해서 사용하면 Scale-out이 일정 부분 잘 됩니다. 하지만, RAC는 비용이 너무 크고, 구조상 Scale-out에 한계가 있습니다.

Scale-up과 Scale-out은 다음과 같이 비교될 수 있습니다.

  SCALE-UP (스케일업)
SCALE-OUT(스케일아웃)
 
scale-up 이미지
scale-out 이미지
구성 CPU 변경, 메모리 추가 등으로 하드웨어 장비의 성능을 높임
하나의 장비에서 처리하던 일을 여러 장비에 나눠서 처리함
확장성 수직 확장, 성능확장에 한계가 있음
수평 확장이며, 지속적 확장 가능
비용 성능 증가에 따른 비용 증가폭이 큼
비교적 저렴한 서버 사용으로 비용 부담이 적음
장애시 영향 한대의 서버에 부하가 집중되어 장애 영향도가 큼
읽기/쓰기가 여러 대의 서버에 분산처리
장애 시 전면장애의 가능성이 적음

데이터 캐시 사용

DBMS에 부하가 몰리는 경우 중간에 데이터를 위한 캐시를 두는 방법을 생각할 수 있습니다. 하지만, 이렇게 되면 티어가 더 늘어나고 관리 포인트가 늘어나서 관리자에게 부담이 생길 수 있습니다.

그래서, 데이터 캐시로 사용할 수 있는 것은 redis(레디스)와 memcached가 있습니다.

이러한 데이터 캐시 제품은 처음부터 확장성을 고려해서 만들어 졌습니다. 때문에 캐시로 사용하면서도 Scale-out을 할 수 있는 장점이 있습니다.

이 둘 간의 차이는 아래에 정리하였습니다.

기능 Memcached Redis
Sub-millisecond latency Yes Yes
Developer ease of use Yes Yes
Data partitioning Yes Yes
Support for a broad set of programming languages Yes Yes
Advanced data structures - Yes
Multithreaded architecture Yes -
Snapshots - Yes
Replication - Yes
Transactions - Yes
Pub/Sub - Yes
Lua scripting - Yes
Geospatial support - Yes

Sub-millisecond latency

Redis와 Memcached는 모두 밀리초 미만의 응답 시간을 지원합니다. 데이터를 인메모리에 저장함으로써 디스크 기반 데이터베이스보다 더 빠르게 데이터를 읽을 수 있습니다.

Developer ease of use

Redis와 Memcached는 모두 구문적으로 사용하기 쉬우며 애플리케이션에 통합하는 데 최소한의 코드만 필요합니다.

Data partitioning

Redis와 Memcached를 사용하면 여러 노드에 데이터를 분산할 수 있습니다. 따라서 수요가 증가할 때 더 많은 데이터를 더 잘 처리할 수 있도록 확장할 수 있습니다.

Support for a broad set of programming languages

Redis와 Memcached 모두 개발자가 사용할 수 있는 다양한 오픈 소스 클라이언트를 제공합니다. 지원되는 언어에는 Java, Python, PHP, C, C++, C#, JavaScript, Node.js, Ruby, Go 등이 있습니다.

Advanced data structures

Redis는 문자열 외에도 목록, 집합, 정렬된 집합, 해시, 비트 배열 및 하이퍼로그를 지원합니다. 애플리케이션은 이러한 고급 데이터 구조를 사용하여 다양한 사용 사례를 지원할 수 있습니다. 예를 들어, Redis 정렬 집합을 사용하여 플레이어 목록을 순위별로 정렬하는 게임 순위표를 쉽게 구현할 수 있습니다.

Multithreaded architecture

memcached는 멀티스레드이므로 여러 개의 처리 코어를 활용할 수 있습니다. 즉, 컴퓨팅 용량을 확장(scale-up)하여 더 많은 작업을 처리할 수 있습니다.

Snapshots

Redis를 사용하면 아카이브 또는 복구에 사용할 수 있는 특정 시점 스냅샷으로 데이터를 디스크에 보관할 수 있습니다.

Replication

Redis를 사용하면 Redis 기본 복제본을 여러 개 생성할 수 있습니다. 이를 통해 데이터베이스 읽기를 확장하고 고가용성 클러스터를 구축할 수 있습니다.

Transactions

Redis는 명령 그룹을 격리된 원자 연산(isolated and atomic operation)으로 실행할 수 있는 트랜잭션을 지원합니다.

Pub/Sub

Redis는 고성능 채팅방, 실시간 댓글 스트림, 소셜 미디어 피드 및 서버 상호 통신에 사용할 수 있는 패턴 매칭을 통해 Pub/Sub 메시징을 지원합니다.

Lua scripting

Redis를 사용하면 트랜잭션 Lua 스크립트를 실행할 수 있습니다. 스크립트를 사용하면 성능을 향상하고 애플리케이션을 간소화할 수 있습니다.

Geospatial support

Redis에는 대규모 실시간 위치 기반 정보 데이터 작업을 위해 특별히 설계된 명령이 있습니다. 두 요소(예: 사람 또는 장소) 사이의 거리 찾기, 한 지점에서 주어진 거리 내에 있는 모든 요소 찾기와 같은 작업을 수행할 수 있습니다.

 

NoSQL 사용을 통한 Scale-out

NoSQL의 특징은 초기부터 스케일 아웃을 고려하여 설계되었다는 것입니다. 따라서 데이터 양이나 요청량이 증가하더라도 동일하거나 유사한 사양의 새 하드웨어를 추가함으로써 쉽게 대응할 수 있습니다. 데이터나 요청이 적을 때는 일반적인 RDBMS를 사용해도 서비스에 문제가 없을 것입니다. 그러나 데이터 증가를 측정하기 어렵거나 서비스 요청량의 증가를 예측하기 어려운 환경에서는 NoSQL을 저장소로 채택하는 좋습니다.

 

멤캐시드와 레디스를 같은 캐시 캐시 시스템으로서 동등한 위치에서 비교하게 된것은 레디스가 멤캐시드와 동일한 기능을 제공하면서 영속성, 다양한 데이터 구조와 같은 부가적인 기능을 지원하기 때문입니다. 또한 특정한 조건에서는 멤캐시드에 비해서 더 나은 성능을 보여주기도 합니다. 이와 같은 이유로 레디스는 멤캐시드를 대체하는 솔루션으로 주목 받아왔습니다.

Redis는 스택오버플로우에서 가장 사랑받는 데이터베이스로 2017년 부터 2021년까지 5년동안 선정되었습니다.

 

레디스는 모든 데이터를 메모리에 저장하고 조회합니다. 즉, 인메모리 데이터베이스 솔루션입니다. 빠른 성능과 확장성은 레디스의 특징 중 하나이며 이 외에도 다른 인메모리 솔루션들과의 차이점 중 가장 특별한 점은 레디스의 '다양한 자료구조'를 제공한다는 점입니다. 다만, 레디스는 테이블 개념이 없습니다.

 

NoSQL로서 키-값 타입의 저장소인 레디스의 주요 정보 및 특징은 다음과 같습니다.

  1. snapshot을 통해 영속성을 지원하는 인메모리 데이터베이스입니다.
  2. Read-Only 성능 확장성을 위해서 서버 측(Server-side) 복제를 지원합니다.
  3. Write-Read 성능 확장성을 위한 클라이언트 측(Client-side) 샤딩을 지원합니다.
  4. ANSI C로 쓰여졌습니다. 그러므로, ANSI C 컴파일러가 동작하는 곳이면 어디든 설치 및 실행이 가능합니다.
  5. 레디스 클라리언트는 대부분의 언어로 포팅되어 있습니다. ( http://redis.io/clients )
  6. 많은 서비스에서 사용되고 있으며 성능적으로 검증되어있습니다.
  7. 문자열, 리스트, 해시, 셋, 정렬된 셋과 같은 다양한 데이터형을 지원합니다. 메모리 저장소임에도 불구하고 많은 데이터형을 지원하므로 다양한 기능을 구현할 수 있습니다.

레디스와 멤캐시드의 차이

- 멤캐시드는 본질적으로 고성능 분산 메모리 객체 캐싱 시스템이지만, 원래는 동적 웹 서비스의 DB 부하를 경감시키는 것이 목적이었습니다.

- 레디스는 오픈소스며, 키-값 저장소 입니다. 값으로 문자열, 리스트, 해시, 셋, 정렬된 셋을 포함할 수 있기 때문에 종종 데이터 구조 서버(data structure server)로 지칭된다.

 

NoSQL에 멤캐시드는 포함되어 있지 않다. NoSQL은 데이터베이스(데이터 저장소)를 지칭하기 때문에 멤캐시드는 NoSQL이 아닙니다. 레디스는 고성능 인메모리 키-값 저장소로서 다섯 가지 데이터형(문자열, 리스트, 해시, 셋, 정렬된 셋)을 지원합니다. 메모리 이외의 영구 저장소를 지원하므로 인스턴스의 재시작에 대한 cache warm up (캐시의 적중률을 높이기 위해서 미리 캐시 데이터를 생성하는 것)에 대한 고려가 필요하지 않습니다. 즉, MySql과 같은 DBMS 없이 사용할 수 있습니다.

읽기를 위한 서버측 복제를 지원하며 쓰기 성능 증대를 위한 클라이언트측 샤딩을 지원합니다.

 

참고: "이것이 레디스다" 책정리 내용 https://12bme.tistory.com/615

레디스의 데이터형 별 접근 예제

Redis는 키-값 쌍을 저장하는 데이터 구조 저장소로, 전통적인 관계형 데이터베이스에서 사용하는 테이블과 같은 개념이 없습니다.

Redis는 다양한 데이터 형을 지원하며, 각 데이터 형에 따라 데이터를 사용하는 방법이 다릅니다. 다음은 문자열, 리스트, 해시, 셋, 정렬된 셋을 사용하는 Java 예제입니다. 이 예제에서는 Jedis 라이브러리를 사용하며, 이를 사용하려면 먼저 의존성을 프로젝트에 추가해야 합니다.

import redis.clients.jedis.Jedis;

public class RedisExample {
    public static void main(String[] args) {
        // Redis 서버에 연결
        Jedis jedis = new Jedis("localhost");

        // 문자열 사용
        jedis.set("myKey", "Hello, Redis!");
        System.out.println("String value: " + jedis.get("myKey"));

        // 리스트 사용
        jedis.lpush("myList", "Redis");
        jedis.lpush("myList", "Hello,");
        System.out.println("List value: " + jedis.lrange("myList", 0, -1));

        // 해시 사용
        jedis.hset("myHash", "field1", "Hello,");
        jedis.hset("myHash", "field2", "Redis");
        System.out.println("Hash value: " + jedis.hgetAll("myHash"));

        // 셋 사용
        jedis.sadd("mySet", "Hello,");
        jedis.sadd("mySet", "Redis");
        System.out.println("Set value: " + jedis.smembers("mySet"));

        // 정렬된 셋 사용
        jedis.zadd("mySortedSet", 1, "Hello,");
        jedis.zadd("mySortedSet", 2, "Redis");
        System.out.println("Sorted set value: " + jedis.zrange("mySortedSet", 0, -1));
    }
}

이 코드는 로컬에서 실행 중인 Redis 서버에 연결하고, 각각의 데이터 형에 대해 데이터를 저장하고 검색합니다.

레디스(Redis)의 단점

Redis는 많은 장점을 가지고 있지만, 몇 가지 단점도 있습니다¹⁴:

1. 단일 마스터: Redis는 단일 마스터를 가지고 있으며, 이 마스터가 다운되면 전체 아키텍처가 붕괴할 수 있습니다.
2. 보안: Redis는 매우 기본적인 보안만 제공합니다.
3. 메모리 요구량: Redis는 데이터를 메모리에 저장하므로 많은 RAM이 필요합니다.
4. 쿼리 언어 부재: Redis는 데이터 구조 서버로, 쿼리 언어(오직 명령만 있음)와 관계 대수를 지원하지 않습니다. 즉, SQL을 사용하여 RDBMS에서처럼 ad-hoc 쿼리를 실행할 수 없습니다.
6. 단일 스레드: 단일 Redis 인스턴스는 확장성이 제한적입니다. 이는 Redis가 단일 스레드 모드에서 단일 CPU 코어에서만 실행되기 때문입니다. 확장성을 얻으려면 여러 Redis 인스턴스를 배포하고 시작해야 합니다.
https://naiveskill.com/web-stories/disadvantages-of-redis/
이러한 단점에도 불구하고, Redis는 매우 빠르며, 좋은 동시성 지원, 낮은 지연 시간, 프로토콜 파이프라이닝, 쉽게 구현할 수 있는 낙관적 동시 패턴, 좋은 사용성/복잡성 비율 등 많은 장점을 가지고 있습니다. 

레디스(Redis)의 오픈소스 라이선스

Redis는 오픈 소스 소프트웨어로, 3-Clause-BSD 라이선스에 따라 릴리스됩니다. 이 라이선스는 사용, 복사, 배포, 수정 등을 허용하며, 특정 조건을 충족해야 합니다.

 

  • 소스 코드의 재배포는 위의 저작권 고지사항, 이 목록의 조건 및 다음 면책 조항을 유지해야 합니다.
  • 이진 형식으로 재배포할 경우, 위의 저작권 고지사항, 이 목록의 조건 및 다음 면책 조항을 배포 문서 및/또는 기타 제공된 자료에 복제해야 합니다.
  • 저작권 소유자의 이름 또는 기여자의 이름을 이 소프트웨어에서 파생된 제품을 보증하거나 홍보하는 데 사용해서는 안 됩니다.


Redis Stack과 Redis Ltd.에서 생성한 모든 Redis 모듈(예: RediSearch, RedisJSON, RedisGraph, RedisTimeSeries, RedisBloom 등)은 Redis Source Available License v2 (RSALv2)와 SSPL에 따라 이중 라이선스가 적용됩니다.

 

RSALv2는 Redis Ltd.에서 만든 허용적이고 비저작권 라이선스로, 소프트웨어의 "사용, 복사, 배포, 제공, 파생 작업 준비"를 허용하며, 주요 제한 사항이 두 가지 있습니다.

소프트웨어를 상업화하거나 관리 서비스로 제공해서는 안 됩니다.
라이선스, 저작권 또는 기타 공지를 제거하거나 숨겨서는 안 됩니다.


RSALv2는 OSI에 의해 승인되지 않았으며, 이를 오픈 소스 라이선스라고 부르지 않습니다

레디스 라이선스

https://github.com/redis/redis

https://redis.com/legal/licenses/

facebook twitter kakaoTalk kakaostory naver band shareLink