최근에 설치부터 개발 설정, 인덱싱 이해에 이르기까지 Couchbase Server의 핵심 구성 요소를 다루는 온라인 웨비나 시리즈를 시작했습니다. 웨비나를 진행하는 동안 많은 질문이 올라와서 여기에 서면 Q&A를 게시합니다.
루비 기반 로드 생성기는 여기에서 다운로드할 수 있습니다: https://github.com/scalabl3/ruby-couchbase-loadgen
Couchbase 101 - 설치 및 구성
질문: 서버를 추가하면 샤딩이 되나요?
A: 예, 모든 데이터에 "해시 샤딩"을 사용합니다. 즉, 모든 키-값 쌍에 대해 문자열 키를 해시하여 해당 키가 있어야 할 파티션 번호(논리적 컨테이너)를 얻습니다. 클러스터 맵에서 파티션 번호를 조회하여 해당 파티션이 Couchbase 클러스터에서 어디에 있는지 확인한 다음, 해당 파티션을 담당하는 Couchbase 노드에서 직접 CRUD를 수행합니다. 새 서버(또는 두 개 이상)를 추가하면 새로운 노드 수에 따라 파티션을 균등하게 재분배하기만 하면 됩니다.
질문: 복제 전용 서버를 추가해야 하나요?
A: 장애 조치 상황에서의 효율성을 위해 복제본은 노드를 "장애 조치"할 수 있도록 서로 다른 노드에 위치해야 합니다. 하나의 복제본에는 최소 두 개의 Couchbase 노드가 있어야 합니다. 복제본이 2개인 경우에는 최소 3개의 Couchbase 노드가 있어야 하고, 복제본이 3개인 경우에는 최소 4개의 Couchbase 노드가 있어야 합니다. 물론 복제본 수를 늘리면 최적의 성능을 위해 더 많은 리소스가 필요합니다.
질문: 해시값이 같은 모든 문서가 같은 파티션에 저장되나요?
A: 예, 해시 함수는 단순히 문자열 키를 [0...1023]의 숫자로 바꾸는 것이며, 숫자 2로 해시되는 모든 키는 파티션 컨테이너 #2 내에 존재합니다. 해당 파티션은 클러스터의 특정 Couchbase 노드에 상주하며, 서버를 더 추가하고 재조정하면 해당 파티션을 다른 서버로 이동할 수 있지만 해당 파티션의 "마스터"인 노드는 항상 한 개만 존재합니다. 물론 해당 파티션의 '복제본'은 별도의 노드에 존재합니다.
질문: 수평 스케일 예제에서 총 파티션은 항상 1024개입니다. 클러스터의 최대 파티션은 1024개인가요?
A: 샤딩 및 배포 방식을 처음 배울 때 많은 개발자가 이 숫자를 조정할 수 있는 노브로 생각하는데, 이는 우리 모두가 땜장이이기 때문입니다. 하지만 파티션의 수는 성능 특성을 바꾸지 않습니다. 1024개는 데이터를 균등하게 분배하는 데 적합한 파티션 수이며, 변경할 필요가 없고 구성 매개변수가 아닙니다. 이 숫자는 10,000개 또는 990개가 될 수도 있으며, 데이터 배포 방식의 아키텍처를 변경하지 않습니다(데이터 파일 수를 늘리거나 줄이는 것일 뿐).
질문: 단일 가상 머신에 몇 개의 버킷을 설치할 수 있나요?
답변: 가상 머신에 할당된 리소스는 매우 다양할 수 있으므로 경험칙을 제시하기 어려운 질문이지만 일반적으로 8코어 이상의 상당한 규모의 머신의 경우 약 10~12개의 버킷이 가능합니다. 각 버킷마다 관리 및 모니터링할 리소스를 할당하므로 많은 수의 버킷을 사용하면 CPU 오버헤드가 증가하므로 일반적으로 권장하지 않습니다.
질문: 노드 리밸런싱이 카우치베이스의 효율성에 어떤 영향을 미치나요?
답변: 저희는 리밸런싱 작업보다 기본 작업을 우선시하지만, 리밸런싱 중에는 Couchbase 노드 간에 CPU 및 네트워크 트래픽이 증가합니다. 물론 다른 시스템과 마찬가지로 백업을 수행할 때도 마찬가지로 사용량이 많지 않은 시간에 리밸런싱을 수행하는 것이 좋습니다. 사용량이 많은 시간에 리밸런싱을 수행하면 사용량이 매우 많은 경우 리밸런싱 시간이 확실히 느려집니다.
질문: 재조정할 때 파티션이 실제로 다른 노드로 이동되나요, 아니면 중복되나요?
A: 리밸런싱 중 장애가 발생할 경우를 대비해 리밸런싱이 완료될 때까지 복사됩니다. 원래 마스터 노드는 리밸런싱이 완전히 완료될 때까지 마스터 노드로 유지됩니다. 리밸런싱이 완료되면 해당 파티션의 새 마스터 노드가 마스터가 되고 이전 마스터 노드는 데이터를 제거하며, 클러스터 맵이 클러스터 전체에 걸쳐 업데이트된 다음 클라이언트 SDK의 클러스터 맵이 업데이트됩니다.
질문: 백업/복원 및 재해 복구에 사용할 수 있는 도구에는 어떤 것이 있나요?
A: 이 용도로만 사용할 수 있는 cbbackup 및 cbrestore 명령줄 도구가 있으며, 여기에서 자세한 내용을 확인할 수 있습니다: http://www.couchbase.com/docs//couchbase-manual-2.0/couchbase-backup-restore-backup-cbbackup.html
Couchbase 102 - 개발
질문: Couchbase에 사진을 저장할 때 어떤 일이 발생하나요?
A: Couchbase에서는 두 가지 방법으로 사진을 저장할 수 있는데, 하나는 바로 바이너리 데이터를 문서 값으로 저장하는 것입니다. 두 번째 옵션은 JSON 문서 내에 미리 인코딩된 베이스64로 저장하는 것입니다. 즉, 하나 이상의 이미지가 JSON 값으로 인코딩된 표준 JSON 문서(JSON 키 포함)로 저장하는 것입니다. 이 경우의 장점 이미지 저장 의 가장 큰 장점은 디스크가 아닌 RAM에서 제공되므로 성능이 매우 뛰어나다는 것입니다. 이를 XDCR(데이터 센터 간 복제)과 결합하면 이미지용 CDN을 직접 만들 수 있습니다!
질문: 여러 문서를 수정/업데이트하고 그 중 하나에서 오류가 발생하면 어떻게 롤백하나요?
A: 카우치베이스에서는 다음 트랜잭션에 대해 낙관적(CAS) 또는 비관적(잠금) 동시성을 매우 쉽게 사용할 수 있습니다. 단일 문서를 사용할 수 있지만, 단일 '트랜잭션'에 여러 문서가 있는 경우에는 2단계 커밋이라는 것을 사용해야 합니다. 자세한 내용은 여기에서 확인할 수 있습니다: http://www.couchbase.com/docs/couchbase-devguide-2.0/two-phase-commits.html
질문: 카우치베이스에서 거래가 가능한가요?
답변: 이전 질문과 마찬가지로 (CAS - 비교 및 스왑) 또는 가져오기 및 잠그기를 사용하여 단일 문서 트랜잭션을 쉽게 수행할 수 있습니다.
질문: 기본 디스크에 쓴 후 실패한 삽입/업데이트 목록으로 콜백하는 일괄 삽입/업데이트 작업이 있나요?
A: 일부 SDK(예: Python)에는 다중 집합 유형 연산이 있지만(모두 다중 get 연산이 있음), 저희는 다중 집합 및 관찰 유형 연산을 지원하지 않는 것으로 알고 있습니다.
질문: 이름, 날짜, 상태와 같이 전달할 매개변수가 여러 개 있는 쿼리를 만들려면 어떻게 해야 하나요? SQL의 "where"처럼요?
A: 뷰(인덱스)를 사용하여 여러 매개변수를 쿼리하려면 별도의 뷰를 쿼리하고 애플리케이션 내에서 교차 작업을 수행하거나 인덱스 키를 창의적으로 사용하여 범위 쿼리를 수행해야 할 수 있습니다. 이를 위한 여러 가지 전략이 있으며, 사용 사례와 문서 디자인에 따라 간결하게 답변할 수 있는 방법이 달라집니다.
질문: Go나 Clojure와 같은 다른 언어도 지원하나요?
A: 네! Go용 커뮤니티 에디션이 있습니다(https://github.com/dustin/go-couchbase)의 모든 고객 페이지에서 모든 커뮤니티 고객을 확인할 수 있습니다: http://www.couchbase.com/communities/all-client-libraries 커뮤니티 클라이언트 라이브러리는 지원 계약에 의해 공식적으로 지원되지 않지만 IRC 또는 트위터를 통해 엔지니어의 도움을 쉽게 찾을 수 있습니다.
질문: 키 패턴이 조회수보다 빠른가요?
A: 키 패턴을 실제로 사용할 수 있는 대부분의 경우, 키 패턴은 RAM 캐시에서 나오는 이진 연산이기 때문에 그렇습니다. 하지만 모든 것을 키 패턴을 사용해 모델링할 수 있는 것은 아닙니다. 이러한 경우에는 보기(인덱스)가 유용하며 Elastic Search 통합도 유용합니다.
Couchbase 103 - 보기, 인덱싱 및 쿼리
질문: 인덱스가 메모리에 보관되나요?
A: 아니요, 다른 데이터베이스의 다른 인덱싱 시스템과 마찬가지로 모든 인덱스는 디스크에 생성되고 디스크에서 쿼리됩니다. 운영 체제는 파일 시스템 캐시에 RAM을 사용하므로 인덱스 쿼리 성능이 상당히 향상됩니다. 그렇기 때문에 운영 체제가 이를 수행할 수 있도록 RAM의 상당 부분을 남겨 둡니다(40% 사용 가능한 RAM).
질문: 인덱스가 여러 노드에 자동으로 분산되나요? 예. 성능상의 이유로 특정 노드에만 인덱스를 배치할 수 있습니다. 예를 들어 쿼리/색인 작업이 많아서 여러 노드에 영향을 미치고 싶지 않은 경우입니다.
A: Couchbase의 모든 노드는 그 노드에 상주하는 마스터/활성 파티션("마스터")에 대한 인덱스를 유지 관리합니다. 파티션에 대한 키의 해시 샤딩으로 인해 데이터가 균등하게 분산되므로 불완전한 인덱스 없이 특정 노드에만 인덱스를 가질 수 없습니다. 하지만 기본 데이터 저장소에서 문서를 수신하는 단방향 XDCR(데이터 센터 간 복제)의 수신 측에 별도의 전체 클러스터를 두는 다른 전략을 사용할 수도 있습니다(수신만 가능합니다, 데이터 생성이나 업데이트에는 사용되지 않음)를 사용하여 무거운 인덱싱과 쿼리에 사용할 수 있으며 해당 목적에 완전히 최적화되어 있습니다.
질문: 인터페이스 수준에서 특정 뷰의 메타 ID를 숨길 수 있나요? 맵 함수 매개 변수에서 제거하면 되나요? 예를 들어 웹사이트를 사용 중인데 고객이 데이터베이스를 쿼리하고 있는데 메타 아이디를 표시하고 싶지 않은 경우?
답변: 아니요, 모든 문서 키(ID)는 해당 결과 '행'(실제로는 결과 배열의 배열 항목)을 생성한 문서에 대한 결과 집합에 JSON으로 포함됩니다. 맵 함수에서 제외해도 이 점은 변하지 않습니다. 두 번째 경우를 해결하기 위해 할 수 있는 일은 웹 페이지 자바스크립트 쿼리가 Couchbase를 직접 쿼리하지 않도록 하는 것입니다(일반적으로 공개하지 않는 데이터베이스와 마찬가지로 Couchbase 서버가 노출되므로 권장하지 않습니다). 대신 자체 API를 통해 쿼리를 실행하고 문서 ID(meta.id)가 없는 결과 집합을 필터링할 수 있습니다.
질문: 건너뛰기가 있는 뷰를 쿼리할 때 응답 시간이 건너뛰기 크기에 비례하는 것 같습니다. 이는 예상된 결과인가요?
A: 건너뛰기를 사용하는 대신 실제로 한 쌍의 매개변수, 시작키와 시작키_docid를 사용하여 페이지를 넘기는 것이 더 좋습니다. 결과는 먼저 시작키(인덱스 키)를 기준으로 정렬된 다음, 결과 집합에 동일한 인덱스 키가 여러 개 있는 경우 시작키_docid를 기준으로 정렬됩니다. 이 방법을 대신 사용하는 이유는 두 가지인데, 하나는 응답 시간 문제를 피할 수 있다는 점입니다. 클러스터가 커질수록 클러스터 전체에 쿼리가 분산되므로 각 노드에서 스킵하는 데 더 많은 시간이 걸리기 때문에 클러스터가 커지면 스킵의 영향을 받는 분산 수집이 모두 악화되는 문제를 피할 수 있습니다. 둘째, 인덱스가 업데이트되면 결과 집합이 변경되므로 '건너뛰기'는 처음 쿼리한 후에도 정확히 동일하게 건너뛰지 않습니다.
읽어 주셔서 감사합니다!
자스딥 자이틀라
jasdeep@couchbase.com
scalabl3
[...] 금주의 블로그 게시물: 카우치베이스 온라인 교육 Q&A(시리즈 101/102/103) [...]