최신 애플리케이션은 수많은 마이크로서비스의 집합으로 구현됩니다. 이러한 각 마이크로서비스는 다른 많은 마이크로서비스와 독립적으로 실행될 수 있습니다. 이러한 애플리케이션은 기본 데이터베이스가 멀티테넌시를 지원할 것으로 기대합니다. Couchbase Server 7.0은 다음과 같은 기능을 도입했습니다. 범위 및 컬렉션 멀티 테넌시를 지원하고 간편한 데이터 모델링 를 사용할 수 있습니다. 범위와 컬렉션은 사용자에게 버킷 내의 데이터를 논리적으로 분리할 수 있는 기능을 제공합니다.
이제 애플리케이션의 각 마이크로서비스는 해당 마이크로서비스에 필요한 글로벌 보조 인덱스를 독립적으로 생성할 수 있습니다. 이전 버전의 Couchbase Server에서는 클러스터에서 하나의 인덱스 생성 요청만 허용되었습니다. 멀티 테넌시에 대한 지원을 강화하기 위해, Couchbase Server 7.0에서는 여러 개의 동시 인덱스 생성 요청을 허용하도록 인덱스 생성 워크플로우가 개선되었습니다. 이 블로그에서는 다음 사항에 대해 설명합니다. 여러 인덱스를 동시에 생성하는 사용자 환경이 어떻게 개선되었는지 알아보세요.
개선된 인덱스 생성 워크플로
먼저 Couchbase 클러스터의 인덱스 생성 워크플로우를 이해해 보겠습니다. 색인 생성 는 (1) 인덱스 메타데이터 생성 및 (2) 인덱스 빌드의 두 단계로 진행됩니다. 첫 번째 단계에서 Couchbase 인덱스 서비스는 다음과 같은 도움을 받아 새 인덱스에 대해 가능한 최상의 배치를 결정합니다. 인덱스 플래너로 설정되며 인덱스 메타데이터는 유지됩니다. 두 번째 단계에서는 첫 번째 단계에서 결정된 호스트 노드가 '인덱스 빌드'를 위해 데이터 서비스와 함께 스트림을 시작합니다. 사용자는 defer_build 플래그를 사용하여 인덱스 생성 중에 첫 번째 단계만 실행하고 나중에 두 번째 단계를 트리거할 수 있습니다. 색인 작성 명령을 사용합니다.
다음 섹션에서는 다음과 같은 의미에 대해 설명합니다. 인덱스 생성 는 첫 번째 단계로만 제한됩니다.
최상의 인덱스 배치를 달성하려면 한 번에 하나의 인덱스 플래너 인스턴스만 실행해야 합니다. 따라서 이전 버전의 카우치베이스 서버를 실행하는 인덱스 서비스는 진행 중인 인덱스 생성 요청이 있는 경우 새로 들어오는 모든 인덱스 생성 요청을 거부합니다.
이 동작은 인덱스 서비스가 인덱스 생성이 진행 중이더라도 들어오는 모든 인덱스 생성 요청을 수락하는 Couchbase Server 7.0에서 개선되었습니다. 인덱스 서비스는 인덱스 생성 요청을 큐에 대기시키고, 백그라운드에서 대기 중인 요청을 처리하며, 인덱스가 생성된 후에만 호출자에게 응답을 반환합니다.
인덱스 생성은 Couchbase Server 7.0 이전에는 차단 요청이었으며 새 릴리스에서도 차단 요청으로 유지된다는 점에 유의하세요.
사용자는 아래 스크린샷과 같이 웹 UI를 통해 백그라운드 생성을 위해 대기 중인 인덱스를 모니터링할 수 있습니다. 인덱스 상태 는 생성 예정.
사용자는 아래 스크린샷과 같이 N1QL을 사용하여 프로그래밍 방식으로 인덱스 상태를 모니터링할 수도 있습니다.
향상된 사용자 경험
이전 릴리즈에서는 생성 중인 다른 인덱스가 있을 때 사용자가 인덱스 생성을 다시 시도해야 했습니다. 인덱스 생성이 프로그래밍 방식으로 이루어지는 경우, 프로그램에는 재시도 메커니즘이 필요합니다. Couchbase 서버 7.0에서는 인덱스 서비스가 백그라운드에서 필요한 재시도를 수행하므로 사용자 프로그램은 인덱스 생성 중에 재시도 메커니즘에 의존할 필요가 없습니다. 인덱스 서비스는 단순히 "단순 재시도"만 수행하는 것이 아닙니다. 요청의 타임스탬프에 따라 요청의 우선순위를 내부적으로 지정하므로 인덱스 생성 요청의 수렴이 더 빠르고 훨씬 더 안정적으로 이루어집니다.
인덱스 서비스는 전 세계적으로 분산된 잠금 메커니즘의 도움을 받아 클러스터에서 인덱스 생성을 직렬화합니다. 따라서 인덱스 생성을 위해서는 모든 인덱스 서비스 노드가 합의에 도달해야만 인덱스 생성을 허용할 수 있습니다.
이제 다음 시나리오/예시를 통해 인덱스 서비스의 개입으로 컨버전스가 어떻게 개선되는지 살펴보겠습니다.
두 개의 사용자 애플리케이션(또는 마이크로서비스)이 동시에 인덱스를 생성하려고 한다고 가정해 보겠습니다. 두 애플리케이션은 인덱스 생성을 위해 서로 다른 두 개의 쿼리 서비스 노드에 연결할 수 있습니다. 쿼리 서비스 노드는 인덱스 서비스 클라이언트를 실행하여 전 세계적으로 분산된 잠금을 획득하고 인덱스 플래너를 실행하여 인덱스 배치를 결정합니다.
7.0 이전 버전의 카우치베이스에서 인덱스 생성 타임라인
아래 다이어그램에 표시된 것처럼 클러스터에서 발생하는 이벤트의 가능한 타임라인 중 하나를 고려해 보겠습니다(카우치베이스 서버 버전이 7.0 미만인 경우).
타임라인:
T0: 두 애플리케이션이 동시에 인덱스 생성 요청을 트리거하고 인덱스 서비스 클라이언트가 요청을 수신합니다.
T1: 인덱스 서비스 클라이언트 1은 잠금 인덱스 노드 1에 요청합니다. 인덱스 노드 1 수락 요청을 처리합니다.
T2: 인덱스 서비스 클라이언트 2는 잠금 인덱스 노드 2에 요청합니다. 인덱스 노드 2 수락 요청을 처리합니다.
T3: 인덱스 서비스 클라이언트 1은 잠금 인덱스 노드 2에 요청합니다. 인덱스 노드 2 거부 클라이언트 2의 요청을 이미 수락했기 때문에 요청을 수락하지 않습니다.
T4: 인덱스 서비스 클라이언트 2는 잠금 인덱스 노드 1에 요청합니다. 인덱스 노드 1 거부 클라이언트 1의 요청을 이미 수락했기 때문에 요청을 수락하지 않습니다.
이 예제에서 Couchbase Server 버전 7.0 미만에서는 두 요청 모두 Couchbase에 의해 거부되고 사용자 스크립트가 다시 시도해야 합니다. 사용자 스크립트가 즉시 또는 결정적 백오프 기간 후에 재시도하는 경우 다음 시도에서도 유사한 시나리오/타임라인이 발생할 수 있으며 다음 시도에서도 두 요청이 모두 거부될 수 있습니다.
Couchbase 7.0을 사용한 인덱스 생성 큐잉
카우치베이스 서버 7.0에서는 개선된 동작과 예제와 유사한 타임라인이 아래 다이어그램에 나와 있습니다. 사용자 애플리케이션 스레드는 여전히 인덱스 생성이 완료되기를 기다리는 동안 인덱스 생성의 책임은 백그라운드 인덱스 생성자가 이어받습니다. 사용자 스레드는 인덱스가 생성될 때만 응답을 받습니다.
타임라인:
T0: 두 개의 백그라운드 인덱스 생성자 스레드가 동시에 인덱스 생성을 트리거하고 인덱스 서비스 클라이언트에서 요청을 수신합니다.
T1: 인덱스 서비스 클라이언트 1은 잠금 요청(우선순위 P1)을 인덱스 노드 1로 전송합니다. 인덱스 노드 1 수락 요청을 처리합니다.
T2: 인덱스 서비스 클라이언트 2는 잠금 요청(우선순위 P2)을 인덱스 노드 2로 전송합니다. 인덱스 노드 2 수락 요청을 처리합니다.
T3: 인덱스 서비스 클라이언트 1은 잠금 요청(우선순위 P1)을 인덱스 노드 2로 전송합니다. 인덱스 노드 2 수락 이전에 수락된 요청보다 우선순위가 높으므로 요청을 수락합니다.
T4: 인덱스 서비스 클라이언트 2는 잠금 요청(우선순위 P2)을 인덱스 노드 1에 보냅니다. 인덱스 노드 1 거부 이미 클라이언트 2의 요청을 더 높은 우선순위로 수락했기 때문에 요청을 수락하지 않습니다.
분산 잠금 메커니즘은 2단계 커밋 프로토콜 를 설정하여 인덱스 노드 2에서 이전에 수락된 요청(우선순위 P2)이 커밋 단계에서 실패하고 백그라운드 인덱스 생성자가 다시 시도하도록 합니다.
또한 요청 우선순위는 나노초 단위로 생성된 요청 타임스탬프를 기반으로 한다는 점에 유의하세요. 이렇게 하면 대부분의 분산 잠금 경합이 제거됩니다. 그러나 두 요청의 요청 타임스탬프가 정확히 동일한 코너 케이스가 발생할 가능성이 있습니다. 이 경우를 처리하기 위해 인덱스 서비스는 무작위 백오프를 사용해 분산 잠금 경합을 더욱 줄입니다.