isolation이 유용한 경우isolation은 지속적인 수집이 이루어지는 대규모 배포를 대상으로 합니다. 저장 데이터가 월 약 100TB 미만이라면 일반적으로 하나의 읽기-쓰기 service가 두 워크로드를 모두 감당하므로 두 번째 service는 필요하지 않을 가능성이 높습니다. 월별 compressed 볼륨을 추정하려면 용량 산정 모델을 사용하십시오.
읽기와 쓰기를 분리해야 하는 이유
- 쓰기가 읽기 성능을 떨어뜨리지 않습니다. 지속적인 OpenTelemetry 수집(삽입 작업 자체와 그 뒤를 잇는 백그라운드 머지)은 대시보드 및 검색 쿼리와 CPU 및 메모리를 두고 경쟁합니다. 수집이 실행되는 동안 읽기 지연 시간이 눈에 띄게 나빠졌다가 수집이 멈추면 회복될 수 있습니다.
- 읽기가 쓰기를 방해하지 않습니다. 경합은 양방향으로 발생합니다. 무거운 애드혹 쿼리나 비용이 큰 대시보드 렌더링은 service의 메모리를 소진시켜 삽입을 단순히 느리게 만드는 정도가 아니라 아예 실패시킬 수 있습니다.
- 읽기 전용 컴퓨트는 전적으로 쿼리에만 사용됩니다. 읽기 전용 service는 system tables를 제외하면 백그라운드 머지를 수행하지 않습니다. 또한 머지 때문에 깨어 있는 상태가 유지될 수 있는 읽기-쓰기 service와 달리, 지연 없이 유휴 상태로 전환됩니다.
- 양쪽 용량을 각각 산정합니다. 용량 산정 모델은 수집 컴퓨트와 쿼리 컴퓨트를 별도로 추정하며, warehouse를 사용하면 각각을 독립적인 service로 프로비저닝할 수 있습니다. 모델의 1 QPS 기준선을 넘어서면 쿼리 컴퓨트가 대부분을 차지합니다. 5 QPS를 가정한 실제 예시에서는 수집에 58 vCPU, 쿼리에 290 vCPU가 산출되므로, 작은 쓰기 service가 훨씬 큰 읽기 service에 데이터를 공급하는 구성이 가능합니다.
- 유휴 상태 전환과 자동 스케일링은 service별로 설정합니다. 각 service는 자체 레플리카 수, 자동 스케일링 및 자동 유휴 상태 전환 설정을 가지므로, 쓰기 service는 지속적인 수집을 위해 항상 켜 두고 읽기 service는 업무 시간 외에 유휴 상태로 전환되도록 할 수 있습니다.
- 스토리지는 중복되지 않습니다. warehouse 내의 service들은 동일한 객체 스토리지 폴더와 동일한 테이블을 공유하며, 스토리지 요금은 한 번만 청구됩니다.
- 엔드포인트별로 액세스를 제한할 수 있습니다. IP 액세스 목록은 service별로 적용되므로, 쓰기 엔드포인트는 collector에서만, 읽기 엔드포인트는 ClickStack 배포에서만 연결할 수 있도록 제한할 수 있습니다. 네트워크 액세스 제어 가이드를 참조하십시오.
아키텍처
권장 토폴로지는 수집용 읽기-쓰기 서비스 1개와 ClickStack용 읽기 전용 서비스 1개로 구성된 warehouse입니다:
토폴로지를 계획할 때 다음 사항을 유념하십시오:
- warehouse의 첫 번째 서비스는 항상 읽기-쓰기이며, 서비스 유형은 생성 시점에 고정됩니다. 읽기 전용과 읽기-쓰기를 전환하려면 warehouse에 새 서비스를 생성하십시오.
- warehouse 내 모든 서비스는 동일한 클라우드 제공업체, 리전, ClickHouse 버전 및 Keeper를 공유하며, 기본 서비스의 upgrade schedule을 따릅니다.
- 수집에는 읽기-쓰기 서비스를 하나만 사용하십시오. 머지는 스토리지를 공유하는 모든 읽기-쓰기 서비스에 분배되므로, 한 서비스에서 발생한 삽입에 대한 머지가 다른 서비스에서 실행될 수 있습니다. 그 다른 서비스가 부하가 큰 쿼리까지 처리하고 있다면, 해당 쿼리와 머지가 같은 서비스의 CPU 및 메모리를 두고 경합하게 되어 첫 번째 서비스의 삽입에 대한 머지가 느려지고, 결과적으로 삽입 performance도 함께 저하됩니다. 쿼리 워크로드는 읽기 전용 서비스에서 처리하고, 머지를 수집과 분리해야 하는 경우에만 두 번째 읽기-쓰기 서비스를 추가하십시오.
격리된 배포 환경 설정하기
1
읽기-쓰기 서비스 준비
기존 서비스 또는 새 warehouse의 기본 서비스를 수집용으로 사용하고, 용량 산정 모델에서 산출한 수집 컴퓨트 규모에 맞게 크기를 지정하십시오.이 서비스에 데이터베이스와 수집 전용 사용자를 생성하십시오. warehouse 내의 모든 서비스는 액세스 제어(access controls)를 공유하므로, 여기서 생성한 사용자는 warehouse의 모든 서비스에서 사용할 수 있습니다:
openssl rand -base64 24와 같은 도구로 비밀번호를 생성하고, 매니페스트나 셸 이력에 남기지 말고 시크릿 관리 도구에 저장하십시오. 자세한 내용은 수집 사용자 생성 가이드를 참조하십시오.이 서비스가 이미 웨어하우스에 속해 있다면, 같은 웨어하우스의 다른 서비스가 유휴(idled) 상태일 때 데이터베이스 수준 DDL이 멈출 수 있다는 점에 유의하십시오. 관리 및 DDL을 참조하십시오.2
웨어하우스에 읽기 전용 서비스를 추가합니다
ClickHouse Cloud 콘솔에서 방금 준비한 서비스의 더하기 기호를 클릭해 해당 데이터를 공유하는 두 번째 서비스를 생성하십시오. 서비스 유형으로 읽기 전용을 선택하고, 용량 산정 모델에서 산출된 쿼리 컴퓨트에 맞게 크기를 지정하십시오.전체 절차는 웨어하우스 설정 방법 가이드를 참조하십시오.
3
Point 수집을 읽기-쓰기 서비스로 지정
수집 사용자로 인증하여 읽기-쓰기 서비스 엔드포인트로 데이터를 내보내도록 collector를 구성하십시오:자세한 내용은 collector 구성 옵션을 참조하고, Vector 및 기타 수집 경로에 대해서는 그에 상응하는 설정을 참조하십시오.읽기 전용 엔드포인트로 전송된 쓰기 요청은 거부되므로, collector는 항상 읽기-쓰기 서비스를 대상으로 지정해야 합니다.
4
ClickStack이 읽기 전용 서비스를 사용하도록 구성합니다
ClickStack UI는 항상 ClickHouse Cloud 콘솔에서 실행을 시작한 ClickHouse 서비스에 연결됩니다. 읽기 전용 컴퓨트에서 실행하려면 다음과 같이 하십시오:
- ClickHouse Cloud 콘솔에서 읽기 전용 서비스를 선택합니다.
- 왼쪽 탐색 메뉴에서 ClickStack을 선택합니다.
5
분할을 확인합니다
ClickStack에서 검색을 실행하거나 대시보드를 연 다음, 쿼리가 어느 노드에서 처리되었는지 확인하십시오. 여기서 결과가 비어 있다고 해서 그것만으로 쿼리가 다른 곳으로 갔다는 뜻은 아닙니다. 이 쿼리를 사용할 때 유의할 점이 두 가지 있습니다. 유휴 상태로 전환된 서비스는 행을 반환할 수 없으므로 완전한 결과가 필요하다면 먼저 해당 서비스를 깨워야 합니다. 또한
system 테이블은 쿼리를 실행한 노드에 기록되므로, 레플리카가 두 개 이상인 서비스에서는 모든 레플리카를 조회하기 위해 default 클러스터 이름과 함께 clusterAllReplicas를 사용해야 합니다. 읽기 전용 서비스에서는 다음과 같이 ClickStack 쿼리가 표시됩니다:system.query_log는 주기적으로(기본값은 7.5초마다) 플러시되므로, 검색 직후에 실행한 쿼리는 아직 보이지 않을 수 있습니다. 잠시 기다린 후 다시 실행하거나, 권한이 있다면 SYSTEM FLUSH LOGS로 플러시를 강제하십시오.트래픽의 출처를 구분해 주는 것은 user와 http_user_agent를 기준으로 한 그룹화입니다. 소스가 어떤 테이블을 가리키든 관계없이 UI와 SQL 콘솔, 그리고 해당 엔드포인트에 연결하는 그 외 모든 것을 구분해 줍니다. is_initial_query = 1로 필터링하면 제출된 형태 그대로 쿼리당 한 행만 남습니다. 분산 실행에서 발생하는 보조 쿼리와 materialized view를 평가하는 내부 쿼리는 is_initial_query = 0으로 별도 기록됩니다.읽기-쓰기 서비스에서 동일한 쿼리를 실행하면 수집 사용자의 삽입 작업만 표시되고 ClickStack 쿼리 트래픽은 나타나지 않아야 합니다.각 서비스에서 차례로 쿼리를 실행하는 것이 확실한 확인 방법입니다. default 클러스터에는 현재 연결된 서비스의 레플리카만 포함되기 때문입니다. warehouse 전체를 집계해서 보려면 대신 all_groups.default 클러스터 이름을 사용하십시오:hostName()은 서비스가 아닌 레플리카를 식별하므로, 특정 서비스의 활동으로 구분하려면 해당 서비스에 직접 쿼리를 실행하십시오.머지와 수집 분리
매우 높은 수집률이 지속되면 삽입 자체보다 머지가 수집 서비스의 주된 비용 요소가 됩니다. 머지는 스토리지를 공유하는 모든 읽기-쓰기 서비스에 걸쳐 할당되므로, 다른 용도로 의도한 서비스에 머지 작업이 배정될 수도 있습니다. 이러한 배포 환경에서는 머지를 수집 서비스에서 완전히 분리하여 다음과 같은 3개 서비스 토폴로지를 구성할 수 있습니다:지원 요청 필요읽기-쓰기 서비스에서 머지를 비활성화하는 설정은 Cloud console에서 변경할 수 없습니다. 특정 서비스에 적용하려면 지원팀에 문의하십시오.
- 두 읽기-쓰기 서비스 모두 auto-idling에 의존하지 마십시오. 머지가 비활성화된 서비스라도 warehouse 내 다른 곳에서 발생한 삽입으로 생성된 파트 다운로드 및 삭제 이벤트를 처리하며, 머지되지 않은 파트 수가 많으면 그 자체만으로도 유휴 상태 전환이 차단될 수 있습니다. 두 읽기-쓰기 서비스가 모두 상시 가동된다고 가정하여 계획하십시오.
- 두 읽기-쓰기 서비스에서는 쿼리를 실행하지 마십시오. 읽기-쓰기 서비스에서 무거운
SELECT쿼리를 실행하면 머지 작업과 CPU 및 메모리를 두고 경쟁하게 되며, 이는 바로 이 토폴로지가 방지하려는 장애 유형입니다. 위에서 설명한 대로 ClickStack이 읽기 전용 서비스를 바라보도록 설정하십시오. - 뮤테이션이 있는 경우, 이를 실행하는 서비스에서 추적됩니다. 관측성 환경에서 뮤테이션은 드뭅니다. ClickStack의 스키마는
ttl_only_drop_parts = 1을 설정하므로, 일반적인 보존 정책은 TTL 머지 과정에서 만료된 파트 전체를 삭제하며 행을 뮤테이션으로 제거하지 않습니다. 뮤테이션을 발생시키는ALTER를 수집 서비스에 제출하더라도 해당 작업은 머지 서비스에서 수행되며, 그 진행 상황도 수집 서비스가 아닌 머지 서비스의system.mutations에 나타납니다.
관리 및 DDL
다음을 포함한 모든 스키마 변경은 읽기-쓰기 서비스에서 실행해야 합니다:- 테이블 생성 - 최초 수집 시 ClickStack collector가 자동으로 수행
- 보존 기간 변경을 위한 TTL 수정
- 쿼리 가속을 위한 materialized view 생성
- 스킵 인덱스, 프로젝션 및 기타 성능 최적화 추가
에이전트형 워크로드 분리
ClickStack MCP 서버를 통해 연결된 AI 어시스턴트도 대시보드와 마찬가지로 읽기 트래픽이지만, 부하 패턴이 다릅니다. 장애를 조사하는 에이전트는 사전에 정해두지 않은 범위에 대해 짧은 시간 안에 수많은 탐색적 쿼리를 실행합니다. 에이전트와 UI가 하나의 읽기 전용 서비스를 공유하면, 이러한 버스트가 같은 장애 상황에서 엔지니어가 보고 있는 대시보드보다 앞서 처리되게 됩니다. 여기에도 동일한 warehouse 패턴이 적용됩니다. 즉, 에이전트에 전용 읽기 전용 컴퓨트를 제공하십시오.1
두 번째 읽기 전용 서비스 추가
위 설정과 동일한 방식으로 warehouse에 읽기 전용 서비스를 하나 더 생성하십시오. 이 서비스는 UI를 담당하는 서비스와 동일한 테이블을 읽으므로 복사할 데이터가 없습니다.그다음 ClickStack을 읽기 전용 서비스로 지정하기에서 설명한 것처럼, Cloud Console에서 해당 서비스에 대해 ClickStack을 한 번 실행하십시오. Cloud MCP는 MCP 자체뿐 아니라 ClickStack이 활성화된 서비스도 필요로 합니다. MCP 사전 요구 사항을 참조하십시오.용량 산정 모델의 대시보드 QPS가 아니라 에이전트에서 예상되는 쿼리 부하에 맞춰 크기를 산정하고, auto-idling은 활성화된 상태로 두십시오. 에이전트형 사용은 일반적으로 간헐적이므로, 조사 작업 사이에 서비스가 유휴 상태로 전환될 수 있습니다.
2
해당 서비스에서 MCP 활성화
ClickHouse Cloud 콘솔에서 읽기 전용 서비스를 열고 Connect를 클릭한 후 Connect with MCP를 선택하여 활성화하십시오. 원격 MCP 서버 활성화를 참조하십시오.
3
MCP 클라이언트를 해당 서비스로 지정
Cloud MCP 엔드포인트는 모든 서비스에서 동일합니다. 요청은 어떤 MCP 클라이언트든 이 헤더를 전달할 수 있습니다. Cursor, VS Code 등에서의 동등한 구성은 특정 서비스 지정을 참조하십시오.
x-service-id 헤더에 따라 라우팅되며, 이 헤더가 없으면 계정에서 처음 사용한 ClickStack 서비스로 전달됩니다. 기존 MCP 구성을 복사한 뒤 새 읽기 전용 서비스의 ID를 담은 헤더를 추가하십시오.알림
ClickStack은 알림이 생성된 서비스에서 해당 알림을 평가하므로, 알림은 UI와 동일한 컴퓨트, 즉 이 토폴로지에서는 읽기 전용 서비스에서 실행됩니다.관리형 ClickStack알림을 활성화하려면 Service Admin 권한을 가진 사용자가 최소 한 번은 ClickStack에 로그인해야 합니다. 이 과정에서 알림 쿼리를 실행하는 전용 데이터베이스 사용자가 프로비저닝되며, 해당 사용자는 warehouse 내 모든 서비스에서 공유됩니다. 관리형 ClickStack에 대한 액세스 부여 가이드를 참조하십시오.
알림 평가 격리
알림 부하는 중앙에서 라우팅할 수 없습니다. 알림은 사용자가 직접 생성하기 때문입니다. ClickStack에서 알림을 추가하면 그 알림은 사용자가 작업 중인 service에 추가되고, 해당 service의 컴퓨트에서 평가됩니다. 특정 service의 알림을 다른 곳으로 옮기는 SETTING은 없습니다. 격리할 수 있는 것은 중앙에서 소유하는 알림, 즉 플랫폼 팀이 organization 전체를 위해 유지 관리하는 알림입니다. 이러한 알림은 보통 가장 자주 평가되는 알림이기도 합니다. 이런 알림에는 warehouse 내에 전용 읽기 전용 service를 할당하고, 그 service에서 실행한 ClickStack에서 알림을 생성하십시오.
남은 절충 관계는 state가 service 단위로 존재한다는 점에서 비롯됩니다.
- 공용 알림과 이에 딸린 dashboards는 알림 service에만 존재하며, 쿼리 service에서 작업하는 사용자에게는 보이지 않습니다. 알림은 어느 쪽이든 동일한 대상으로 전달되므로, 사용자가 잃는 것은 정의에 대한 가시성일 뿐 알림 기능 자체는 아닙니다.
- 알림 service의 sources는 별개의 객체입니다. 기본 OpenTelemetry schema를 사용하는 source는 자동으로 감지되지만, 사용자 정의 source는 알림이 참조할 수 있도록 해당 service에서도 구성해야 합니다.