책너두 (데이터 중심 애플리케이션 설계) 16일차 (~193p)

요약

  • 리더 없는 복제에서 정족수 일관성의 한계에 대해 알게 됨.
    • 정족수 조건을 만족하지 못하는 경우에 대한 문제가 있음.
    • 최종적 일관성을 허용하도록 합의가 필요함.
  • 느슨한 정족수와 암시된 핸드오프에 대해 알게 됨.
    • 느슨한 정족수 : 정족수를 충족하지 않더라도 쓰기를 허용한다.
    • 암시된 핸드오프 : 일시적으로 수용한 쓰기를 홈노드로 전송한다.
  • 동시 쓰기 감지에 대해 이해함
    • 동시 쓰기로 인해 충돌이 불가피함.
    • 충돌 해소 기법이 여러개 있음.
      • 최종 쓰기 승리
      • “이전 발생” 관계와 동시성
        • 이전 발생 관계 파악하기
      • 동시에 쓴 값 병합
      • 버전벡터

메모

정족수 일관성의 한계

  • w + r > n 이 되게끔 w, r 을 선택하면, 읽은 노드 중, 최신 값을 가진 노드가 하나 이상 있어야 함.
    • 보통, r 과 w 값은 노드의 과반수 (= n/2 초과)를 선택함.
    • 왜냐하면 n/2 노드가 장애가 나도 w + r > n 이 보장되기 때문
  • w + r ≤ n (정족수 조건 충독되지 않음) 조건이 되게끔 설정할 수도 있음.
    • 이 경우는 읽기, 쓰기를 계속 n개의 노드로 전송하지만 성공에 필요한 성공 응답의 수는 더 적음.
    • 따라서 낮은 지연시간과 높은 가용성이 가능함.
  • w + r > n 인 경우에도 오래된 값을 반환하는 엣지 케이스가 있음.
    • 느슨한 정족수를 사용한다면 w개의 쓰기는 r개의 읽기와 다른 노드에서 수행될 수 있으므로, r개의 노드와 w개의 노드가 겹치는걸 보장하지 않음.
    • 두 개의 쓰기가 동시에 발생하면 어떤 쓰기가 먼저 일어났는지 불분명함.
    • 쓰기가 읽기와 동시에 발생하면 쓰기는 일부 복제 서버에만 바녕될 수 있음.
    • 쓰기를 성공했는데, w 복제 서버보다 적다면 성공한 복제 서버에서는 롤백하지 않음.
      • 만약, 쓰기가 실패된다면, 이어지는 읽기에서 쓰기에 실패한 값이 반환될 수도 있고, 아닐 수도 있음.
    • 새 값을 전달하는 노드가 고장나면, 예전 값을 가진 다른 복제 서버에서 해당 데이터가 복원되는데, 새로운 값을 저장한 복제 서버 수가 w보다 낮아져서 정족수 조건이 깨짐
    • 동작 시점 문제로 인한 엣지 케이스가 있을 수 있음.
      • p331쪽에서 다시 다룸
  • 다이나모 스타일 데이터베이스는 일반적으로 최종적 일관성을 허용하는 사용 사례에 맞게 최적화됨.
    • 하지만, 매개변수 w, r 만으로 오래된 값을 읽는 확률을 조정할 수는 있지만 절대적 보장은 안됌.
    • 따라서, 견고한 보장을 위한 일반적인 트랜잭션이나 합의가 필요함.
      • 7, 9장에서 다시 다룸

최신성 모니터링

  • 리더 기반 복제에서 데이터베이스는 일반적으로 복제 지연에 대한 지표를 노출함.
    • 이 지표는 모니터링 시스템에 제공됨.
    • 쓰기가 리더에 적용되고, 같은 순서로 팔로워에도 적용되고 각 노드가 복제 로그의 위치를 가지기 때문에 가능함.
    • 리더의 현재 위치에서 팔로워의 현재 위치를 빼면 복제 지연량을 측정할 수 있음.
  • 리더 없는 복제 시스템에서는 쓰기가 적용된 순서를 고정할 수가 없어서 모니터링이 좀 더 어려움.
    • 최종적 일관성은 모호한 보장이지만, 운용성을 위해서는 “최종적”을 정량화할 수 있어야 함.

느슨한 정족수와 암시된 핸드오프

  • 적절히 설정된 정족수가 있는 데이터베이스는 장애 복구 없이 개별 노드 장애를 용인함.
  • 하지만 정족수는 내결함성이 없음.
    • 네트워크 중단등의 이유로 데이터베이스 노드와 클라이언트 연결이 쉽게끊어질 수 있음.
    • 이 상황에서, 응답 가능한 노드가 w, r보다 적을 가능성이 있으므로 클라이언트는 더 이상 정족수를 충족할 수 없음.
  • 노드가 n개 이상인 대규모 클러스터에서 클라이언트는 네트워크 장애 상황에서 일부 데이터베이스 노드(= 정족수 구성에 들어가지 않는 노드)에 연결될 가능성이 있음.
    • 여기서 트레이드오프에 직면함
      • w나 r노드 정족수를 만족하지 않는 모든 요청에 오류를 반환하는게 좋을까?
      • 아니면 일단 쓰기를 받아들이고 값이 보통 저장되는 n개 노드에 속하지는 않지만 연결할 수 있는 노드에 기록할까?
    • 여기서 후자를 느슨한 정족수라 부름.
      • 즉, 쓰기와 읽기는 w, r의 성공 응답이 필요하지만, 값을 위해 지정된 n개의 홈노드에 없는 노드가 포함될 수 있음.
        • 여기서 네트워크 장애 상황이 해제되면 한 노드가 다른 노드를 위해 일시적으로 수용한 모든 쓰기를 해당 홈노드로 전송함.
          • 이를 암시된 핸드오프라 부름
    • 느슨한 정족수는 쓰기 가용성을 높임.

