데이터 중심 애플리케이션 설계 - 5장

공상현 (Kong Sang Hyean)·2024년 6월 12일
0

K DEVCON DDIA STUDY

목록 보기
5/12

😊 Go to Learn이란?

K-devcon에서 주최하는 멘토링 프로그래밍으로 각 분야에서 전문가이신 멘토분들의 멘토링을 통하여 약 2-3달간 진행하는 프로그램입니다.

Go to Learn 1기 같은 경우 Flutter, Back-end, Full-stack, Writing 등 여러가지 주제가 담긴 멘토링 프로그램이 있었습니다.

그 중 Back-end를 중심으로 진행하는 DDIA 프로그램 같은 경우 데이터 중심 애플리케이션 설계라는 책을 매주 1장 씩 정독하고 요약하면서 괸련된 이야기를 논의하면서 진행하고 있습니다.

K-devcon 이란? : IT 정보를 공유하거나 위에서 설명한 Go to Learn 스터디 및 밋업을 개최하는 활동을 하고있는 IT 커뮤니티입니다.
K-devcon 홈페이지 바로가기


📖 5장 요약 및 정리

분산 데이터의 특징

확장성 : 단일 장비에서 다룰 수 있는 양보다 커지면 여러 장비로 분배할 수 있다.

  • 내결함성 & 고가용성 : 장비 하나가 죽더라도 애플리케이션을 동작 할 수 있다.
  • 지연 시간 : 전 세계 다양한 곳에 서버를 둘 수 있어 지리적으로 가까운 곳에서 통신 할 수 있다.

고부하 확장 : 공유 메모리 아키텍처에서 모든 구성 요소를 단일 장비처럼 다룰 수 있다.

비공유 아키텍처 : 각 독립적인 노드간 네트워크를 사용하여 코디네이션하여 소프트웨어 수준에서 수행한다.

데이터를 분산하는 방법은 크게 복제, 파티셔닝 등이 존재한다.

단일 리더 복제

단일 리더 복제는 하나의 리더와 다수의 팔로워로 이루어져있는 데이터 복제 방식이다.

동기식과 비동기식 복제

복제 시스템의 중요한 세부 사항 중 하나는 복제가 동기식으로 발생하는지 비동기식으로 발생하는지의 여부이다.

동기식 : 클라이언트로부터 쓰기를 수신했는지 확인해줄 때 까지 기다려준 후 응답해주는 방식이다.

  • 동기식은 최신 데이터 복사본을 가지는 것을 보장해준다.
  • 만일 팔로워에서 응답하지 않는다면 쓰기가 처리될 수 없는 단점이 존재한다.
  • 반동기식 : 동기식을 사용할 수 없거나 느려지면 적어도 두 노드에 데이터의 최신 복사본이 있는 것을 보장하는 방법이다.

비동기식 : 메시지를 전송하지만 팔로워의 응답을 기다리지 않고 쓰기를 처리해주는 방식이다.

  • 보통 리더 기반 복제에 구성되있다.

팔로워 설정 과정

  1. 가능하다면 전체 데이터베이스를 잠그지 않고 리더의 데이터베이스 스냅숏을 일정 시점에 가져온다.
  2. 가져온 스냅숏을 새로운 팔로워 노드에 복사한다.
  3. 팔로워는 리더에 연결해 스냅숏 이후 발생한 모든 데이터 변경을 요청한다.
  4. 팔로워가 데이터 변경 미처리분을 모두 처리했을 때 리더에 발생하는 데이터 변화를 이어 처리할 수 있게 된다.

노드 중단 처리

팔로워 노드에서 장애가 발생했을 경우 : 팔로우에서 재시작하거나 리더와 팔로워 사이의 네트워크가 일시적으로 중단된 후 따라잡기 복구를 실행한다.

리더 노드에서 장애가 발생했을 경우

  1. 먼저 리더 노드가 장애가 발생했는지 판단한다.
  2. 팔로우 노드 중 새로운 리더 노드를 선택한다.
  3. 새로운 리더 사용을 위해 시스템을 재설정한다.

복제 로그 구현

리더 기반 복제는 내부적으로 동작하는 방법들은 아래와 같다.

