문서 메뉴

문서 홈애플리케이션 개발MongoDB 매뉴얼

삽입 전용 워크로드를 위한 분산 로컬 쓰기

이 페이지의 내용

  • 시나리오
  • 절차

MongoDB 태그 인식 샤딩을 사용하면 관리자가 샤드 키 의 범위를 정의하고 하나 이상의 샤드에 태그를 지정하여 샤딩된 클러스터의 데이터 배포를 제어할 수 있습니다.

이 튜토리얼에서는 다중 데이터 센터 샤드 cluster 배포 및 애플리케이션 측 로직과 함께 Zones 을 사용하여 분산된 로컬 쓰기는 물론 replica set 이벤트 또는 데이터 센터 장애 발생 시 높은 쓰기 가용성을 지원합니다.

샤드 컬렉션 작업은 비어 있거나 존재하지 않는 컬렉션을 샤딩하기 전에 구역 및 구역 범위를 정의하여 정의된 구역 범위에 대한 청크와 샤드 키 값의 전체 범위를 포함하는 추가 청크를 생성하고 그역 범위를 기반으로 초기 청크 분배를 수행합니다. 이러한 청크의 초기 생성 및 배포를 통해 샤딩을 더 빠르게 설정할 수 있습니다. 초기 분배 이후에는 밸런서가 앞으로의 청크 분배를 관리합니다.

예를 보려면 비어 있거나 존재하지 않는 컬렉션에 대한 구역 및 구역 범위 사전 정의를 참조하세요.

중요

이 튜토리얼에서 설명하는 개념에는 애플리케이션 수준 로직뿐만 아니라 특정 배포 아키텍처가 필요합니다.

이러한 개념을 이해하려면 MongoDB 샤드 cluster, 복제본 세트구역의 일반적인 동작을 잘 알고 있어야 합니다.

이 튜토리얼에서는 삽입 전용 또는 삽입 집약적인 워크로드를 가정합니다. 이 튜토리얼에서 설명하는 개념과 전략은 빠른 읽기 또는 업데이트가 필요한 사용 사례에는 적합하지 않습니다.

읽기가 빈번하지 않고 쓰기에 비해 우선순위가 낮은 삽입 집약적인 애플리케이션을 생각해 보세요. 이 애플리케이션은 샤드 collection에 문서를 작성하며, SLA 또는 SLO를 지원하기 위해 데이터베이스의 거의 일정한 가동 시간이 필요합니다.

다음은 애플리케이션이 데이터베이스에 쓰는 문서 형식의 부분 보기를 나타냅니다.

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620,
"datacenter" : "alfa",
"userid" : 123,
...
}
{
"_id" : ObjectId("56f08c447fe58b2e96f595fb"),
"message_id" : 578494,
"datacenter" : "bravo",
"userid" : 456,
...
}
{
"_id" : ObjectId("56f08c447fe58b2e96f595fc"),
"message_id" : 689979,
"datacenter" : "bravo",
"userid" : 789,
...
}

이 collection은 { datacenter : 1, userid : 1 } 복합 인덱스를 샤드 키로 사용합니다.

각 문서의 datacenter 필드를 사용하면 각 고유 데이터 센터 값에 태그 범위를 만들 수 있습니다. datacenter 필드가 없으면 문서를 특정 데이터 센터와 연결할 수 없습니다.

userid 필드는 datacenter에 비해 분할 키에 높은 카디널리티와 낮은 빈도 구성 요소를 제공합니다.

샤드 키 선택에 대한 일반적인 지침은 샤드 키 선택을 참조하십시오.

배포는 두 개의 데이터 센터 alfabravo 로 구성됩니다. 두 개의 샤드, shard0000shard0001 가 있습니다. 각 샤드는 세 명의 멤버로 구성된 복제본 세트 입니다. shard0000 의 에는 두 개의 멤버가 alfa 있고 에는 하나의 우선순위 0 멤버bravo 있습니다. shard0001bravo 에 두 개의 멤버가 있고 alfa우선순위 0 멤버 가 한 개 있습니다.

고가용성을 위한 샤드 cluster 아키텍처 다이어그램

