데이터베이스의 일관성

Pinterest

 글 : 이승용

전통적인 데이터베이스 시스템의 일관성은 휘발성 저장장치와 비휘발성 저장장치 사이의 데이터 유지에 다루어졌다. 즉 시스템 장애에 따른 휘발성 저장장치에 저장된 데이터와 비휘발성 저장장치에 저장된 데이터와의 일관성 유지는 안전한 데이터 처리에 중요한 이슈인 것이다. 이를 위해 일관성은 엄격한 일관성Strict Consistency과 인과적 일관성Casual Consistency이라는 두 가지 측면에서 다루어 졌다.

  • 엄격한 일관성

가장 엄격한 일관성으로 모든 읽기가 가장 최근에 기록된 값을 읽어야 한다.

  • 인과적 일관성

타임스탬프보다 이벤트 순서에 일관성을 부여하여 관련성이 있는 모든 쓰기는 순서대로 읽혀야 한다.

이 두 가지 일관성을 살펴보면, 엄격한 일관성은 가장 기본적인 사항으로, 기존 RDBMS에서 사용되던 방식이다. 하지만, 분산화된 상태에서의 일관성을 엄격하게 유지한다는 것은 매우 어려운 일이며, 이는 또한, DB 시스템의 속도를 거북이보다 느리게 만드는 결과를 가져온다. 이러한 문제를 해결하기 위해, 분산 및 병렬 처리 환경에서 발생되는 일관성을 인과적casual인 관계로 구현한 기술이 인과적 일관성이다.

즉, 인과적 일관성의 필요조건은 쓰기 연산에 의해 저장된 데이터를 모든 프로세스가 동일한 순서로 읽기를 수행하여야 하며, 쓰기는 복수개의 다른 기계상에서 다른 순서로 쓰기 연산이 동시에 수행될 수 있다는 것을 전제로 한다. 다음의 예제를 살펴 보자.

 

[그림 1-1]

 

[그림 1-1]의 (a)번은 정상적인 인과적 일관성을 유지하고 있는 반면, (b)는 인과적 일관성에 위배된다. (a)번의 경우는 쓰기의 순서가 W(x)a 이후에 W(x)b로 발생되었다. 그리고, P2에서 R(x)a로 읽기가 a가 먼저 수행되었기 때문에 인과적 일관성이 유지된다. 하지만, (b)는 a와 b의 순서로 쓰기 연산이 수행되었지만, P3에서 b가 a보다 먼저 선행되어 인과적 일관성에 위배되었다. 한가지 주의할 점은 읽기 연산은 전체 프로세스를 걸쳐 어떤 순서로 발생되었는지 확인한다. 즉, (a)의 경우는 P3가 b, a순으로 데이터를 읽어 들였지만, P2에서 이미 a가 먼저 읽혀졌기 때문에 인과적 일관성에 위배되지 않는다.

NoSQL이 작금에 유행처럼 번지면서, 새로운 일관성에 대한 이론도 나타났다. Dynamo가 구현한 일관성으로 약한 일관성Weak Consistency가 그것이다. 약한 일관성은 엄격한 일관성과는 달리 데이터를 두 종류 – 동기화 데이터, 비동기화 데이터 – 로 구분한다. 동기화 데이터란 모든 시스템 전반에 걸쳐 동기화가 되어야 한다는 것으로, 분산 시스템이 100대의 규모로 구성되었다면, 모든 100대의 노드에서 동일한 읽기 연산을 수행하더라도 동일한 값이 읽혀져야 한다는 것이다. 따라서, 데이터 정보를 분산되어 저장하고 있는 모든 영역에 값이 정확히 쓰여질 때까지 쓰기 연산은 완료된 상태로 보지 않는다.

반면, 비동기화 데이터는 동기화 데이터와는 달리 운영자 또는 프로그래머에 의해 레벨을 결정할 수 있다. 예를 들어, 3군데로 구성된 데이터 영역에 2군데만 저장되어도 쓰기 연산이 성공하였다고 보는 것이다.

약한 일관성의 성질을 정리하면 다음과 같다.

  • 데이터 저장소에 할당된 동기화 데이터는 순차적 일관성 또는 엄격한 일관성을 유지하여야 한다.
  • 동기화 데이터 연산은 이전 모든 쓰기 연산이 모든 장소에서 완료될 때까지 허락하지 않는다.
  • 동기화 데이터를 포함한 데이터 읽기 및 쓰기 연산은 이전 모든 동기화 데이터 연산이 완료될 때까지 수행할 수 없다.

모든 데이터를 동기화 데이터로 저장할 경우, 분산데이터베이스에서는 모래 사장 위의 거북이보다 느릴 수 있다. 이를 위해 분산데이터베이스에서는 동기화 데이터 보다는 비동기화 데이터를 사용한다. 비동기화 데이터 레벨을 조정하여 일정 수준의 일관성을 확보하고, 비일관성이 발생되었을 경우에 보정 기능을 통해 해결할 수 있다면, 강력한 일관성 보다 유연한 시스템 구성이 가능하다. 다음의 예제를 보자.

 

[그림 1-2]

 

[그림 1-2] 시스템에서는 총 5개의 노드가 동일한 데이터 저장소를 가지고 있는 분산데이터베이스이다. 그리고 쓰기와 읽기가 노드 5에서 발생하고, 연산 레벨이 3으로 설정되어 있다. 연산 레벨 3은 쓰기 또는 읽기 연산이 3개의 노드를 통해 발생한다는 것이다. 즉, (a)번의 쓰기 연산은 노드 5에서 저장이 한번 발생하고 나머지 두 번의 연산이 성공하면 쓰기 연산을 성공으로 본다는 것이다. 따라서 (a)번에서의 쓰기 연산은 노드 1, 2, 5에서 성공하여 쓰기 연산이 완료되었다. 하지만, 노드 3, 4에서의 쓰기 연산이 실패한 것이 아니라, 쓰기 성공 이후에 언젠가는 성공한다는 것을 전제로 한다.

(b)번의 그림은 노드 5에서 읽기 연산을 쓰기 연산 바로 직후 수행한 것이다. 노드 5는 자신의 노드에서 읽어 들인 데이터가 일관성에 위배되는지 판단하기 위해, 시스템에 설정된 레벨을 취득하여, 자신 이외에 두 개의 노드에서 동일한 데이터 값을 읽어 들인다. 이때, 읽어 들인 데이터가 자신과 같은 데이터라면 읽기 성공을 나타내고, 값을 리턴 한다.

 

[그림 1-3]

 

하지만, [그림 1-3]과 같은 (c)의 경우는 읽기 연산이 실패된 경우이다. (a)번의 쓰기 연산 이후에 노드 4번으로 쓰기 연산을 수행한 데이터가 아직 쓰기 연산을 수행하지 않은 경우라면, 노드 4의 값은 노드 5가 보유한 데이터 값과 다른 값을 가지고 있을 것이다. 이때 읽기 연산은 실패로 판단하고 보정 연산을 수행하여야 한다. 보정 연산은 일정 시간 동안 노드 4의 데이터 값을 취득하여 노드 5의 값과 동일한지 판단하는 것이다.

 

이전글 : MongoDB의 일관성

다음글 : 소켓의 blocking-mode


  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
  1. 아직 댓글이 없습니다.
  1. 엮인글들이 아직 없습니다.