ClickHouse 사용 및 테이블 설계 소개

PostgreSQL과의 차이점

소개 페이지는 ClickHouse에 대한 개요를 제공하는 데 매우 유용합니다.

ClickHouse는 PostgreSQL과 같은 전통적인 OLTP(온라인 트랜잭션 처리) 데이터베이스와 많은 차이점이 있습니다. 기본 아키텍처가 약간 다르며, 처리 방식이 전통적인 데이터베이스보다 훨씬 더 CPU 집약적입니다.

ClickHouse는 불변성(immutability)이 핵심 요소인 로그 중심 데이터베이스입니다. 이러한 접근 방식의 장점은 잘 문서화되어 있습니다 [1] 다만 업데이트가 훨씬 더 어려워집니다. UPDATE/DELETE 지원을 제공하는 작업에 대한 ClickHouse 문서를 참조하세요. 이러한 작업이 빈번하게 수행되지 않아야 한다는 점이 눈에 띕니다.

이러한 구분은 테이블을 설계할 때 중요합니다. 다음 중 하나입니다:

  • 업데이트가 필요하지 않음(최상의 경우)
  • 업데이트가 필요하다면 쿼리 실행 중에 실행되지 않아야 합니다.

ACID 호환성

ClickHouse는 트랜잭션 지원에 대한 약간 다른 개요를 가지고 있으며, 보장은 특정 테이블에 삽입된 데이터 블록까지 적용됩니다. 자세한 내용은 트랜잭셔널(ACID) 지원 문서를 참조하세요.

단일 쓰기에서 여러 삽입은 피해야 하며, 여러 테이블에 걸친 트랜잭션 지원은 물질화된 뷰에서만 제공됩니다.

ClickHouse는 분석 쿼리에 대한 최고의 지원을 제공하는 데 중점을 두고 있습니다. 집계와 같은 작업은 매우 빠르며 이러한 기능을 강화하기 위한 여러 기능이 있습니다.

ClickHouse의 집계에 관한 상세 내용을 다룬 좋은 블로그 게시물이 있습니다.

기본 인덱스, 정렬 인덱스 및 사전

ClickHouse의 인덱스에 대한 이해를 위해 “ClickHouse의 기본 인덱스에 대한 실용적인 소개” 를 읽는 것이 강력히 권장됩니다.

특히 ClickHouse에서의 데이터베이스 인덱스 설계가 PostgreSQL과 같은 트랜잭션 데이터베이스와 어떻게 다르다 는 점에 주목하세요.

기본 인덱스 설계는 쿼리 성능에서 매우 중요한 역할을 하며 신중하게 선언해야 합니다. 거의 모든 쿼리는 기본 인덱스에 의존해야 하며, 전체 데이터 스캔은 시간이 더 걸리게 됩니다.

MergeTree 테이블 엔진(ClickHouse의 기본 테이블 엔진)에서 쿼리 성능에 인덱스가 미치는 영향을 배우기 위해 쿼리에서의 기본 키 및 인덱스 문서를 읽으세요.

ClickHouse의 보조 인덱스는 다른 시스템에서 제공되는 것과 다릅니다. 이들은 데이터 블록을 건너뛰는 데 사용되므로 데이터 건너뛰기 인덱스(data-skipping indexes)라고도 불립니다. 데이터 건너뛰기 인덱스 문서를 참조하세요.

ClickHouse는 외부 인덱스로 사용될 수 있는 “사전”도 제공합니다. 사전은 메모리에서 로드되며 쿼리 실행 시간에 값을 조회하는 데 사용할 수 있습니다.

데이터 유형 및 파티셔닝

ClickHouse는 SQL 호환 데이터 유형을 제공하며, 몇 가지 전문화된 데이터 유형도 제공합니다. 예를 들어:

테이블을 설계할 때 가장 중요한 디자인 측면 중 하나는 파티셔닝 키입니다. 파티션은 임의의 표현일 수 있지만 일반적으로는 월, 일 또는 주와 같은 시간 지속성을 가집니다. ClickHouse는 가장 작은 파티션 세트를 사용하여 읽는 데이터를 최소화하려고 최선의 노력을 기울입니다.