이 애플리케이션에는 데이터 센터당 하나의 태그가 필요합니다. 각 샤드에는 대부분의 복제본 세트 구성원을 포함하는 데이터 센터를 기반으로 하나의 태그가 할당되어 있습니다. 각 데이터 센터마다 하나씩 두 가지 태그 범위가 있습니다.

alfa 데이터 센터

이 데이터 센터에서 대다수의 구성원을 가진 샤드에 alfa 으로 태그를 지정합니다.

다음을 사용하여 태그 범위를 생성합니다.

  • { "datacenter" : "alfa", "userid" : MinKey } 의 하한값,

  • { "datacenter" : "alfa", "userid" : MaxKey } 의 상한선,

  • 태그 alfa

bravo 데이터 센터

이 데이터 센터에서 대다수의 구성원을 가진 샤드에 bravo 으로 태그를 지정합니다.

다음을 사용하여 태그 범위를 생성합니다.

  • { "datacenter" : "bravo", "userid" : MinKey } 의 하한값,

  • { "datacenter" : "bravo", "userid" : MaxKey } 의 상한선,

  • 태그 bravo

참고

MinKeyMaxKey 값은 비교를 위해 예약된 특수 값입니다.

구성된 태그 및 태그 범위를 기반으로 mongosdatacenter : alfa 이 있는 문서를 alfa 데이터 센터로 라우팅하고 datacenter : bravo 이 있는 문서를 bravo 데이터 센터로 라우팅합니다.

삽입되거나 업데이트된 문서가 구성된 태그 범위와 일치하는 경우 관련 태그가 있는 샤드에만 쓸 수 있습니다.

MongoDB는 구성된 태그 범위와 일치하지 않는 문서를 cluster의 샤드에 작성할 수 있습니다.

참고

위에서 설명한 동작을 위해서는 클러스터가 구성된 태그 범위를 위반하는 청크가 없는 정상 상태여야 합니다. 자세한 내용은 밸런서 에 대한 다음 섹션을 참조하세요.

밸런서 는 태그가 지정된 청크를 적절한 샤드 로 마이그레이션 합니다. 마이그레이션이 완료될 때까지 샤드에는 구성된 태그 범위 및 태그를 위반하는 청크가 포함될 수 있습니다. 밸런싱이 완료되면 샤드에는 범위가 할당된 태그 및 태그 범위를 위반하지 않는 청크만 포함되어야 합니다.

태그 또는 태그 범위를 추가하거나 제거하면 청크 마이그레이션이 발생할 수 있습니다. 데이터 세트의 크기와 태그 범위가 영향을 미치는 청크의 수에 따라 이러한 마이그레이션은 클러스터 성능에 영향을 미칠 수 있습니다. 특정 예약 Windows 동안 밸런서 를 실행하는 것이 좋습니다. 스케줄링 기간을 설정하는 방법에 대한 튜토리얼 은 밸런싱 기간 예약을 참조하세요.

기본적으로 애플리케이션은 가장 가까운 데이터 센터에 기록합니다. 로컬 데이터 센터가 다운되거나 해당 데이터 센터에 대한 쓰기가 설정된 기간 내에 승인되지 않으면 애플리케이션은 데이터베이스에 문서를 쓰기를 시도하기 전에 datacenter 필드의 값을 변경하여 사용 가능한 다른 데이터 센터로 전환합니다.

이 애플리케이션은 쓰기 시간 초과를 지원합니다. 애플리케이션은 쓰기 고려 (write concern) 를 사용하여 각 쓰기 작업에 대한 시간 제한 을 설정합니다.

애플리케이션에 쓰기 또는 시간 초과 오류가 발생하면 각 문서의 datacenter 필드를 수정하고 쓰기를 수행합니다. 이렇게 하면 문서가 다른 데이터 센터로 라우팅됩니다. 두 데이터 센터가 모두 다운되면 쓰기가 성공할 수 없습니다. 쓰기 실패 해결을 참조하세요.

이 애플리케이션은 '다운'으로 표시된 데이터 센터에 대한 연결을 주기적으로 확인합니다. 연결이 복원되면 애플리케이션은 일반 쓰기 작업을 계속 수행할 수 있습니다.

