MongoDB의 데이터 유실 가능성

Pinterest

글 : 이승용

앞 절에서 살펴보았듯이 MongoDB의 데이터 유실 가능성이 존재하지 않는 것은 아니다. 복제의 경우는 slave가 아무리 빨리 데이터 동기화를 한다고 하여도, master와의 통신 지연 시간만큼의 차이를 가질 수 있고, 저널링 역시 group commits의 시간에 의해 차이가 발생된다.

하지만, slave의 Oplog 동기화는 시스템 부하가 없는 경우라면, 쓰레드에 의해 아주 빠르게 주기적으로 동기화를 수행하기 때문에, 쓰기 연산이 엄청난 부하를 가지는 않는 상태에서는 Oplog의 동기화로 문제시 되지 않는다. 다만, 부하를 견디지 못해 서버가 죽는 경우라면, Oplog에 동기화 되지 않은 채 남아있는 데이터 연산을 잃어버리는 현상이 나타난다.

저널링은 데이터 저장소에 문제가 발생하여 데이터가 유실되었을 경우에, 복구를 수행하는 것이다. 복구는 MongoDB를 재 기동시킬 때 또는 복구 명령을 직접 수행하였을 경우에 이루어진다. 저널링 파일에 데이터를 저장하는 방법 역시, 앞 절에서 살펴보았듯이 디폴트 값이 100ms의 오차를 가지고 있다. 만약 100ms 안에 데이터가 존재하여 시스템이 죽어서 메모리에 저장된 데이터가 날라갔다면, 이는 복구가 불가능하다.

이러한 경우는, 복제로 설정된 상태에서 master와의 Oplog를 통한 동기화를 수행할 수 있으므로, 일정 부분 복구가 가능하다. 하지만, master 자체가 죽었다면 복구가 불가능한 데이터가 일부 남아 있을 수 있다.[1] MongoDB는 이러한 문제점을 해결하기 위해 [표 1]의 일관성 정책에서 복제의 Oplog와 관련된 REPLICAS_SAFE, MAJORITY를 제공하고, 저널링과 관련된 JOURNAL_SAFE를 제공한다. REPLICAS_SAFE는 master를 제외한 적어도 한 개의 slave의 Oplog가 동기화가 완료된 상태를 의미하고, MAJORITY는 임의의 복제 집합으로 구성된 노드들의 과반수가 Oplog 동기화에 성공하였음을 의미한다. 예를 들어, 복제 레벨을 5로 구성하였다면[2], master를 포함한 3대가 동기화 되었음을 알려준다. JOURNAL_SAFE는 저널 파일에 로그가 저장될 때까지 쓰기 연산을 기다리는 것으로, 만약 group commits가 100ms로 설정되어 있다면, 한 번의 쓰기 연산은 최대 100ms를 기다릴 수 있음을 나타낸다.

이외에도 FSYNC_SAFE 모드가 있는데, 이는 MongoDB가 메모리에 있는 데이터를 물리적 저장소에 저장시킬 때까지 쓰기 연산을 기다리는 것을 의미한다. MongoDB의 fsync는 디폴트 값이 60초로 설정되어 있다. 따라서 한 번의 쓰기 연산은 최대 60초를 기다릴 수 있다.

MongoDB의 데이터 유실과 관련된 사항은 일반 데이터베이스에서 고려될 수 있는 일반적인 사항이다. MongoDB 역시 이러한 부분을 옵션을 이용하여 처리할 수 있도록 제공하고 있고, 또는 쓰기 연산에 WriteConcern을 조정하여 특정 연산에 대한 트랜잭션을 보장할 수 있도록 API를 제공하고 있다.

일관성과 데이터 유실 문제가 심각한 트랜잭션 보장 데이터에 대해서는 복제로 구성된 시스템에서는 REPLICAS_SAFE로 처리하는 것이 바람직하며, standalone으로 사용하는 시스템에서는 저널링의 group commits 시간을 줄이고, JOURNAL_SAFE를 사용하는 것이 바람직하다. 물론 이러한 두 가지 방법 모두 성능과 밀접한 관련이 있으므로, 프로그래머에 의한 적절한 조절이 필요하다.

마지막으로, 복제가 이유 없이 수행되지 않는다는 것은, 첫째 시스템 부하가 너무 많아서 slave의 동작이 의심스러운 경우, 또는 master의 fail에 대해서 master 선출과정에서 slave들이 master 정보를 갱신하지 못해, Oplog의 동기화를 수행하지 못하는 경우이다.

전자의 경우는 한 노드에 여러 개의 slave를 설정하는 경우이거나 다른 프로세스의 동작이 MongoDB의 slave가 원활하게 동작할 수 없도록 막는 경우이다. 가급적 MongoDB의 coordinate하는 과정에서 slave를 중복하여 설치하는 것은 복제 동기화에 부담을 줄 수 있으므로, 피하는 것이 바람직하다. 후자의 경우는 예전 버전에서 이러한 문제점들이 발견되어 master를 읽는 경우가 있었으나, 현재는 그러한 버그는 모두 수정된 것으로 알고 있다. 만약 slave를 arbiter와 같이 사용할 경우에, arbiter는 master 선출을 위한 투표 이외에 아무런 작업을 하지 않으므로, 복제와는 관련이 없다.

완벽한 프로그램은 존재하지 않는다. 어떤 이유에서라도 프로그램 오동작으로 인해, 프로세스가 충돌이 날 수 있다. 이러한 경우를 대비하기 위해, 중요한 시스템에서는 복제 레벨을 올려두거나 또는 일관성 정책을 조절하는 등 여러 가지 대비하여 시스템을 구축하는 것이 가장 좋은 fail-over 방법이다.

 

이전글 : MongoDB의 복제 한계

 


[1] Oplog의 동기화는 slave가 master에 요청하는 것이기 때문에, slave는 master의 데이터보다 같거나 적은 데이터를 유지한다.

[2] Master 1대와 slave 4대로 구성


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