분류

카우치베이스 자바 SDK 내부

[이 블로그는 http://nitschinger.at/ 에서 신디케이트되었습니다.]

동기 부여

이 블로그 게시물은 이미 Couchbase Java SDK를 사용해 본 적이 있고 내부가 어떻게 작동하는지 알고 싶은 분들을 위한 매우 상세하고 유익한 글입니다. 이 글은 Java SDK를 사용하는 방법에 대한 소개가 아니며, 앞으로 상당히 고급적인 주제를 다룰 것입니다.

일반적으로 SDK에 대해 이야기할 때는 클라이언트 라이브러리, 문서, 릴리스 노트 등 개발에 필요한 모든 것을 의미합니다. 하지만 이 글에서 SDK는 달리 명시되지 않는 한 클라이언트 라이브러리(코드)를 의미합니다.

소개

무엇보다도 SDK는 다음과 같은 기능을 래핑하고 확장한다는 점을 이해하는 것이 중요합니다. 스파이멤캐시 ("스파이"라고 함) 멤캐시드 라이브러리를 사용합니다. 내부적으로 사용되는 프로토콜 중 하나는 멤캐시드 프로토콜이며, 많은 기능을 재사용할 수 있습니다. 반면에 SDK의 첫 번째 레이어를 벗겨내기 시작하면 스파이가 애초에 SDK에 필요한 것보다 더 많은 기능을 제공하기 때문에 일부 구성 요소가 다소 더 복잡하다는 것을 알 수 있습니다. 또 다른 부분은 많은 구성 요소가 서로 얽혀 있으므로 항상 종속성을 올바르게 파악해야 한다는 점을 기억해야 한다는 것입니다. 대부분의 경우 새로운 기능이 추가되거나 수정되었기 때문에 새 SDK와 같은 날짜에 새 스파이 버전을 출시합니다.

따라서 spy에서 제공하는 기능을 재사용하는 것 외에도 SDK는 주로 자동 클러스터 토폴로지 관리와 1.1(및 2.0 서버) 이후 뷰 지원이라는 두 가지 기능 블록을 추가합니다. 그 외에도 버킷 및 디자인 문서 관리와 같은 관리 기능도 제공합니다.
클라이언트의 작동 방식을 이해하기 위해 클라이언트의 다양한 수명 주기 단계에 따라 전체 프로세스를 분석해 보겠습니다. 세 단계(부트스트랩, 운영, 종료)를 모두 거치고 나면 내부에서 어떤 일이 벌어지고 있는지 명확하게 파악할 수 있을 것입니다. 오류 처리에 대해서는 별도의 블로그 포스팅이 준비 중이므로 여기서는 자세히 다루지 않겠습니다(몇 주 후에 같은 블로그에 게시될 예정입니다).

1단계: 부트스트랩

실제로 다음과 같은 작업을 시작하기 전에 get() 그리고 set()를 부트스트랩해야 합니다. 카우치베이스클라이언트 객체를 생성합니다. 여기서 수행해야 할 중요한 부분은 처음에 클러스터 구성(노드와 vBucket 맵이 포함된)을 가져오는 것뿐만 아니라 (거의) 실시간으로 클러스터 업데이트를 받기 위한 스트리밍 연결도 설정하는 것입니다.

부트스트랩 중에 통과하는 노드 목록을 가져와서 반복합니다. 목록에서 포트 8091로 연결할 수 있는 첫 번째 노드는 서버에서 RESTful 인터페이스를 걸어가는 데 사용됩니다. 사용할 수 없는 경우 다음 노드가 시도됩니다. 즉, 제공된 http://host:port/pools URI를 클릭하면 결국 버킷 엔티티로 연결되는 링크를 따라갑니다. 이 모든 일은 구성 공급자(이 경우 com.couchbase.client.vbucket.ConfigurationProviderHTTP. 내부를 자세히 살펴보고 싶으시면 getBucketConfiguration 그리고 readPools 메서드.
(성공적인) 걷기는 다음과 같이 설명할 수 있습니다:
  1. GET /pools
  2. "기본" 풀을 찾습니다.
  3. GET /pools/default
  4. 버킷 목록이 포함된 "buckets" 해시를 찾습니다.
  5. GET /pools/default/buckets
  6. 버킷 목록을 구문 분석하고 애플리케이션에서 제공한 버킷을 추출합니다.
  7. GET /pools/default/buckets/

이제 필요한 REST 엔드포인트에 도달했습니다. 이 JSON 응답 안에는 SDK 내부적으로도 사용되는 모든 유용한 세부 정보가 있습니다(예를 들어 스트리밍우리노드 및 vBucketServerMap). 구성이 구문 분석되고 저장됩니다. 계속 진행하기 전에 REST 워크의 이상한 풀 부분에 대해 간단히 살펴보겠습니다:

버킷을 그룹화하는 리소스 풀의 개념은 Couchbase Server용으로 설계되었지만 현재 구현되어 있지 않습니다. 하지만 REST API는 이러한 방식으로 구현되어 있으므로 모든 SDK에서 이를 지원합니다. 즉, 이론적으로는 직접 리소스 풀의 /pools/default/버킷 로 설정하고 처음 몇 개의 쿼리를 건너뛰면 현재 동작은 미래에 대비한 것이므로 서버가 구현한 후에는 부트스트랩 코드를 변경할 필요가 없습니다.
부트스트랩 단계로 돌아갑니다. 이제 모든 노드(및 호스트 이름 또는 IP 주소)가 포함된 유효한 클러스터 구성이 있으므로 노드에 대한 연결을 설정할 수 있습니다. 데이터 연결을 설정하는 것 외에도 데이터 연결 중 하나에 대한 스트리밍 연결을 인스턴스화해야 합니다. 간단하게 하기 위해 초기 구성을 한 목록에서 노드에 대한 스트리밍 연결을 설정하기만 하면 됩니다.
여기서 명심해야 할 중요한 점이 있습니다. 카우치베이스클라이언트 객체가 여러 노드에서 실행되고 모두 동일한 목록으로 부트스트랩되는 경우 스트리밍 연결을 위해 동일한 노드에 연결하게 되어 병목 현상이 발생할 수 있습니다. 따라서 부하를 조금 더 잘 분산하려면 배열을 셔플하여 카우치베이스클라이언트 객체를 추가합니다. 몇 개만 있는 경우 카우치베이스클라이언트 개체가 클러스터에 연결되어 있어도 전혀 문제가 되지 않습니다.
스트리밍 연결 URI는 이전에 받은 설정에서 가져온 것으로, 일반적으로 다음과 같습니다:
streamingUri: "/pools/default/bucketsStreaming/default?bucket_uuid=88cae4a609eea500d8ad072fe71a7290"
브라우저에서 이 주소를 가리키면 클러스터 토폴로지 업데이트도 실시간으로 스트리밍됩니다. 스트리밍 연결은 항상 설정되어야 하고 잠재적으로 스레드를 차단할 수 있으므로 이 작업은 다른 스레드에서 처리하는 백그라운드에서 수행됩니다. 이 작업에는 비동기 작업을 처리하는 매우 편리한 방법을 제공하는 NIO 프레임워크 Netty를 사용하고 있습니다. 이 부분을 자세히 살펴보고 싶다면 모든 읽기 작업은 쓰기 작업과 완전히 분리되어 있으므로 서버에서 돌아오는 내용을 처리하는 핸들러를 처리해야 한다는 점을 명심하세요. Netty에 필요한 일부 배선을 제외하고 비즈니스 로직은 com.couchbase.client.vbucket.BucketMonitor 및 com.couchbase.client.vbucket.BucketUpdateResponseHandler에서 찾을 수 있습니다. 또한 소켓이 닫히는 경우(예: 이 노드가 클러스터에서 재조정되는 경우) 이 스트리밍 연결을 다시 설정하려고 시도합니다.
실제로 클러스터 노드에 데이터를 셔플하려면 다양한 소켓을 클러스터 노드에 열어야 합니다. 모든 소켓을 사전 예방적으로 관리하기 때문에 클라이언트 내부에서는 연결 풀링이 전혀 필요하지 않습니다. 서버 중 하나에 대한 특수 스트리밍 연결(포트 8091에 대해 열림)을 제외하고 다음 연결을 열어야 합니다:
  1. 멤캐시드 소켓: 포트 11210
  2. 소켓 보기: 포트 8092

포트 11211은 클라이언트 SDK 내부에서 사용되는 것이 아니라 클러스터를 인식하지 못하는 일반 멤캐시드 클라이언트를 연결하는 데 사용된다는 점에 유의하세요. 즉, 이러한 일반 클라이언트는 클러스터 토폴로지를 업데이트하지 않습니다.

따라서 경험상 10개의 노드 클러스터가 실행 중인 경우 하나의 CouchbaseClient 객체는 약 21개(2*10 + 1)의 클라이언트 소켓을 열게 됩니다. 이는 직접 관리되므로 노드가 제거되거나 추가되면 그에 따라 숫자가 변경됩니다.
이제 모든 소켓이 열렸으므로 일반 클러스터 작업을 수행할 준비가 되었습니다. 보시다시피, CouchbaseClient 객체가 부트스트랩될 때 많은 오버헤드가 발생합니다. 따라서 요청이 있을 때마다 새 객체를 생성하거나 하나의 애플리케이션 서버에서 많은 CouchbaseClient 객체를 실행하는 것은 권장하지 않습니다. 이렇게 하면 애플리케이션 서버에 불필요한 오버헤드와 부하가 추가되고 클러스터에 대해 열린 총 소켓이 늘어날 뿐입니다(성능 문제가 발생할 수 있음).
참고로, 일반 정보 수준 로깅이 활성화된 상태에서 1노드 클러스터(Couchbase 버킷)에 연결 및 연결 해제는 다음과 같은 모습입니다:
Apr 17, 2013 3:14:49 PM com.couchbase.client.CouchbaseProperties setPropertyFile
INFO: 속성 파일 "cbclient.properties"를 로드할 수 없습니다: 시스템 클래스 로더에서 파일을 찾을 수 없습니다.
2013-04-17 15:14:49.656 INFO com.couchbase.client.CouchbaseConnection: 큐 연결에 {QA sa=/127.0.0.1:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} 추가했습니다.
2013-04-17 15:14:49.673 INFO com.couchbase.client.CouchbaseConnection: sun.nio.ch.SelectionKeyImpl@2adb1d4에 대한 연결 상태가 변경되었습니다.
2013-04-17 15:14:49.718 INFO com.couchbase.client.ViewConnection: 연결 대기열에 localhost를 추가했습니다.
2013-04-17 15:14:49.720 INFO com.couchbase.client.CouchbaseClient: viewmode 속성이 정의되지 않았습니다. 뷰모드를 프로덕션 모드로 설정
2013-04-17 15:14:49.856 INFO com.couchbase.client.CouchbaseConnection: 카우치베이스 클라이언트를 종료합니다.
2013-04-17 15:14:49.861 INFO com.couchbase.client.ViewConnection: 노드 localhost에 큐에 작업이 없습니다.
2013-04-17 15:14:49.861 INFO com.couchbase.client.ViewNode: 로컬 호스트에 대한 I/O 리액터가 종료되었습니다.
Couchbase Server 1.8에 연결하거나 Memcache-Bucket에 연결하는 경우 보기 연결이 설정되는 것을 볼 수 없습니다:
INFO: 속성 파일 "cbclient.properties"를 로드할 수 없습니다: 시스템 클래스 로더에서 파일을 찾을 수 없습니다.
2013-04-17 15:16:44.295 INFO com.couchbase.client.CouchbaseConnection: 큐 연결에 {QA sa=/192.168.56.101:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0}를 추가했습니다.
2013-04-17 15:16:44.297 INFO com.couchbase.client.CouchbaseConnection: 큐 연결에 {QA sa=/192.168.56.102:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0}를 추가했습니다.
2013-04-17 15:16:44.298 INFO com.couchbase.client.CouchbaseConnection: 큐 연결에 {QA sa=/192.168.56.103:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0}를 추가했습니다.
2013-04-17 15:16:44.298 INFO com.couchbase.client.CouchbaseConnection: 큐 연결에 {QA sa=/192.168.56.104:11210, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0}를 추가했습니다.
2013-04-17 15:16:44.306 INFO com.couchbase.client.CouchbaseConnection: sun.nio.ch.SelectionKeyImpl@38b5dac4에 대한 연결 상태가 변경되었습니다.
2013-04-17 15:16:44.313 INFO com.couchbase.client.CouchbaseClient: viewmode 속성이 정의되지 않았습니다. 뷰모드를 프로덕션 모드로 설정
2013-04-17 15:16:44.332 INFO com.couchbase.client.CouchbaseConnection: sun.nio.ch.SelectionKeyImpl@69945ce에 대한 연결 상태가 변경되었습니다.
2013-04-17 15:16:44.333 INFO com.couchbase.client.CouchbaseConnection: sun.nio.ch.SelectionKeyImpl@6766afb3에 대한 연결 상태가 변경되었습니다.
2013-04-17 15:16:44.334 INFO com.couchbase.client.CouchbaseConnection: sun.nio.ch.SelectionKeyImpl@2b2d96f2에 대한 연결 상태가 변경되었습니다.
2013-04-17 15:16:44.368 INFO net.spy.memcached.auth.AuthThread: 192.168.56.103/192.168.56.103:11210으로 인증됨
2013-04-17 15:16:44.368 INFO net.spy.memcached.auth.AuthThread: 192.168.56.102/192.168.56.102:11210으로 인증됨
2013-04-17 15:16:44.369 INFO net.spy.memcached.auth.AuthThread: 192.168.56.101/192.168.56.101:11210으로 인증됨
2013-04-17 15:16:44.369 INFO net.spy.memcached.auth.AuthThread: 192.168.56.104/192.168.56.104:11210으로 인증됨
2013-04-17 15:16:44.490 INFO com.couchbase.client.CouchbaseConnection: 카우치베이스 클라이언트를 종료합니다.

2단계: 운영
SDK가 부트스트랩되면 애플리케이션이 연결된 클러스터에 대해 작업을 실행할 수 있습니다. 이 블로그 게시물의 목적상, 안정적인 클러스터에 대해 실행되는 작업과 현재 어떤 형태의 토폴로지 변경(노드 추가 등으로 인해 계획된 것이든 노드 장애로 인해 계획되지 않은 것이든)이 발생하고 있는 클러스터에 대한 작업을 구분할 필요가 있습니다. 먼저 일반 작업에 대해 살펴보겠습니다.

안정적인 클러스터에 대한 작업

처음부터 직접 보이지는 않지만 SDK 내부에서는 멤캐시된 연산과 보기 연산을 구분해야 합니다. 메서드 시그니처에 고유 키가 있는 모든 연산은 멤캐시드 연산으로 간주할 수 있습니다. 이 모든 연산은 결국 스파이를 통해 퍼널링됩니다. 반면에 보기 연산은 SDK 자체 내에서 완전히 구현됩니다.
보기와 멤캐시드 작업은 모두 비동기식입니다. 스파이 내부에는 IO 작업을 처리하는 전용 스레드(I/O 스레드라고 함)가 하나 있습니다. 트래픽이 많은 환경에서는 이 스레드가 항상 활성화되어 있는 경우가 많습니다. 이 스레드는 비차단 Java NIO 메커니즘을 사용해 트래픽을 처리하고, 데이터를 쓰거나 읽을 수 있을 때 알림을 받는 '선택기'를 중심으로 루프를 수행합니다. 애플리케이션을 프로파일링하면 이 스레드가 대부분의 시간을 선택 메서드에서 대기하는 것을 볼 수 있는데, 이는 새로운 트래픽에 대한 알림을 기다리며 유휴 상태임을 의미합니다. 이를 처리하기 위해 스파이 내부에서 사용되는 개념은 일반적인 Java NIO 지식이므로, 이 문제를 해결하기 위해 NIO 내부 를 먼저 살펴본 후 코드 경로를 파헤치세요. 좋은 출발점은 net.spy.memcached.MemcachedConnection 그리고 net.spy.memcached.protocol.TCPMemcachedNodeImpl 클래스를 추가합니다. SDK 내부에서는 자체 재구성 로직에 연결하기 위해 MemcachedConnection을 재정의합니다. 이 클래스는 SDK 내부의 다음 위치에서 찾을 수 있습니다. com.couchbase.client.CouchbaseConnection 의 멤캐시드형 버킷의 경우 com.couchbase.client.CouchbaseMemcachedConnection.
따라서 멤캐시된 연산(예 get())가 발행되면 IO 스레드에 도달할 때까지 전달됩니다. 그러면 IO 스레드는 이를 대상 노드로 향하는 쓰기 대기열에 넣습니다. 결국 쓰기가 완료되면 IO 스레드가 읽기 대기열에 정보를 추가하여 응답을 적절히 매핑할 수 있도록 합니다. 이 접근 방식은 퓨처를 기반으로 하므로 결과가 실제로 도착하면 퓨처가 완료된 것으로 표시되고 결과가 파싱되어 Object로 첨부됩니다.
SDK는 멤캐시드 바이너리 프로토콜만 사용하지만, 스파이에서는 ASCII도 지원합니다. 바이너리 형식이 훨씬 더 효율적이며 일부 고급 작업은 이 형식에서만 구현됩니다.
SDK가 작업을 어디로 보낼지 어떻게 알 수 있는지 궁금하실 것입니다. 이미 최신 클러스터 맵을 가지고 있으므로 키를 해시한 다음 노드 목록과 vBucketMap을 기반으로 액세스할 노드를 결정할 수 있습니다. vBucketMap에는 배열의 마스터 노드에 대한 정보뿐만 아니라 0~3개의 복제 노드에 대한 정보도 포함되어 있습니다. 이 (단축된) 예시를 보세요:
vBucketServerMap: {
해시알고리즘: "CRC",
numReplicas: 1,
서버리스트: [
“192.168.56.101:11210”,
“192.168.56.102:11210”
],
vBucketMap: [
[0,1],
[0,1],
[0,1],
[1,0],
[1,0],
[1,0]
//…..
},
서버리스트에는 노드가 포함되어 있고, vBucketMap에는 서버리스트 배열에 대한 포인터가 있습니다. 여기에는 1024개의 vBucket이 있으므로 그 중 일부만 표시되어 있습니다. 이를 보면 첫 번째 vBucket에 있는 모든 키는 인덱스 0에 마스터 노드(즉, .101 노드)가 있고 인덱스 1에 복제본(즉, .102 노드)이 있다는 것을 알 수 있습니다. 클러스터 맵이 변경되고 vBucket이 이동하면 구성을 업데이트하고 작업을 가리킬 위치를 항상 알기만 하면 됩니다.
보기 작업은 다르게 처리됩니다. 키 등을 해시하는 방법이 없기 때문에 특정 노드로 뷰를 전송할 수 없으므로 연결된 노드 간에 라운드 로빈을 수행합니다. 연결에 여유가 생기면 작업은 com.couchbase.client.ViewNode에 할당된 다음 실행됩니다. 결과도 퓨처를 통해 처리됩니다. 이 기능을 구현하기 위해 SDK는 타사 Apache HTTP Commons(NIO) 라이브러리를 사용합니다.

전체 보기 API는 모든 노드의 포트 8092 뒤에 숨어 있으며, 다음과 매우 유사합니다. CouchDB. 여기에도 RESTful API가 포함되어 있지만 구조가 약간 다릅니다. 예를 들어 다음 주소에서 디자인 문서에 액세스할 수 있습니다. /_design/. 여기에는 JSON으로 된 보기 정의가 포함되어 있습니다:

{
언어: "자바스크립트",
보기: {
모두: {
map: "function (doc) { if(doc.type == "city") {emit([doc.continent, doc.country, doc.name], 1)}}",
줄입니다: "_sum"
}
}
}
그런 다음 /_design/_view/와 같이 한 단계 더 내려가서 실제로 쿼리할 수 있습니다:
{"total_rows":9,"행":[
{"id":"도시:상하이","key":["아시아","china","상하이"],"value":1},
{"id":"도시:도쿄","key":["아시아","japan","tokyo"],"value":1},
{"id":"도시:모스크바","key":["아시아","러시아","moscow"],"value":1},
{"id":"도시:비엔나","key":["유럽","오스트리아","비엔나"],"value":1},
{"id":"도시:파리","key":["유럽","프랑스","paris"],"value":1},
{"id":"도시:로마","key":["유럽","italy","rome"],"value":1},
{"id":"도시:암스테르담","key":["유럽","netherlands","암스테르담"],"value":1},
{"id":"city:new_york","key":["north_america","usa","new_york"],"value":1},
{"id":"city:san_francisco","key":["north_america","usa","san_francisco"],"value":1}
]
}
요청이 전송되고 응답이 돌아오면 보기 요청 유형에 따라 응답이 구문 분석되는 방식이 결정됩니다. 축소된 뷰 쿼리는 축소되지 않은 뷰 쿼리와 다르게 보이기 때문에 차이가 있습니다. 또한 SDK에는 공간 뷰에 대한 지원도 포함되어 있으므로 공간 뷰도 다르게 처리해야 합니다.
전체 보기 응답 구문 분석 구현은 내부에서 찾을 수 있습니다. com.couchbase.client.protocol.views 네임스페이스로 이동합니다. 여기에는 ViewResponse와 같은 추상 클래스와 인터페이스가 있으며, ViewResponseNoDocs, ViewResponseWithDocs 또는 ViewResponseReduced와 같은 특수 구현도 찾을 수 있습니다. 또한 쿼리 객체에서 setIncludeDocs()를 사용하는 경우 SDK가 백그라운드에서 멤캐시 프로토콜을 사용하여 전체 문서를 로드해야 하므로 상황이 달라집니다. 이 작업은 뷰를 파싱하는 동안에도 수행됩니다.
이제 SDK가 안정적인 조건에서 작업을 배포하는 방법에 대해 기본적으로 이해하셨으니, 이제 중요한 주제인 클러스터 토폴로지 변경을 처리하는 방법에 대해 다뤄야 합니다.

리밸런싱 클러스터에 대한 작업

SDK에 문제가 발생했을 때 발생할 수 있는 모든 시나리오를 다루는 별도의 블로그 포스팅이 곧 게시될 예정입니다. 리밸런싱과 장애 복구는 SDK의 중요한 부분이므로 이 게시물에서는 이를 처리하는 일반적인 프로세스에 대해 자세히 다룹니다.
앞서 언급했듯이 SDK는 스트리밍 연결을 통해 토폴로지 업데이트를 수신합니다. 이 노드가 실제로 제거되거나 실패하는 특별한 경우를 제외하면 모든 업데이트는 거의 실시간으로 스트리밍됩니다(결국 일관된 아키텍처에서는 클러스터 업데이트가 해당 노드로 채워질 때까지 시간이 걸릴 수 있습니다). 스트림을 통해 들어오는 청크는 초기 구성을 읽을 때 보았던 것과 똑같이 보입니다. 이러한 청크를 파싱한 후에는 변경 사항이 실제로 SDK에 영향을 미치는지 확인해야 합니다(SDK에 필요한 매개변수보다 훨씬 더 많은 매개변수가 있으므로 모든 매개변수를 다 듣는 것은 의미가 없습니다). 토폴로지 및/또는 vBucket 맵에 영향을 미치는 모든 변경 사항은 중요한 것으로 간주됩니다. 노드가 추가되거나 제거되는 경우(장애로 인한 것이든 계획된 것이든) 소켓을 열거나 닫아야 합니다. 이 프로세스를 "재구성"이라고 합니다.
이러한 재구성이 트리거되면 여러 곳에서 많은 작업이 수행되어야 합니다. Spymemcached는 소켓을 처리해야 하고, View 노드를 관리해야 하며, 새로운 구성을 업데이트해야 합니다. SDK는 잠금을 통해 동시에 하나의 재구성만 발생할 수 있도록 하여 경쟁 조건이 발생하지 않도록 합니다.
Netty 기반 BucketUpdateResponseHandler는 CouchbaseClient#reconfigure 메서드를 트리거한 다음 모든 것을 디스패치하기 시작합니다. 사용된 버킷 유형에 따라(즉, 멤캐시드 유형 버킷에는 뷰가 없으므로 뷰노드가 없음), 구성이 업데이트되고 소켓이 닫힙니다. 재구성이 완료되면 새로운 구성을 받을 수 있습니다. 계획된 변경 중에는 모든 것이 거의 제어되어야 하며 어떤 작업도 실패해서는 안 됩니다. 노드가 실제로 다운되어 연결할 수 없는 경우 해당 작업은 취소됩니다. 재구성은 작업이 시스템을 통해 흐르는 동안 토폴로지가 변경되기 때문에 까다로운 작업입니다.
마지막으로 카우치베이스와 멤캐시 유형 버킷의 몇 가지 차이점에 대해 알아보겠습니다. 앞서 읽은 모든 정보 모자는 Couchbase 버킷에만 적용됩니다. 멤캐시 버킷은 매우 기본적이며 vBuckets의 개념이 없습니다. vBuckets가 없으므로 클라이언트가 해야 할 일은 노드와 해당 소켓을 관리하는 것뿐입니다. 또한 각 키의 대상 노드를 결정하기 위해 다른 해싱 알고리즘(주로 Ketama)이 사용됩니다. 또한 멤캐시 버킷에는 뷰가 없으므로 뷰 API를 사용할 수 없으며 뷰 소켓을 유지하는 것도 큰 의미가 없습니다. 따라서 앞의 설명을 명확히 하기 위해, 10개의 노드 클러스터에서 멤캐시 버킷에 대해 실행하는 경우 11개의 연결만 열리게 됩니다.

3단계: 종료

CouchbaseClient#shutdown() 메서드가 호출되면 더 이상 CouchbaseConnection에 작업을 추가할 수 없습니다. 시간 초과에 도달할 때까지 클라이언트는 모든 작업이 적절하게 진행되었는지 확인하려고 합니다. 대기열에 더 이상 작업이 없으면(또는 삭제되면) 멤캐시드 연결과 보기 연결의 모든 소켓이 종료됩니다. 이러한 소켓의 종료 방법은 정상 작동 중에 노드가 클러스터에서 제거될 때도 사용되므로 기본적으로 동일하지만 연결된 모든 노드에 대해 동시에 종료된다는 점에 유의하세요.

요약

이 블로그 게시물을 읽고 나면 클라이언트 SDK가 어떻게 작동하는지, 왜 이런 방식으로 설계되었는지 훨씬 더 명확하게 이해하실 수 있을 것입니다. 향후 릴리스에서는 주로 직접 API 환경을 개선하는 등 많은 개선 사항이 계획되어 있습니다. 이 블로그 게시물에서는 SDK 내부에서 오류가 처리되는 방식은 다루지 않았으며, 이 또한 다룰 정보가 많으므로 별도의 블로그 게시물로 게시할 예정입니다.
이 문서 공유하기
받은 편지함에서 카우치베이스 블로그 업데이트 받기
이 필드는 필수 입력 사항입니다.

작성자

게시자 마이클 니칭거

마이클 니칭어는 Couchbase의 수석 소프트웨어 엔지니어로 일하고 있습니다. 그는 JVM에서 최초의 완전 반응형 데이터베이스 드라이버 중 하나인 Couchbase Java SDK의 설계자이자 유지 관리자입니다. 또한 Couchbase Spark Connector를 작성하고 유지 관리하고 있습니다. Michael은 오픈 소스 커뮤니티에서 활발히 활동 중이며, RxJava 및 Netty와 같은 다양한 프로젝트에 기여하고 있습니다.

댓글 남기기

카우치베이스 카펠라를 시작할 준비가 되셨나요?

구축 시작

개발자 포털에서 NoSQL을 살펴보고, 리소스를 찾아보고, 튜토리얼을 시작하세요.

카펠라 무료 사용

클릭 몇 번으로 Couchbase를 직접 체험해 보세요. Capella DBaaS는 가장 쉽고 빠르게 시작할 수 있는 방법입니다.

연락하기

카우치베이스 제품에 대해 자세히 알고 싶으신가요? 저희가 도와드리겠습니다.