전환 로직과 데이터 센터 간 클라이언트 트래픽을 처리하기 위한 로드 밸런서 또는 유사한 메커니즘을 감안할 때 애플리케이션은 두 데이터 센터 중 특정 문서가 기록된 데이터 센터를 예측할 수 없습니다. 읽기 작업의 일부로 누락된 문서가 없도록 하려면 애플리케이션은 datacenter 필드를 쿼리의 일부로 포함 하지 않음 으로써 브로드캐스트 쿼리 를 수행 해야 합니다.

애플리케이션은 지연 시간을 줄이기 위해 nearest 의 읽기 기본 설정을 사용하여 읽기 를 수행합니다.

보고된 시간 초과 오류에도 불구하고 쓰기 작업이 성공할 수 있습니다. 애플리케이션은 다른 데이터 센터에 문서를 다시 작성하려고 시도하여 오류에 응답하며, 이로 인해 두 데이터 센터에서 문서가 중복될 수 있습니다. 애플리케이션은 읽기 로직의 일부로 중복 항목을 해결합니다.

애플리케이션에는 하나 이상의 쓰기가 실패하거나 설정된 기간 내에 쓰기가 승인 되지 않는 경우 데이터 센터를 전환하는 로직이 있습니다. 애플리케이션은 대상 데이터 센터의 태그 를 기반으로 datacenter 필드를 수정하여 문서를 해당 데이터 센터로 향하게 합니다.

예를 들어 alfa 데이터 센터에 쓰기를 시도하는 애플리케이션은 다음과 같은 일반 절차를 따를 수 있습니다.

  1. datacenter : alfa 을(를) 지정하여 문서 작성을 시도합니다.

  2. 쓰기 시간 초과 또는 오류가 발생하면 alfa 를 일시적으로 다운된 것으로 로그합니다.

  3. datacenter : bravo 을(를) 수정하여 동일한 문서를 작성하려고 시도합니다.

  4. 쓰기 시간 초과 또는 오류가 발생하면 bravo 를 일시적으로 다운된 것으로 로그합니다.

  5. alfabravo 모두 다운된 경우 오류를 기록하고 보고합니다.

쓰기 실패 해결을 참조하세요.

계속 mongos 진행하려면 대상 샤드 cluster 와 연결된 에 연결되어 있어야 합니다. 샤드 복제본 세트 멤버에 직접 연결하여 태그를 생성할 수 없습니다.

1

alfa 태그를 사용하여 alfa 데이터 센터의 각 샤드에 태그를 지정합니다.

sh.addShardTag("shard0000", "alfa")

bravo 태그를 사용하여 bravo 데이터 센터의 각 샤드에 태그를 지정합니다.

sh.addShardTag("shard0001", "bravo")

sh.status() 를 실행하여 특정 샤드에 할당된 태그를 검토할 수 있습니다.

2

alfa 데이터베이스의 범위를 정의하고 sh.addTagRange() 메서드를 사용하여 이를 alfa 태그에 연결합니다. 이 메서드에는 다음이 필요합니다.

  • collection의 전체 네임스페이스입니다.

  • 범위의 포괄적인 하한입니다.

  • 범위의 배타적 상한선입니다.

  • 태그의 이름입니다.

sh.addTagRange(
"<database>.<collection>",
{ "datacenter" : "alfa", "userid" : MinKey },
{ "datacenter" : "alfa", "userid" : MaxKey },
"alfa"
)

bravo 데이터베이스의 범위를 정의하고 sh.addTagRange() 메서드를 사용하여 이를 bravo 태그에 연결합니다. 이 메서드에는 다음이 필요합니다.

  • collection의 전체 네임스페이스입니다.

  • 범위의 포괄적인 하한입니다.

  • 범위의 배타적 상한선입니다.

  • 태그의 이름입니다.

sh.addTagRange(
"<database>.<collection>",
{ "datacenter" : "bravo", "userid" : MinKey },
{ "datacenter" : "bravo", "userid" : MaxKey },
"bravo"
)

MinKeyMaxKey 값은 비교를 위해 예약된 특수 값입니다. MinKey 은 항상 다른 모든 가능한 값보다 작게 비교되는 반면, MaxKey 는 항상 다른 모든 가능한 값보다 크게 비교됩니다. 구성된 범위는 각 datacenter 에 대한 모든 사용자를 캡처합니다.

