실제 IBM Cloudant
IBM Cloudant 사례 문서는 이 시리즈의 세 번째 모범 사례 문서입니다. 다음과 같은 모범 사례를 보여줍니다:
- 충돌을 피하는 방법.
- 문서 삭제의 작동 방식
- 업데이트 시 주의해야 할 사항
- 궁극적으로 일관된 환경에서 작업하는 방법
- 복제를 설정하는 방법
- 대량 API를 사용하는 방법.
- Q, R, N을 변경하면 안 되는 이유.
- 요금 제한의 작동 방식.
- 어떤 로깅 트랙을 추적할까요?
- HTTP 트래픽을 압축하는 방법.
자세한 정보는 데이터 모델링 또는 인덱싱 및 조회를 참조하십시오.
이 문서의 컨텐츠는 원래 Stefan Kruger가 2019년 11월 21일에 Best and worst practice 블로그 게시물로 작성했습니다.
충돌 방지
IBM Cloudant는 분산 시스템에서 충돌을 자연적인 데이터 상태로 처리하도록 설계되었습니다. 이 기능은 IBM Cloudant 클러스터가 항상 고가용성을 유지하도록 지원하는 강력한 기능입니다. 그러나 충돌은 상당히 드물다고 가정됩니다. IBM Cloudant의 코어에서 충돌을 추적하는 데는 상당한 비용이 연관되어 있습니다.
충돌을 무시하는 것은 완벽하게 가능합니다. 그러나 잘못된 생각입니다. 데이터베이스는 무작위이지만 결정론적인 충돌 문서 개정을 선택하여 오퍼레이션을 수행합니다. 그러나 해결되지 않은 충돌의 수가 증가함에 따라 데이터베이스의 성능은 특히 복제 시 블랙홀로 떨어집니다.
충돌을 확인하고 해결하거나 더 나아가 충돌을 불가능하게 하는 데이터 모델을 사용하는 것은 개발자의 책임입니다.
정기적으로 충돌을 일으키는 경우 실제로 모델 변경을 고려해야 합니다. 충돌을 열심히 해결해도 개정 트리의 충돌 분기는 쉽게 정리할 수 없는 상태로 남아 있습니다. 자세한 정보는 다음 웹 사이트를 참조하십시오.
문서를 삭제해도 삭제되지 않음
IBM Cloudant 데이터베이스에서 문서를 삭제해도 제거되지 않습니다. 삭제는 _deleted: true 필드가 추가된 삭제 중인 문서의 새 개정판을 작성하여 구현됩니다. 이 특별 개정판은 tombstone이라고 합니다. 삭제 표식은 여전히 공간을 차지하며 복제자에 의해 전달됩니다.
문서의 빈번한 삭제에 의존하는 모델은 IBM Cloudant에 적합하지 않습니다. 자세한 정보는 IBM Cloudant 삭제 표식 문서를 참조하십시오.
업데이트에 주의해야 함
새 문서를 작성하는 것보다 기존 문서를 변경하는 것이 결과적으로 더 비용이 많이 듭니다. IBM Cloudant는 항상 문서 트리 구조를 유지해야 합니다. 이 규칙은 트리의 내부 노드에서 페이로드가 제거된 경우에도 적용됩니다. 긴 개정 트리를 작성하면 복제 성능이 저하됩니다. 또한 업데이트 빈도가 몇 초마다 한 번 또는 두 번 정도로 높은 경우 업데이트 충돌이 발생할 가능성이 높습니다.
변경 불가능한 모델을 사용하십시오.
다음 섹션을 읽으면 문서를 삭제해도 삭제되지 않으며, 업데이트 시 주의해야 한다는 문구가 눈에 띕니다. 즉, "내 모델이 변경 불가능한 경우 데이터 세트가 무한으로 증가합니까?"라는 질문입니다. 삭제해도 삭제된 데이터가 완전히 제거되지 않고 데이터 볼륨 증가 측면에서 업데이트가 제자리에서 업데이트되지 않는 것을 허용하면 큰 차이가 없습니다. 시간 경과에 따라 데이터 볼륨을 관리하려면 다양한 기술이 필요합니다.
실제로 공간을 확보하는 유일한 방법은 문서가 아닌 데이터베이스를 삭제하는 것입니다. 성공한 개정판만 새 데이터베이스에 복제하고 이전 개정판을 삭제하여 느린 삭제 및 충돌을 제거할 수 있습니다. 또는 유스 케이스가 허용하는 경우 모델에 빌드하여 정기적으로 새 데이터베이스('연간 데이터'라고 함)를 시작하고 오래된 데이터를 아카이브(또는 제거)할 수 있습니다.
최종 일관성은 가혹한 태스크 마스터임(쓰기를 읽지 않음이라고도 함)
최종 일관성은 문서상의 훌륭한 아이디어이며 실제로 확장할 수 있는 IBM Cloudant의 기능에 대한 핵심 컨트리뷰터입니다. 그러나 결국 일관된 데이터 저장소에 대해 개발하는 데 필요한 사고방식이 대부분의 사람들에게는 자연스럽게 느껴지지 않는다고 말해도 무방합니다.
다음과 유사한 테스트를 작성할 때 종종 문제가 발생합니다:
- 데이터베이스를 작성합니다.
- 일부 테스트 데이터로 데이터베이스를 채웁니다.
- 데이터베이스에서 이 테스트 데이터의 일부 서브세트를 조회합니다.
- 반환한 데이터가 반환할 것으로 예상한 데이터인지 확인합니다.
해당 테스트에 문제가 없습니까? 지금까지 사용했던 다른 모든 데이터베이스에서 작동하는 것이 맞죠?
IBM Cloudant에서는 작동하지 않습니다.
오히려 100번 중에서 99번은 작동합니다.
이러한 차이가 발생하는 이유는 데이터베이스에 데이터를 쓰는 시점과 클러스터의 모든 노드에서 이 데이터를 사용할 수 있는 시점 사이에 (대부분) 작은 불일치 간격이 있기 때문입니다. 클러스터의 모든 노드는 위상이 동일하므로 쓰기와 후속 읽기가 동일한 노드에서 서비스된다는 보장은 없습니다. 따라서 일부 상황에서는 기록된 데이터가 노드에 도달하기 전에 읽기가 노드에 도달할 수 있습니다.
그렇다면 테스트의 쓰기와 읽기 사이에 짧은 지연 시간을 두는 것이 어떻습니까? 이러한 지연 시간으로 인해 테스트가 실패할 가능성이 줄어들지만 문제점은 여전히 존재합니다.
IBM Cloudant에는 트랜잭션 보장이 없습니다. 문서 쓰기는 원자적이지만(문서를 전체적으로 읽을 수 있거나 전혀 읽을 수 없음이 보장됨) 불일치 창을 닫을 수 있는 방법은 없습니다. 디자인에 따라 존재합니다.
모든 개발자가 고려해야 하는 심각한 문제는 사용자가 작성한 데이터를 특정 시점에 다른 사용자가 사용할 수 있다고 안전하게 가정할 수 없다는 점입니다. 다른 유형의 기존 데이터베이스를 사용해 왔다면 이 상태에 익숙해지는 데 시간이 걸립니다.
테스트 팁: 테스트에서 불일치 기간을 피하기 위해 할 수 있는 방법은 Docker (도커 정보) 에서 실행 중인 IBM Cloudant 또는 CouchDB 의 단일 노드 인스턴스에 대해 테스트하는 것입니다. 단일 노드는 최종 일관성 문제를 제거하지만 프로덕션에서 대상으로 하는 것과 다르게 작동하는 환경에 대해 테스트 중임에 유의하십시오. 주의 Emptor.
복제는 마법이 아님
“So let’s set up three clusters across the world, Dallas, London, Sydney, with bi-directional synchronization between them to provide real-time collaboration between our 100,000 clients.”
아니오. 그냥… 아니오. IBM Cloudant는 복제를 잘 수행합니다. 마법처럼 보일 수 있지만 지연 시간을 보장하지 않는다는 점에 유의하세요. 사실, 전체 시스템은 최종 일관성을 염두에 두고 설계되었습니다. IBM Cloudant의 복제를 실시간 메시징 시스템으로 처리하는 것은 만족스러운 결과로 끝나지 않습니다. 이 유스 케이스의 경우 Apache Kafka와 같이 이 목적으로 설계된 시스템을 사이에 배치하십시오.
복제 처리량에 숫자를 매기는 것은 어렵습니다. 답변은 항상 "상황에 따라 다릅니다."입니다. 복제 성능에 영향을 미치는 요소에는 다음이 포함됩니다(단, 이에 제한되지 않음).
- 변경 빈도
- 문서 크기
- 전체 클러스터의 동시 복제 작업 수
- 넓은(충돌) 문서 트리
- 예약 처리량 용량 설정
자세한 정보는 다음 웹 사이트를 참조하십시오.
벌크 API 사용
IBM Cloudant 에는 한 번의 요청으로 많은 문서를 대량으로 로드(및 읽기)할 수 있는 멋진 API 엔드포인트가 있습니다. 한 번의 요청으로 많은 문서를 읽는 것이 한 번에 많은 문서를 읽고 쓰는 것보다 훨씬 효율적일 수 있습니다. 쓰기 엔드포인트가 다음 예제에 나와 있습니다.
${database}/_bulk_docs
주요 목적은 복제자 알고리즘의 중심 부분이 되는 것이지만 사용자가 사용할 수도 있으며 훌륭합니다.
_bulk_docs를 사용하여 PouchDB를 작성하는 것 이외에 단일 문서에 대해서도 더 적은 코드 경로를 위해 이 방식으로 작성, 업데이트 및 삭제를 구현하십시오.
다음 예제에서는 하나의 새 문서를 작성하고 두 번째 기존 문서를 업데이트하며 세 번째 문서를 삭제합니다.
curl -XPOST 'https://ACCT.cloudant.com/DB/_bulk_docs' \
-H "Content-Type: application/json" \
-d '{"docs":[{"baz":"boo"}, \
{"_id":"463bd...","foo":"bar"}, \
{"_id":"ae52d...","_rev":"1-8147...","_deleted": true}]}'
_all_docs ( _bulk_get 이라는 비교적 새로운 엔드포인트도 존재하지만 이 엔드포인트는 원하는 것이 아닐 수도 있습니다)로 POST를 발행하여 한 번의 요청으로 많은 문서를 가져올 수도 있습니다. 특정 내부 목적을 위해 존재함).
' _all_docs, ' POST '를 ' keys 본문과 함께 사용하여 고정된 문서 집합을 가져오려면 다음 명령을 실행합니다:
curl -XPOST 'https://ACCT.cloudant.com/DB/_all_docs' \
-H "Content-Type: application/json" \
-d '{"keys":["ab234....","87addef...","76ccad..."]}'
IBM Cloudant(쓰기 시)는 최대 요청 크기를 11MB로 지정합니다. 이 크기를 초과하는 _bulk_docs 요청은 413: Payload Too Large error와 함께 거부됩니다.
자세한 정보는 다음 웹 사이트를 참조하십시오.
- IBM Cloudant 벌크 오퍼레이션 문서
- IBM Cloudant 요청 및 문서 크기 한계
실제로 수행 중인 작업을 알지 못하는 경우 Q, R 및 N을 건드리지 마십시오.
자신이 무엇을 하고 있는지 잘 알지 못한다면 Q, R, N을 변경하지 마세요. IBM Cloudant 의 쿼럼 및 샤딩 매개변수를 발견한 후에는 데이터베이스의 동작을 변경하고 싶은 유혹적인 옵션처럼 보입니다.
일관성이 강화되어 복제본 수에 대한 쓰기 쿼럼을 설정할 수 있습니까?
아니오! 클러스터에서 불일치 창을 닫을 방법이 없음을 기억하십시오.
이는 고려하지 마십시오. 이러한 동작은 특히 네트워크 파티션 중에 이해하기 훨씬 어려울 수 있습니다. Cloudant-the-service를 사용하는 경우 기본값은 대부분의 사용자에게 적합합니다.
최상의 성능을 얻기 위해서는 데이터베이스의 샤드 수를 조정하는 것이 필수적일 수 있습니다. 이유를 말할 수 없다면 상황을 더 악화시킬 수 있습니다.
IBM Cloudant 요금이 제한되어 있습니다 - 이 요금 제한을 코드에 알립니다
Cloudant-the-service(기본 CouchDB와 달리)는 "예약 처리 용량" 모델로 판매됩니다. 즉, 최종적으로 사용하는 처리량이 아니라 특정 처리량까지 사용할 수 있는 권리에 대한 비용을 지불하는 것입니다. 사용할 수 있는 권한 방법을 충분히 이해하는 데 시간이 걸립니다. 한 가지 잘못된 비교는 사용하는지 여부에 관계없이 설정된 시간(분)에 대한 비용을 지불하는 휴대전화 약정의 경우일 수 있습니다.
휴대전화 약정 비교는 전체 상황을 포착하지 못하지만 한 달 동안 IBM Cloudant에 대해 수행할 수 있는 요청의 합계에는 제약이 없습니다. 제약조건은 얼마나 빠르게 요청하는지에 있습니다.
이는 실제로 IBM Cloudant가 사용자에게 하는 약속이 아니라 사용자가 IBM Cloudant에 하는 약속입니다. 사전에 합의한 것보다 더 많이 초당 요청을 수행하지 않겠다고 약속합니다. 원하는 경우 최대 속도를 제한합니다. 위반하는 경우 IBM Cloudant가 429: Too Many Requests 상태로 요청에 실패합니다. 이 케이스를 조사하고 처리하는 것은 사용자의 책임이며, 다중 앱 서버가
있는 경우에는 어려울 수 있습니다. 초당 요청 수 제한을 총체적으로 유지하기 위해 어떻게 조정할 수 있을까요?
{{{site.data.keyword.cloudant_short_notm}}공식 클라이언트 라이브러리에는 '백오프 후 재시도' 전략에 따라 이 사용 사례를 활성화할 수 있는 몇 가지 기본 제공 조항이 있습니다.
이 기본 제공 조항은 기본적으로 꺼져 있어 사용자가 고려하도록 합니다.
그러나 이 기능에만 의존하다 보면 결국 실망할 수 있습니다. 백오프 및 재시도 전략은 일시적인 위반의 경우에만 도움이 되며 프로비저닝된 처리 용량 한계에 지속적으로 영향을 미치지 않습니다.
비즈니스 로직이 이 조건을 처리할 수 있어야 합니다. 이를 보는 또 다른 방법은 사용자가 지불하는 할당을 받는 것입니다. 할당이 충분하지 않은 경우 유일한 솔루션은 더 높은 할당 비용을 지불하는 것입니다.
프로비저닝된 처리 용량은 검색, 쓰기 및 조회의 세 가지 버킷으로 나뉩니다. 검색은 해당 _id를 기반으로 문서를 페치하는 "기본 키" 읽기입니다. 쓰기는 문서 또는 첨부 파일을 디스크에 저장하며 조회는 2차 인덱스(_design 또는 _find가
있는 API 엔드포인트)를 사용하여 문서를 검색합니다.
각각 서로 다른 할당을 받으며 이들 사이의 비율은 고정되어 있습니다. 이 사실은 비용을 최적화하는 데 사용될 수 있습니다. 하나의 조회마다 20개의 검색을 얻습니다(초당). 주로 조회 한계에 도달하지만 검색에는 충분한 헤드룸이 있습니다. 데이터를 일부 리모델링하거나 클라이언트 측에서 더 많은 작업을 수행하여 조회에 대한 의존도를 줄일 수 있습니다.
그러나 여기서 결론은 서드파티 라이브러리 또는 프레임워크가 편의성보다 비용을 먼저 최적화한다고 가정할 수 없다는 것입니다. 플러그인을 사용하여 다중 지속성 계층을 지원하는 클라이언트 측 프레임워크는 이러한 상황을 인식하지 못하거나 이와 같이 절충하지 못할 수 있습니다.
특정 도구를 커미트하기 전에 서드파티 라이브러리 또는 프레임워크 호환성을 확인하는 것이 좋습니다.
또한 비율이 HTTP API 엔드포인트 호출과 직접적으로 동등하지 않다는 것도 이해해야 합니다. 예를 들어, 대량 업데이트는 해당 구성요소 문서 쓰기에 따라 계산될 것으로 예상해야 합니다.
- IBM 퍼블릭 클라우드의 플랜 및 가격 책정에 대한 IBM Cloudant 문서
로깅은 진행 상황을 확인하는 데 도움이 됨
IBM Cloudant 의 각 API 호출, 요청된 내용, 응답에 걸린 시간을 나타내는 로그는 IBM Cloud 기반 서비스에 대한 분석 및 보고를 위해 자동으로 IBM Cloud Logs 에 스풀링될 수 있습니다. 이 데이터는 요청량, 성능, 애플리케이션이 IBM Cloudant 서비스에 대해 프로비저닝된 용량을 초과하고 있는지 여부를 파악하는 데 유용합니다.
IBM Cloud Logs 다양한 보존 기간과 로그 소비 계층을 제공하는 계량화된 서비스입니다. 계층을 통해 데이터를 COS에 보관하고, 콜드 또는 핫 검색하고, 다양한 비용으로 알림을 받을 수 있습니다. 데이터의 슬라이스 및 집계를 시각적 대시보드에 빌드하여 IBM Cloudant 트래픽을 한 눈에 볼 수 있습니다. 자세한 정보는 다음 문서를 참조하십시오.
HTTP 트래픽 압축
코드가 다음 형식의 데이터를 처리할 수 있음을 나타내는 HTTP 헤더를 요청에 제공하면 IBM Cloudant에서 해당 JSON 응답을 압축합니다.
Request:
> GET /cars/_all_docs?limit=5&include_docs=true HTTP/2
> Host: myhost.cloudant.com
> Accept: */*
> Accept-Encoding: deflate, gzip
Response:
< HTTP/2 200
< content-type: application/json
< content-encoding: gzip
압축된 컨텐츠는 압축 해제된 동등한 컨텐츠 크기의 일부를 차지합니다. 즉, IBM Cloudant의 서버에서 애플리케이션으로 데이터를 전송하는 데 더 짧은 시간이 걸립니다.
Content-encoding 헤더를 사용하여 HTTP 요청 본문을 압축하도록 선택할 수도 있습니다. 이 방법은 IBM Cloudant 로 문서를 작성할 때 데이터 전송 시간을 줄이는 데 도움이 됩니다.