구문 기반 복제

  • 모든 쓰기 요청을 구문으로 기록하고 쓰기를 실행 한 뒤 구문 로그를 각 팔로워 노드에게 전송하는 방법이다.
  • 각 팔로워 노드는 클라이언트에서 직접 받은 것처럼 SQL 구문을 파싱한 후 구문을 실행한다.

쓰기 전 로그 배송

  • 로그 구조화 및 B 트리 등의 자료구조를 활용하여 디스크 상에서 데이터를 표현하는 방법이다.
  • 완전히 동일한 로그를 사용해 다른 노드에서 복제 서버를 구축한다.
  • 위 로그를 각 팔로워 노드가 처리되어 진다면 리더에 있는 것과 정확히 동일한 데이터 구조의 복제본이 만들어진다.
  • 활용 : 포스트그레스큐엘, 오라클

논리적 로그 복제 (로우 기반)

  • 논리적 로그 (logical log) : 같은 종류의 복제 로그를 저장소 엔진의 데이터 표현과 구별하기 위해 사용되어진다.
  • 로우 단위로 관계형 데이터베이스 테이블에 쓰기를 기술한다.
  • 위의 방식은 하위 호환성을 더 쉽게 유지할 수 있으며, 변경 데이터를 캡쳐할 수 있어 외부 애플리케이션이 파싱하기 더 쉬워진다.

트리거 기반 복제

  • 애플리케이션 층에서 복제 로그를 구현하는 방식이다.
  • 트리거 및 스토어드 프로시저 방식이 활용된다. 트리거 같은 경우 사용자 정의 애플리케이션 코드를 등록할 수 있다.

복제 지연 문제

읽기 확장 : 팔로워를 추가함으로써 처리 용량을 늘릴 수 있다.

  • 동기식으로 진행한다면 단일 노드 장애나 네트워크 중단으로 쓰기가 불가능하진다.

최종적 일관성 : 모든 쓰기가 팔로워에 반영되지 않았기 때문에 데이터가 불일치 되어진다.

  • 데이터베이스에 쓰기를 멈추고 기다리면 팔로워는 따라잡히게 되고 리더와 일치해진다.

자신이 쓴 내용 읽기

비동기식 복제에서는 사용자가 쓰기를 수행한 직후 데이터가 복제 서버에 반영되지 않을 수 있다.

  • 위를 해결하기 위하여 디바이스 간 쓰기 후 읽기 일관성이 필요하다.
  • 페이지를 재로딩하였을 때 자신이 제출한 모든 갱신을 볼 수 있음을 보장할 수 있어야한다.

단조 읽기

사용자가 쓰기를 수행할 경우 시간이 거꾸로 흐르는 현상을 목격할 수도 있다.

  • 단조 읽기를 활용하여 이러한 현상을 발생하지 않음을 보장해야한다.
  • 단조 읽기를 달성하는 방법 중 하나는 각 사용자의 읽기가 항상 동일한 복제 서버에서 수행되게 끔 할 수 있게 진행하는 방법이 있다.

일관된 순서로 읽기

복제를 수행하게 될 경우 인과성 위반이 우려될 수 있다.

  • 위의 현상을 방지하기 위해 일관된 순서로 읽기 보장이 필요하다.
  • 단, 위의 문제는 파티셔닝된 데이터베이스에서 발생하는 특징적인 문제에 해당된다.

복제 지연문제에 대한 해결책

위의 문제들을 해결하기 위하여 복제가 비동기식으로 동작하지만 동기식으로 동작하는 척 해야한다. 위를 실행하기 위하여 주로 트랜잭션을 활용되어진다.


다중 리더 복제

모든 쓰기는 하나의 리더를 거쳐야하여 리더에 연결할 수 없다면 데이터베이스에 쓰기처리가 불가능해지는 리더 기반 복제의 문제를 해결하기 위해 쓰기를 허용하는 노드를 하나 이상 두는 다중 리더 복제가 등장하였다.

다중 리더 복제의 사용 사례

여러 다른 데이터센터에서 각 데이터센터 마다 다중 데이터센터 운영할 때 활용되어진다.

  • 동일한 데이터를 다른 두 개의 데이터센터에서 동시에 변경할 수 있다. , 위와 같은 경우 쓰기 충돌이 발생 할 수도 있다.

또한 인터넷 연결이 끊어진 동안 애플리케이션이 계속 동작해야하는 경우 활용되어진다.