3

다음에 밸런서 가 실행되면 구성된 구역과 관련하여 샤드 전체에 데이터를 마이그레이션 합니다.

밸런싱이 완료되면 alfa 태그가 지정된 샤드에는 datacenter : alfa 이 있는 문서만 포함해야 하고, bravo 태그가 지정된 샤드에는 datacenter : bravo 이 있는 문서만 포함해야 합니다.

sh.status() 을(를) 실행하여 청크 분포를 검토할 수 있습니다.

애플리케이션의 기본 데이터 센터가 다운되거나 액세스할 수 없는 경우 애플리케이션은 datacenter 필드를 다른 데이터 센터로 변경합니다.

예를 들어, 애플리케이션은 기본적으로 alfa 데이터 센터에 다음 문서를 쓰려고 시도합니다.

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620,
"datacenter" : "alfa",
"userid" : 123,
...
}

애플리케이션이 쓰기 시도 시 오류를 수신하거나 쓰기 확인에 너무 오래 걸리는 경우 애플리케이션은 데이터 센터를 사용할 수 없는 것으로 로그하고 bravo 데이터 센터를 가리키도록 datacenter 필드를 변경합니다.

{
"_id" : ObjectId("56f08c457fe58b2e96f595fb"),
"message_id" : 329620,
"datacenter" : "bravo",
"userid" : 123,
...
}

애플리케이션이 주기적으로 alfa 데이터 센터의 연결을 확인합니다. 데이터 센터에 다시 연결할 수 있으면 애플리케이션은 정상적인 쓰기를 재개할 수 있습니다.

참고

특히 오류가 시간 초과 와 관련된 경우 datacenter : alfa 에 대한 원래 쓰기가 성공했을 수 있습니다. 이 경우 message_id : 329620 이 있는 문서가 두 데이터 센터 모두에서 중복될 수 있습니다. 애플리케이션은 읽기 작업의 일부로 중복 항목을 해결해야 합니다.

애플리케이션의 전환 로직으로 인해 잠재적인 문서 중복이 발생할 수 있습니다. 애플리케이션은 읽기를 수행할 때 애플리케이션 계층에서 모든 중복 문서를 확인합니다.

다음 쿼리는 userid123 인 문서를 검색합니다. 참고로 userid 은(는) 샤드 키의 일부이지만 쿼리에는 datacenter 필드가 포함되어 있지 않으므로 대상 읽기 작업을 수행하지 않습니다.

db.collection.find( { "userid" : 123 } )

결과는 329620message_id 가 있는 문서가 쓰기 승인이 지연된 결과로 MongoDB에 두 번 삽입되었음을 보여줍니다.

{
"_id" : ObjectId("56f08c447fe58b2e96f595fa"),
"message_id" : 329620
"datacenter" : "alfa",
"userid" : 123,
data : {...}
}
{
"_id" : ObjectId("56f08c457fe58b2e96f595fb"),
"message_id" : 329620
"datacenter" : "bravo",
"userid" : 123,
...
}

애플리케이션은 중복 문서를 무시하여 두 문서 중 하나를 선택하거나, 문서가 하나만 남을 때까지 중복 문서를 잘라내려고 할 수 있습니다.

중복 항목을 트리밍하는 한 가지 방법은 ObjectId.getTimestamp() 메서드를 사용하여 _id 필드에서 타임스탬프를 추출하는 것입니다. 그러면 애플리케이션은 삽입된 첫 번째 문서나 마지막으로 삽입된 문서를 유지할 수 있습니다. 여기서는 _id 필드가 MongoDB ObjectId() 을 사용한다고 가정합니다.

예를 들어 ObjectId("56f08c447fe58b2e96f595fa") 가 있는 문서에서 getTimestamp() 를 사용하면 다음이 반환됩니다.

ISODate("2016-03-22T00:05:24Z")

ObjectId("56f08c457fe58b2e96f595fb") 가 있는 문서에서 getTimestamp() 를 사용하면 다음이 반환됩니다.

ISODate("2016-03-22T00:05:25Z")
← 애플리케이션 또는 고객별로 데이터 세분화

이 페이지의 내용