때때로 클라이언트 라이브러리의 내부를 더 깊이 파고들기 때문에 문서에 직접적으로 맞지 않는 주제에 대한 질문을 받기도 합니다. 이 시리즈에서는 다양한 관심 주제를 다룰 예정인데, 이번 주제는 SDK 부트스트랩 자체에 관한 것입니다.
이 게시물은 Java SDK 2.5.9 / 2.6.0 릴리스를 염두에 두고 작성되었습니다. 시간이 지남에 따라 상황이 바뀔 수 있지만 전반적인 접근 방식은 거의 동일하게 유지될 것입니다.
첫 번째 단계
일반적으로 어떤 원격 호스트에 설정을 요청할지 알기 위해서는 사용자가 카우치베이스클러스터 API를 제공합니다. 예를 들어 이 코드가 제공된 경우입니다:
|
1 |
카우치베이스클러스터 클러스터 = 카우치베이스클러스터.create("node1", "node2", "node3"); |
그런 다음 node1 , node2 그리고 node3 를 초기 부트스트랩 프로세스의 일부로 설정합니다. 이 시점에서 아직 실제 연결이 설정되지 않았다는 점을 이해하는 것이 중요합니다. 이 코드는 이 세 호스트를 단지 구성 공급자 를 시드 호스트로 사용합니다. 하지만 문자열로 저장되는 것이 아니라 네트워크 주소 각각은 일반 JDK보다 편리하고 더 풍부한 기능을 제공하는 래퍼를 제공합니다. InetAddress . 예를 들어 시스템 속성을 통해 수정하여 역방향 DNS 조회를 허용하지 않거나 JDK가 다르게 구성되어 있어도 IPv6보다 IPv4를 강제로 사용하도록 할 수 있습니다.
호스트가 제공되지 않은 경우, 127.0.0.1 가 시드 호스트로 설정됩니다.
또한 SDK를 사용하는 독자들을 위해 연결 문자열 구성의 경우: Java SDK는 이러한 문자열이 주어지면 구문 분석하지만 부트스트랩 노드 목록 이외의 구성 설정은 사용하지 않습니다. 모든 구성은 반드시 카우치베이스 환경 및 빌더 또는 가능한 경우 시스템 속성을 통해 확인할 수 있습니다.
양동이를 열고 잡초에 들어가기 전에 마지막으로 덮어야 할 것이 하나 더 있습니다. 만약 카우치베이스 환경 로 구성됩니다. dnsSrvEnabled 로 설정하면 클러스터 구성 단계에서 코드가 DNS SRV 조회를 수행하여 DNS SRV 참조 호스트 대신 실제 호스트를 검색합니다. 이 코드는 JVM 클래스를 사용하여 이를 수행하며, 코드는 다음에서 찾을 수 있습니다. 여기.
구성 가져오기
이제 작업할 시드 노드 목록이 생겼으니 버킷이 열리면 곧바로 실제 작업이 시작됩니다. 다음 코드 조각을 시작점으로 고려해 보겠습니다:
|
1 |
버킷 버킷 = 클러스터.오픈버킷("travel-sample"); |
버킷을 여는 작업에는 완료해야 할 작은 단계가 많이 있지만 가장 중요한 첫 번째 단계는 클러스터의 노드 중 하나에서 좋은 초기 구성을 가져오는 것입니다.
그리고 구성 공급자 는 구성 로더의 체인을 구축하며, 각 로더는 구성을 가져오는 메커니즘이 다릅니다. 현재 두 개의 서로 다른 로더가 있습니다:
– 캐리어로더는 KV 서비스에서 멤캐시 바이너리 프로토콜을 통해 구성을 가져오려고 시도합니다(포트
11210 기본값).
– HttpLoader: 클러스터 관리자에서 구성을 가져오려고 시도합니다(포트
8091 기본값).
그리고 캐리어로더 가 확장성이 더 뛰어난 옵션이기 때문에 우선권을 가지며(KV 서비스는 클러스터 관리자보다 초당 훨씬 더 많은 요청을 처리할 수 있음), 이 옵션을 사용할 수 없는 경우 SDK는 HttpLoader . 실패할 수 있는 이유 중 하나는 특정 (이전) Couchbase Server 릴리스가 이 메커니즘을 지원하지 않기 때문입니다. 일반적으로 발생하는 다른 오류로는 포트 11210 방화벽에 의해 차단되거나(어차피 다른 문제로 이어질 수 있습니다...) 소켓이 시간 초과되는 등의 문제가 발생할 수 있습니다.
그리고 HttpLoader 자체에도 (이전 버전과의 호환성을 위해 Couchbase Server 버전에 따라) 가져올 수 있는 두 개의 HTTP 엔드포인트가 있는데, 하나는 간결한 구성을 제공하는 것이고 다른 하나는 자세한 구성을 제공하는 것입니다. 자세한 정보는 Couchbase Server 1.8/2.0부터 제공되어 왔으며 작동이 보장되지만 최신 기능은 여기에 노출되지 않을 가능성이 높습니다.
최신/확장성이 가장 뛰어난 접근 방식이 먼저 시도되고 구형 클라이언트와 사용자 정의 구성을 위한 폴백 옵션이 제공됩니다. 일반적으로 클러스터 관리자는 항상 최신 구성을 관리하고 제공할 책임이 있지만, SDK가 특수 명령으로 검색할 수 있도록 KV 서비스에도 전송됩니다.
구형 서버의 특별한 경우로, 구형 서버의 구성이 HttpLoader 로 설정하면 SDK가 HTTP 엔드포인트 중 하나에 스트리밍 연결을 연결하여 설정 업데이트를 수신합니다. 만약 캐리어로더 가 성공했다면, 대신 바이너리 프로토콜을 통해 구성에 대해 구성 가능한 폴링 간격으로 폴링하는 것이 서버 측에서 더 리소스 효율적이므로 계속 폴링할 것입니다(KV 서비스는 클러스터 관리자보다 잠재적으로 많은 요청을 처리하는 데 훨씬 더 적합하므로 애초에 캐리어 로딩이 구현된 이유입니다).
다른 오류 사례는 나중에 다루겠지만, 지금은 로더 중 하나에서 유효한 구성을 가져올 수 있었다고 가정하겠습니다. 이 시점에서 구성 공급자에게 다시 전송되고, 이 공급자는 이를 확인하여 요청 핸들러.
구성 제공업체가 구성을 전달하지 않을 수 있는데, 주된 이유는 구성이 오래되었거나 충분히 새롭지 않기 때문입니다. 모든 구성에는 함께 제공되는 리비전이 있으며 SDK는 내부적으로 이 리비전 번호를 추적하여 이미 처리된 구성보다 최신인 구성만 전파합니다. 리밸런싱 작업 중에는 이런 일이 자주 발생할 수 있으며, 디버그 로깅을 활성화한 경우 메시지가 있는 로그 행을 찾아서 이를 확인할 수 있습니다: Not 신청하기 new 구성, 이전 또는 동일 rev ID .
가 요청 핸들러 가 새 구성을 푸시 받으면 재구성. 재구성에는 서버에서 제공한 구성을 가져와 내부 SDK의 상태를 미러링하도록 변경하는 작업 하나만 있습니다. 여기에는 노드 참조, 서비스 엔드포인트 또는 소켓을 추가하거나 제거하는 작업이 포함될 수 있습니다. SDK는 서버의 공통 언어를 미러링하므로 다음을 관리합니다. 노드 를 제공하는 서비스 하나 이상의 엔드포인트.
디버그 로깅을 활성화하면 부트스트랩 중에 제공된 구성에 따라 다양한 노드, 서비스 및 엔드포인트가 어떻게 활성화되는지 확인할 수 있습니다:
|
1 2 3 4 5 6 7 |
[cb-계산-8] 2018-06-20 17:43:55 DEBUG 요청 핸들러:435 - 시작 재구성. [cb-계산-8] 2018-06-20 17:43:55 DEBUG 요청 핸들러:527 - 시작 재구성 에 대한 버킷 여행-샘플 [cb-계산-8] 2018-06-20 17:43:55 DEBUG 요청 핸들러:292 - 노드 네트워크 주소{localhost/127.0.0.1, from호스트이름=false, reverseDns=true} 이미 등록된, 건너뛰기. [cb-계산-8] 2018-06-20 17:43:55 DEBUG 요청 핸들러:352 - Got 지시 에 추가 서비스 바이너리, 에 노드 네트워크 주소{localhost/127.0.0.1, from호스트이름=false, reverseDns=true} [cb-계산-8] 2018-06-20 17:43:55 DEBUG 노드:273 - [127.0.0.1/localhost]: 추가 서비스 바이너리 [cb-계산-8] 2018-06-20 17:43:55 DEBUG 노드:276 - [127.0.0.1/localhost]: 서비스 바이너리 이미 추가, 건너뛰기. ... |
또한 원하는 결과가 이미 달성된 경우 특정 작업을 무시하는 것을 볼 수 있습니다. 이러한 메시지의 대부분은 부트스트랩, 리밸런싱 또는 장애 조치 중에 새 구성이 도착할 때 표시됩니다.
재구성은 서버에서의 리밸런싱과 마찬가지로 '온라인' 작업입니다. 즉, 기내 작업은 대부분의 경우 영향을 받지 않으며, 영향을 받는 경우 성공하거나 시간이 초과될 때까지 일정을 재조정하여 링버퍼에 다시 넣습니다.
첫 번째 재구성이 성공하자마자 버킷 열기 요청이 완료되고 버킷 핸들은 동기식 API에서 반환됩니다. 여기에는 분명하지 않은 트레이드오프가 있습니다. 열린 버킷 요청을 즉시 반환할 수 있지만 부트스트랩 중에 오류를 포착할 수 없다는 것입니다. 첫 번째 재구성이 완료될 때까지 기다리면 더 많은 오류를 즉시 포착할 수 있지만 클러스터에 더 많은 노드가 추가될수록 시간이 더 오래 걸린다는 의미이므로 클러스터의 부트스트랩 성능을 측정해야 합니다. 대부분의 경우 기본 시간 제한 5초면 충분하지만, 속도가 느리고 규모가 큰 클라우드 배포에서는 이 시간 제한을 늘리는 것이 합리적일 수 있습니다.
환경을 수정하여 이 작업을 수행할 수 있습니다:
|
1 2 3 |
카우치베이스 환경 환경 = 기본 카우치 기반 환경.빌더() .connectTimeout(시간 단위.초.toMillis(10)) // 5초에서 10초로 설정 .빌드(); |
또는 직접 오픈버킷 호출합니다:
|
1 |
버킷 버킷 = 클러스터.오픈버킷("travel-sample", 10, 시간 단위.초); |
부트스트랩 실패 및 구성
제공된 시드 호스트 중 하나 또는 모두를 사용할 수 없는 경우 어떻게 되나요? 이 질문에 답하기 위해 로더가 구성을 가져오는 방법을 간단히 살펴볼 필요가 있습니다.
시드 노드 목록의 모든 호스트에 대해 기본 및 폴백 로더가 조립되고 모든 로더가 적절한 구성을 얻기 위해 동시에 실행됩니다. 첫 번째 구성이 발견되면 관찰 가능한 시퀀스가 구독 취소되고 앞으로는 하나의 구성만 사용됩니다. 시퀀싱 대신 이 방식을 사용하면 부트스트랩 시간이 빨라지지만 하나 이상의 노드에 연결할 수 없는 경우 로그에 오류가 더 많이 발생할 수 있습니다. 하지만 좋은 경우를 위해 최적화하고 있기 때문에(실패한 경우에는 어차피 뭔가 잘못된 것이므로) 이는 허용 가능한 절충안처럼 보입니다.
기본적으로 시드 노드 목록에 부트스트랩할 좋은 노드가 있는 한 SDK는 구성을 선택할 수 있습니다. 특별한 경우를 고려해 보겠습니다. MDS 설정을 사용하면 SDK가 KV 서비스를 포함하지 않는 노드(쿼리와 클러스터 관리자만 포함한다고 가정)에서만 부트스트랩하도록 지시할 수 있습니다.
디버그 로깅을 사용하도록 설정한 경우 SDK가 KV 서비스에서 구성을 가져오려고 시도하지만 오류와 함께 거부되는 것을 볼 수 있습니다:
|
1 |
[cb-계산-7] 2018-06-21 10:53:48 DEBUG 로더:178 - 가능 not 추가 서비스 on 네트워크 주소{10.142.175.102/10.142.175.102, from호스트이름=false, reverseDns=true} 왜냐하면 의 com.카우치베이스.클라이언트.핵심.엔드포인트.kv.인증 예외: 버킷 not 발견 on 선택 버킷 명령, 제거 it 다시. |
특정 오류는 중요하지 않지만 로그의 뒷부분에서 로더가 사용 가능한 HTTP 폴백으로 전환하는 방법을 확인할 수 있습니다:
|
1 2 3 4 5 |
[cb-계산-2] 2018-06-21 10:53:48 DEBUG 로더:196 - 성공적 활성화 서비스 CONFIG on 노드 네트워크 주소{10.142.175.102/10.142.175.102, from호스트이름=false, reverseDns=true} [cb-계산-2] 2018-06-21 10:53:48 DEBUG HttpLoader:69 - 시작 에 발견 구성 통해 HTTP 부트스트랩 ... [cb-계산-4] 2018-06-21 10:53:48 DEBUG HttpLoader:93 - 성공적 로드 구성 통해 HTTP. [cb-계산-4] 2018-06-21 10:53:48 DEBUG 로더:203 - Got 구성 에서 서비스, 시도 중 에 parse. |
이에 대한 한 가지 의미는 다른 노드에서 KV 서비스를 사용할 수 있더라도 이 경우 HTTP 로더가 후속 구성을 가져오기 위해 스트리밍 연결을 열도록 지시한다는 것입니다.
환경 설정을 통해 부트스트랩 동작을 사용자 지정할 수 있습니다:
- 부트스트랩HttpEnabled : HttpLoader가 전혀 활성화되어 있지 않은 경우(기본값은 true).
- 부트스트랩 캐리어 활성화 : 캐리어로더가 전혀 활성화되어 있지 않은 경우(기본값은 true).
- 부트스트랩HttpDirectPort : SSL이 활성화되지 않은 경우 HttpLoader가 처음에 연결해야 하는 포트(기본값 8091).
- 부트스트랩HttpSslPort : SSL이 활성화된 경우 HttpLoader가 처음에 연결해야 하는 포트(기본값 18091).
- 부트스트랩 캐리어 다이렉트 포트 : SSL이 활성화되지 않은 경우 CarrierLoader가 처음에 연결해야 하는 포트(기본값 11210).
- 부트스트랩캐리어Ssl포트 : SSL이 활성화된 경우 캐리어로더가 처음에 연결해야 하는 포트(기본값 11207).
이러한 설정에는 정상적인 기본값이 있으며 일반적으로 수정할 필요가 없습니다. 시나리오를 디버깅하거나 Couchbase 내부에서 사용자 지정 빌드를 테스트할 때 유용하게 사용할 수 있습니다.
최종 생각
일반적으로 부트스트랩은 개별 노드 장애에 대해 원활하고 탄력적으로 작동하지만, 문제가 발생하여 버킷이 제대로 열리지 않는 경우 가장 먼저 해야 할 일은 항상 정보/경고 수준에서 로그를 살펴보고 가능한 경우 디버그 로깅을 활성화하는 것입니다. 이렇게 하면 일반적으로 어떤 소켓이 제대로 연결되지 않았는지 또는 부트스트랩 단계에서 클라이언트가 오류나 시간 초과로 인해 중지해야 했던 위치에 대한 인사이트를 얻을 수 있습니다.
또한 대규모 클러스터를 실행하는 경우 네트워크가 느리거나 평소보다 지연 시간 편차가 큰 경우 버킷 열기 시간을 일반적인 5초보다 길게 지정하는 것이 좋습니다.
좋은 기사입니다! 감사합니다.
서버 측의 어떤 로그에 부트스트랩 정보가 있는지 궁금합니다. "memcached.log"인가요? 이에 대해 자세히 설명해 주시면 감사하겠습니다. 고마워요.
예, 서버 측의 memcached.log에 일부 정보가 있습니다. 스팸이 많을 수 있기 때문에 (최신 "hello" 명령 외에는) 많은 로그를 기록하지는 않습니다.
특별히 찾고 있는 것이 있나요?