제안된 읽기 자료:

샤딩 및 복제

샤딩은 데이터를 여러 ClickHouse 노드로 분할하여 처리량을 증가시키고 지연 시간을 줄일 수 있게 해주는 기능입니다. 샤딩 기능은 로컬 테이블로 지원되는 분산 엔진을 사용합니다. 분산 엔진은 데이터를 저장하지 않는 “가상” 테이블로, 데이터를 삽입하고 쿼리하기 위한 인터페이스로 사용됩니다.

ClickHouse 문서복제 및 샤딩에 대한 이 섹션을 참조하세요. ClickHouse는 합의를 유지하기 위해 Zookeeper 또는 ClickHouse Keeper라는 구성 요소를 통해 자체 호환 API를 사용할 수 있습니다.

노드가 설정된 후, 클라이언트로부터 보이지 않게 될 수 있으며, 쓰기 및 읽기 쿼리를 어느 노드에나 발행할 수 있습니다.

대부분의 경우, 클러스터는 고정된 수의 노드(~샤드)로 시작합니다. 샤드 재조정은 운영적으로 무겁고 철저한 테스트가 필요합니다.

복제는 MergeTree 테이블 엔진에 의해 지원됩니다. 복제 정의 방법에 대한 자세한 내용은 복제 섹션에서 확인하세요. ClickHouse는 쿼럼에 참여하는 노드를 추적하기 위해 분산 조정 구성 요소(Zookeeper 또는 ClickHouse Keeper)에 의존합니다. 복제는 비동기이며 다중 리더입니다. 삽입은 어떤 노드에나 발행할 수 있으며, 일부 지연을 동반하여 다른 노드에서도 나타날 수 있습니다. 원한다면 특정 노드에 고정함으로써 읽기가 최신 작성 데이터를 확인하도록 할 수 있습니다.

물리화된 뷰

ClickHouse의 정의적인 기능 중 하나는 물리화된 뷰입니다. 기능적으로 이들은 ClickHouse의 삽입 트리거와 유사합니다.

작동 방식을 더 잘 이해하기 위해 공식 문서의 섹션을 읽을 것을 권장합니다.

문서를 인용하자면:

ClickHouse의 물리화된 뷰는 삽입 트리거와 유사하게 구현됩니다. 뷰 쿼리에 집계가 있는 경우, 이는 막 새로 삽입된 데이터 배치에만 적용됩니다. 기존 소스 테이블의 데이터 변경(업데이트, 삭제, 파티션 드롭 등)은 물리화된 뷰를 변경하지 않습니다.

안전하고 합리적인 기본값

ClickHouse 인스턴스는 이러한 보안 권장 사항을 따라야 합니다:

사용자

파일: users.xmlconfig.xml.

주제 보안 요구 사항 이유
user_name/password 사용자 이름은 비어 있을 수 없습니다. 비밀번호는 password_sha256_hex를 사용해야 하며 비어 있을 수 없습니다. plaintextpassword_double_sha1_hex는 안전하지 않습니다. 사용자 이름이 지정되지 않으면, default가 비밀번호 없이 사용됩니다.
access_management 서버 구성 파일users.xmlconfig.xml을 사용합니다. SQL 기반 워크플로는 피합니다. SQL 기반 워크플로는 적어도 하나의 사용자가 access_management를 가지고 있음을 의미하며, 이는 구성 파일을 통해 피할 수 있습니다. 이 파일들은 감사 및 모니터링이 더 쉽습니다. “구성 방법 두 가지로 동일한 액세스 엔터티를 동시에 관리할 수 없습니다.”
user_name/networks <ip>, <host>, <host_regexp> 중 적어도 하나는 설정해야 합니다. <ip>::/0</ip>를 사용하여 모든 네트워크에 대한 접근을 열지 마십시오. 네트워크 제어. (주의 깊게 신뢰하라 원칙)
user_name/profile 프로필을 사용하여 여러 사용자 간에 유사한 속성을 설정하고 제한을 설정합니다(사용자 인터페이스에서). 최소 권한 원칙 및 제한.
user_name/quota 가능한 경우 사용자에 대한 할당량을 설정합니다. 일정 기간 동안 자원 사용을 제한하거나 자원 사용을 추적합니다.
user_name/databases 데이터에 대한 접근을 제한하며, 전체 접근 권한이 있는 사용자는 피합니다. 최소 권한 원칙.

