1P by neo 1달전 | favorite | 댓글 1개

데이터베이스 없이 고가용성 웹 서비스 구축하기

탐색

  • 새로운 스타트업의 경우, 보통 Rails, Django, Node와 같은 웹 프레임워크와 MySQL, PostgreSQL, MongoDB와 같은 데이터베이스를 선택함
  • 하지만 웹 서비스와 데이터베이스 인스턴스를 하나로 합칠 수 있다면? 모든 데이터를 RAM에 저장하는 방식으로 접근 가능
  • RAM을 데이터베이스로 사용하면 SQL 쿼리로 데이터를 직렬화할 필요가 없어짐
  • 인덱스는 메모리 내 해시 테이블을 사용하여 구현 가능
  • 백그라운드 작업은 큰 프로세스 내의 스레드로 처리 가능
  • 프로세스가 충돌할 경우, 주기적으로 RAM의 스냅샷을 찍고 변경 사항을 디스크에 기록하여 복구 가능

확장

  • 고가용성을 요구하는 고객이 생기면, Raft 합의 알고리즘을 사용하여 서버를 복제함
  • 리더 서버가 다운되면 새로운 리더가 선출되어 요청을 처리함
  • 이 방식으로 서버를 재시작하지 않고도 롤링 배포 가능

추출

  • 큰 고객이 많아지면 샤딩을 통해 웹 서비스를 분할하여 처리 가능
  • 각 엔터프라이즈 고객에게 전용 클러스터를 제공함
  • 주요 병목 현상은 커밋 스레드의 성능이 될 수 있음

우리의 스택

  • Common Lisp 사용: 다중 스레드 지원이 뛰어나고, 코드 핫 리로딩에 적합함
  • bknr.datastore와 bknr.cluster 사용: Raft 구현을 위해 Baidu의 Braft 라이브러리 사용
  • 이미지 파일 저장을 위해 EFS 사용: S3보다 오류 처리와 테스트가 용이함

요약

  • 이 아키텍처는 새로운 스타트업에 적합하며, Common Lisp을 사용하면 많은 도구가 이미 준비되어 있음
  • bknr.datastore, Braft, Raft의 기여에 감사함

GN⁺의 정리

  • 이 글은 데이터베이스 없이 고가용성 웹 서비스를 구축하는 새로운 아키텍처를 소개함
  • RAM을 데이터베이스로 사용하고, Raft 합의 알고리즘을 통해 고가용성을 보장함
  • Common Lisp을 사용하여 다중 스레드와 코드 핫 리로딩을 지원함
  • 이 아키텍처는 새로운 스타트업에 적합하며, 빠른 개발과 디버깅이 가능함
  • 유사한 기능을 가진 프로젝트로는 Redis와 Memcached가 있음
Hacker News 의견
  • SQLite를 사용하지 않고 자체 트랜잭션 로그를 만드는 것은 이상함

    • 데이터가 한 서버에 맞으면 그냥 그 서버에서 데이터베이스를 실행하는 것이 좋음
    • 데이터가 RAM에 맞으면 ramdisk를 사용하고 표준 도구로 영구 저장소에 복제하는 것이 간단함
  • MySQL, Postgres, Redis, MongoDB 등을 사용하지 않고 자체 메모리 내 데이터베이스를 만드는 것은 복잡함

    • 트랜잭션을 직렬화하고 디스크에 기록해야 함
    • 웹 서버 간의 트랜잭션 로그를 동기화하고 메모리 내 데이터베이스를 업데이트해야 함
    • 충돌 해결 알고리즘을 작성해야 함
    • 웹 서버를 테넌트별로 샤딩하고 로드 밸런싱 계층을 작성해야 함
  • MySQL이나 Postgres의 기본적인 측면을 배우지 않으려는 것은 시간 낭비임

    • 공용 클라우드 제공자에서 실행할 때 기본 튜닝으로 동시성 문제를 해결할 수 있음
    • 1천만 행을 추가하는 것은 큰 문제가 아님
    • 더 나쁜 상황이 올 때까지 기다렸다가 해결하는 것이 더 현명함
  • HashiCorp의 Nomad, Consul, Vault와 유사한 아키텍처임

    • 개발자 경험이 좋음
    • 메모리 내 상태를 원하는 대로 설정할 수 있음
    • 새로운 스타트업에는 적합하지 않음
    • 업그레이드가 특히 어려움
  • RAM이 매우 저렴하다는 오해가 있음

    • SSD와 vCPU 성능은 크게 향상되었지만 RAM 가격은 크게 떨어지지 않음
    • DRAM 가격은 주기적으로 변동하며, 최근에야 약간 저렴해짐
  • 파일 시스템 디렉토리를 테이블로, JSON 파일을 행으로 사용하는 프로젝트를 본 적이 있음

    • Redis, Mongo, Postgres를 고려했지만 자체 데이터베이스를 구축함
    • 혁신적인 토큰을 데이터베이스 구축에 사용하는 것은 비효율적임
  • 관계형 데이터베이스를 사용하는 것이 더 안정적임

    • 내장된 중복성, 트랜잭션 로그, 백업, 복구 기능이 있음
    • 대부분의 경우 데이터베이스를 사용하는 것이 좋음
  • 복잡한 것을 피하기 위해 자체 Raft 합의 계층을 구현함

    • Redis를 사용하는 것이 더 간단할 수 있음
  • 현대의 데스크탑 및 모바일 앱은 종종 SQLite와 같은 데이터베이스를 사용함

    • 관계형 데이터 저장 및 쿼리가 유용함
  • 자체 메모리 내 데이터베이스를 구축하는 것이 Postgres나 SQLite를 설치하는 것보다 간단하지 않음

    • 동시성 코드를 작성하는 것보다 SQL을 작성하는 것이 더 쉬움