동시에 여러 사람이 문서를 편집할 수 있는 협업 편집 툴에서도 활용되어진다. 위의 사례는 오프라인 편집 사용 사례와 공통점이 많다.

쓰기 충돌 해결 방법

다중 리더 복제는 충돌 해소가 필요해야 할 상황이 많다. 아래의 방법을 통하여 쓰기 충돌을 해결하고 있다.

동기 대 비동기 충돌 감지

다중 리더 설정에서 두 쓰기가 모두 성공 후 데이터 충돌은 이후 특정 시점에서 비동기로만 감지되어진다.

  • 이론적으로 충돌 감지는 동기식으로 만들 수 있다.

충돌 회피

특정 레코드의 모든 쓰기가 동일한 리더를 거치도록 애플리케이션이 보장해주는 방식이다.

  • 단, 한 데이터센터가 고장 나서 트래픽을 다른 데이터센터로 다시 라우팅해야 할 경우 위의 방법은 실패할 수 있다.

일관된 상태 수렴

다중 리더 설정에서는 쓰기 순서가 정해지지 않아 최종 값이 무엇인지 명확하지 않다.

  • 따라서 모든 복제 계획은 모든 복제 서버가 최종적으로 동일하다는 사실을 보장해야한다.
  • 수렴 방식으로 충돌을 해소해야한다.

사용자 정의 충돌 해소 로직

쓰기 수행 중 : 로그에서 충돌을 감지하자마자 충돌 핸들러를 호출한다.
읽기 수행 중 : 충돌을 감지하면 모든 충돌 쓰기를 저장한다.

  • 다음 번 데이터를 읽을 때 여러 버전의 데이터가 애플리케이션으로 변환한다.

자동 충돌 해소

  • 아마존의 장바구니 충돌 해소가 그 예시이다.
  • 충돌 없는 복제 데이터 타입 / 병합 가능한 영속 데이터 구조 / 운영 변환

다중 리더 복제 트롤로지

복제 트롤로지 : 쓰기를 한 노드에서 다른 노드로 전달하는 통신 경로들을 설명해준다.

  • 쓰기는 모든 복제 서버에 도달하기 전에 여러 노드를 거쳐야 한다.
  • 하나의 노드에 장애가 발생하면 흐름에 방해를 줄 수 있다.

전체 연결 : 모든 리더가 각자의 쓰기를 다른 모든 리더에서 전송한다.

원형 트롤로지 : 각 노드가 하나의 노드로부터 쓰기를 받고, 다른 노드로 전달한다. (활용 예시 : mySQL)

별 모양 트롤로지 : 지정된 루트 노드 하나가 다른 모든 노드에 쓰기를 전달 한다.

  • 보통 트리로 일반화하는 방식으로 사용되어진다.

리더 없는 복제

리더 없는 복제는 다이나모 시스템에서 사용된 후 데이터베이스용 아키텍쳐로 사용되어졌다.
다른 용어로 다이나모 스타일로 불러지고 있다.
리더 없는 복제 같은 경우 리더 노드가 없기 때문에 장애 복구가 필요하지 않다.

노드가 다운되었을 때

누락된 클라이언트가 해당 노드에서 데이터를 읽는다면 응답으로 오래된 값을 얻을 수 있다.
위의 문제를 해결하기 위해 읽기 요청을 병렬로 여러 노드로 전송

읽기 복구

클라이언트가 여러 노드에서 병렬로 읽기를 수행하면 오래된 응답을 감지할 수 있다. 만일 오래된 응답을 감지하였을 경우 새로운 값을 다시 기록한다.

안티 엔트로피

백그라운드 프로세스를 두고 복제 서버 간 데이터 차이를 지속적으로 찾아 누락된 데이터를 하나의 복제 서버에서 다른 서버로 복사하는 방법이다.

  • 위의 방법을 통하여 데이터가 무질서한 상황을 방지힐 수 있다.
  • 단, 거의 읽지 않는 값은 일부 복제본에서 누락되어 각 노드 간 내구성이 떨어진다.

정족수

n개의 복제 서버가 있을 때 모든 쓰기는 w개의 노드에서 성공해야 쓰기가 확정되고 모든 읽기는 최소란 r개의 노드에 질의해야 할 수 있도록 설정하는 방법이다.

  • 각 파라미터(n, w, r)는 설정이 가능하다.
    - 보통 r와 w의 값으로 노드의 과반수를 선택하는 편이다.
    • r와 w이 작을수록 오래된 값을 읽힐 확률이 높다.
  • 단, 리더가 없는 복제 시스템은 쓰기가 적용된 순서를 고정할 수 없어 모니터링이 조금 더 어렵다.