다중 데이터센터 운영

  • 리더 없는 복제 모델도 다중데이터센터 운영에 적합함.
    • 동시 쓰기 충돌, 네트워크 중단, 지연 시간 급증을 허용하기 때문
  • 클라이언트의 각 쓰기는 데이터센터 상관없이 모든 복제 서버에 전송됨.
    • 그렇지만, 클라이언트는 보통 로컬 데이터센터 안에서 정족수 노드의 확인 응답을 기다리므로 데이터센터 간 연결의 지연과 중단에 영향을 받지 않음.

동시 쓰기 감지

  • 다이나모 스타일 데이터베이스는 여러 클라이언트가 동시에 같은 키에 쓰는 것을 허용하기에 엄격한 정족수를 사용하더라도 충돌이 발생함.
  • 네트워크 지연 등의 이유로 쓰기가 다른 노드에 다른 순서로 도착할 수 있음.
    • p186 예시 참고
    • 각 노드가 클라이언트로부터 쓰기 요청을 받을 때마다 키의 값을 단순하게 덮어 쓴다면, 노드들이 영구적으로 일관성이 깨짐.
    • 데이터 손실을 피하려면 애플리케이션 개발자는 데이터베이스 내부에서 충돌을 어떻게 다루는지 잘 알아야 함.
      • 데이터베이스가 이를 자동으로 처리해주길 바라지만, 불행하게도 대부분의 구현은 그렇지 못하기 때문임.
  • 충돌 해소를 위한 몇가지 전략을 살펴보자.

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

  • 각 복제본이 예전값을 버리고 가장 최신값으로 덮어쓰는 방법임.
  • 클라이언트가 동시 쓰기를 했다고하면, 이는 자연적인 순서는 없지만 임의로 순서를 정할 수 있음.
    • ex) 쓰기에 타임스탬프를 붙여 가장 최신이라는 의미로 제일 큰 타임스탬프를 선택하고 예전 타임스탬프를 가진 쓰기를 무시한다.
    • 최종 쓰기 승리(LWW)라 부르는 충돌 해소 알고리즘은 카산드라에서 유일하게 제공하는 충돌 해소 방법임.
    • 손실 데이터를 허용하지 않으면 LWW는 충돌 해소에 적합하지 않음.

“이전 발생” 관계와 동시성

  • 작업 B가 작업 A에 대해서 알거나 A에 의존적이거나 어떤 방식으로든 A를 기반으로 한다면 작업 A는 작업 B의 이전 발생(happens-before)임.
    • 한 작업이 다른 작업 이전에 발생했는지가 동시성의 의미를 정의하는 핵심임.
    • 이러한 인과가 없다면, 단순히 동시 작업이라고 말함.
      • 두 작업이 동시성인지 아닌지 알 수 있는 알고리즘이 필요함.
  • 단순히 동시 작업이 발생한다면, 충돌을 해소해야 함.

이전 발생 관계 파악하기

  • p189-190 예시 참고
  • 작업간 데이터프로는 어떤 작업이 다른 작업 이전에 발생했는지, 두 작업간의 의존이 있는지를 나타냄.
    • 서버는 버전 번호를 보도 두 작업이 동시에 수행됐는지 여부를 결정할 수 있음.
    • 쓰기에 이전 읽기의 버전 번호를 포함하면 쓰기가 수행되기 이전 상태를 알 수 있음.
    • 만약, 버전 번호를 포함하지 않는 쓰기는 다른 쓰기와 동시에 수행된 것이므로 아무것도 덮어쓰지 않는다.

동시에 쓴 값 병합

  • 이 알고리즘은 어떤 데이터도 자동 삭제되지 않음을 보장함.
  • 하지만 클라이언트가 추가적으로 작업을 수행해야함.
  • 여러 작업이 동시에 발생하면 클라이언트는 동시에 쓴 값을 합쳐서 정리해야 함.
  • 만약, 쓰기에서 값 추가가 아닌 값 삭제라면 단순히 데이터베이스에서 삭제하면 안됨.
    • 대신 형제를 병합할 때, 상품을 제거했음을 나타내기 위해 해당 버전 번호에 표시를 남겨둬야 함.
      • 이런 삭제 표시를 툼스톤이라고 함.

버전 벡터

  • 다중 복제본에서 리더가 없는 경우, 키당 버전 번호 뿐만 아니라 복제본당 버전 번호도 사용해야 함.
    • 모든 복제본의 버전 번호 모음을 버전 벡터(version vector)라고 부름.
    • 이 버전 벡터를 이용하면 데이터베이스는 복제본에서 덮어쓰기와 동시 쓰기를 구분할 수 있음.
    • 형제 병합할 때, 버전 벡터는 하나의 복제본을 읽은 다음, 이어서 다른 복제본에 다시 쓰는 작업이 안전함을 보장한다.

댓글

Designed by JB FACTORY