네트워크

파일: config.xml

주제 보안 요구 사항 이유
mysql_port 엄격히 필요하지 않는 한 MySQL 접근을 비활성화합니다:
<!-- <mysql_port>9004</mysql_port> -->.
불필요한 포트 및 기능 노출을 차단합니다. (심층 방어 원칙)
postgresql_port 엄격히 필요하지 않는 한 PostgreSQL 접근을 비활성화합니다:
<!-- <mysql_port>9005</mysql_port> -->
불필요한 포트 및 기능 노출을 차단합니다. (심층 방어 원칙)
http_port/https_port & tcp_port/tcp_port_secure SSL-TLS를 구성하고 비 SSL 포트를 비활성화합니다:
<!-- <http_port>8123</http_port> -->
<!-- <tcp_port>9000</tcp_port> -->
그리고 안전한 포트를 활성화합니다:
<https_port>8443</https_port>
<tcp_port_secure>9440</tcp_port_secure>
전송 중 데이터를 암호화합니다. (심층 방어 원칙)
interserver_http_host ClickHouse가 클러스터로 구성된 경우 interserver_https_host(<interserver_https_port>9010</interserver_https_port>)의 이점을 위해 interserver_http_host를 비활성화합니다. 전송 중 데이터를 암호화합니다. (심층 방어 원칙)

저장소

주제 보안 요구 사항 이유
권한 ClickHouse는 기본적으로 clickhouse 사용자로 실행됩니다. root로 실행할 필요는 없습니다. 다음 폴더에 대해 최소한의 권한 원칙을 사용하세요: /etc/clickhouse-server, /var/lib/clickhouse, /var/log/clickhouse-server. 이러한 폴더는 clickhouse 사용자 및 그룹에 속해야 하며, 다른 시스템 사용자는 접근할 수 없어야 합니다. 기본 비밀번호, 포트 및 규칙은 “열린 문”입니다. (Fail securely & use secure defaults 원칙)
암호화 RED 데이터를 처리하는 경우 로그 및 데이터에 대해 암호화된 저장소를 사용하세요. Kubernetes에서 사용되는 StorageClass는 암호화되어야 합니다. GKEEKS는 이미 모든 데이터를 안정적으로 암호화합니다. 이 경우, 자체 키를 사용하는 것이 최상의 방법이지만 필수는 아닙니다. 데이터가 안정적으로 암호화됩니다. (Defense in depth)

로깅

주제 보안 요구 사항 이유
logger Logerrorlog반드시 정의되어야 하며 clickhouse에 의해 쓰기 가능해야 합니다. 로그가 저장되도록 하세요.
SIEM GitLab.com에서 호스팅되는 경우, ClickHouse 인스턴스 또는 클러스터는 반드시 우리의 SIEM에 로그를 보고해야 합니다 (내부 링크). GitLab은 중요한 정보 시스템 활동을 로그합니다.
민감한 데이터 로그 민감한 데이터가 로깅될 수 있는 경우 쿼리 마스킹 규칙을 반드시 사용해야 합니다. 예시 마스킹 규칙을 참조하세요. 열 수준 암호화를 사용하여 로그에서 민감한 데이터(키)가 유출될 수 있습니다.

예시 마스킹 규칙

<query_masking_rules>
    <rule>
        <name>SSN 숨기기</name>
        <regexp>(^|\D)\d{3}-\d{2}-\d{4}($|\D)</regexp>
        <replace>000-00-0000</replace>
    </rule>
    <rule>
        <name>암호화/복호화 인수 숨기기</name>
        <regexp>
           ((?:aes_)?(?:encrypt|decrypt)(?:_mysql)?)\s*\(\s*(?:'(?:\\'|.)+'|.*?)\s*\)
        </regexp>
        <replace>\1(???)</replace>
    </rule>
</query_masking_rules>