느슨한 정족수

쓰기와 읽기는 여전히 성공 응답이 필요하지만 연결이 쉽게 끊어짐을 막기 위하여 지정된 홈 노드가 없는 노드가 포함 될 수 있다.
위의 방식을 이용한 방법이 느슨한 정족수이다.

  • 암시된 핸드오프 : 네트워크 장애 상황이 해제되면 한 노드가 다른 노드를 위해 일시적으로 수용한 모든 쓰기는 홈 노드 전송하는 방식이다.

동시 쓰기 감지

여러 클라이언트가 동시에 같은 키에 쓰는 것을 허용하기 때문에 충돌이 발생할 수도 있다.
이벤트 순서가 정해지지 않았을 경우 동시 쓰기라고 부른다.

최종 쓰기 승리 (동시 쓰기 버리기)

각 복제본이 가진 예전 값을 버리고 가장 최신 값으로 덮어쓰는 방법이다.

이전 발생

한 작업이 다른 작업 이전에 발생했는지가 핵심이다. 만일 작업이 다른 작업보다 먼저 발생하지 않으면 동시 작업

형제 값

여러 작업이 동시에 발생하면 클라이언트는 동시에 쓴 값을 합쳐 정리해야한다.

  • 형제 값의 변합은 다중 리더 복제에서 충돌을 해소하는 문제와 같다.
  • 형제를 병합할 때 제거했음을 나타내기 위해 버전 번호에 표시해야한다.(툼스톤을 활용한다.)

버전 벡터

모든 복제본의 버전 번호 모음이다.

  • 비전 벡터는 값을 읽을 때 데이터베이스 복제본에서 클라이언트로 보낸다. 그 이후 기록할 때 데이터베이스로 다시 전송한다.

😉 필자의 생각

5장은 분산 데이터에 관한 챕터를 시작하게 되면서 데이터를 분산하게 되는 방법 중 하나인 복제에 대하여 설명해주는 내용이었다.

위 장을 읽어보면서 데이터 충돌 및 덮어쓰기에 관한 내용들이 중심 내용이었던 것 같았다. 아무래도 데이터 베이스를 분산화 시키는 작업에서 자주 나타는 문제였기 때문인 것 같다. 덕분에 위의 문제를 해결하기 위한 해결법 또한 많이 기술되어 있었다.

또한 단일 리더 복제 방식을 어떻게 이용하고 있는 지 논의하고 있는 중 RDS Aurora에 대한 설명을 듣게 되었는데, 해당 서비스 내 들어있는 Cluster Volume을 이용하여 편의성을 보장할 수 있다고 한다.

관련 자료
Amazon Aurora이란 무엇인가요? - Amazon Aurora

리더 없는 복제같은 경우 다이나모 방식을 활용하여 사용한다는 내용이 있어서 혹시 다이나모 DB와 관련이 있지 않을까 생각이 들어 위의 서비스는 복제를 어떻게 활용하는지 잠깐 조사하게 되었다.

조사 결과 다이나모 디비 같은 경우 전역 테이블 작업을 이용하여 데이터를 지역 간으로 복제가 가능하다고 한다. 그렇지만 다이나모 디비같은 경우 이름과 무색하게 데이터 복제 같은 경우 전혀 다른 아키텍쳐를 사용한다고 한다. ㅜㅜ

관련 자료
Global tables - multi-Region replication for DynamoDB - Amazon DynamoDB

마지막으로 책 말미에 나오는 CRDT에 대하여 이야기가 나왔는데 CRDT는 합리적인 방법으로 형체를 자동 병합할 수 있는 데이터 구조군이다. 대표적인 예시로 Code Editer 중 하나인 Zed 내 버퍼를 CRDT를 활용하고 있다.

위의 내용을 활용하여 실시간 협업 편집 툴과 관련하여 작은 사이드 서비스 프로젝트 하나를 만들고 싶어졌다.

profile
개발자 같은 거 합니다. 1인분 하는 개발자로서 살아갈려고 노력 중입니다.

0개의 댓글