ClickHouse 사용 및 테이블 디자인 소개

PostgreSQL과의 차이점

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

ClickHouse는 PostgreSQL과 같은 전통적인 OLTP(온라인 트랜잭션 처리) 데이터베이스와 많은 차이점을 가지고 있습니다. ClickHouse의 기본 아키텍처는 다르며, 처리방식은 전통적인 데이터베이스보다 훨씬 CPU 중심적입니다. ClickHouse는 불변성이 핵심 요소인 로그 중심 데이터베이스입니다. 이러한 방식의 장점은 잘 문서화되어 있지만, 업데이트를 훨씬 어렵게 만듭니다. UPDATE/DELETE 지원을 제공하는 작업에 대한 ClickHouse 문서를 참조하세요. 이러한 작업은 빈번하게 발생하지 않아야 합니다.

테이블 디자인 시 이러한 차이점이 중요합니다. 다음 중 하나일 수 있습니다:

  • 업데이트가 필요하지 않음(최상의 경우)
  • 필요하다면, 쿼리 실행 중에 실행되어서는 안 됩니다.

ACID 호환성

ClickHouse는 트랜잭션 지원에 대해 약간 다른 개요를 가지고 있으며, 보증이 특정 테이블에 삽입된 데이터 블록까지만 적용된다는 것을 확인할 수 있습니다. 자세한 내용은 트랜잭션(ACID) 지원 문서를 참조하세요.

단일 작성에서 여러 삽입은 하나의 로컬 테이블을 지원하는 분산 엔진을 통한 트랜잭션 지원을 피해야 합니다.

ClickHouse는 분석 쿼리에 대한 최고 수준의 지원을 제공하기 위해 많은 노력을 기울이고 있습니다. 집계와 같은 작업은 매우 빠르며 이러한 기능을 강화하는 여러 가지 기능이 있습니다. ClickHouse에는 집계에 대한 자세한 내용을 다루는 좋은 블로그 게시물이 있습니다.

기본 인덱스, 정렬 인덱스 및 딕셔너리

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

특히 ClickHouse에서 데이터베이스 인덱스 디자인이 PostgreSQL과 같은 트랜잭션 데이터베이스와 어떻게 다른지에 주목하세요.

기본 인덱스 디자인은 쿼리 성능에 매우 중요한 역할을 하며 주의 깊게 명시되어야 합니다. 대부분의 쿼리는 전체 데이터 스캔이 더 오래 걸리게 되므로 기본 인덱스에 의존해야 합니다.

MergeTree Table 엔진(ClickHouse의 기본 테이블 엔진)에서 인덱스가 쿼리 성능에 미치는 영향을 알아보려면 쿼리에서 기본 키 및 인덱스를 확인하세요.

ClickHouse의 보조 인덱스는 다른 시스템에서 제공되는 것과 다릅니다. 데이터 스킵 인덱스로도 불리며, 데이터 블록을 건너뛰기 위해 사용됩니다. 데이터 스킵 인덱스에 대한 문서를 참조하세요.

ClickHouse는 또한 딕셔너리를 제공하며, 이는 외부 인덱스로 사용될 수 있습니다. 딕셔너리는 메모리에서 로드되어 쿼리 실행 중에 값 조회에 사용될 수 있습니다.

데이터 유형 및 파티셔닝

ClickHouse는 SQL 호환 데이터 유형LowCardinality, UUID, Maps, Nested와 같은 몇 가지 특수한 데이터 유형을 제공합니다. Nested는 컬럼 내부에 테이블을 시뮬레이션하는 흥미로운 기능입니다.

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

권장 읽기:

샤딩과 복제

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

ClickHouse 문서에서 분산 및 샤딩 섹션과 함께 ClickHouse Keeper라는 구성 요소를 통해 Zookeeper 또는 ClickHouse의 호환 API를 사용하여 합의를 유지하는 방법을 참조하세요.

노드를 설정한 후에는 클라이언트로부터 숨겨진 상태가될 수 있으며 쓰기 및 읽기 쿼리가 모든 노드에 대해 발행될 수 있습니다.

대부분의 경우 클러스터는 일정한 수의 노드(~샤드)로 시작됩니다. 샤드 재분배은 운영적으로 매우 중요하며 철저한 테스트가 필요합니다.

Replication은 MergeTree 테이블 엔진에서 지원되며 자세한 정보는 복제 섹션을 참조하세요. ClickHouse는 분산 조정 구성 요소(Zookeeper 또는 ClickHouse Keeper)에 의존하여 합의에 참여하는 노드를 추적합니다. 복제는 비동기적이고 멀티 리더입니다. 삽입은 모든 노드에 전달될 수 있으며 일부 지연이 발생할 수 있습니다. 원하는 경우 특정 노드에 대한 고정성을 사용하여 읽기에서 최신 데이터를 확인할 수 있습니다.

Materialized views

ClickHouse의 가장 중요한 특징 중 하나는 materialized views입니다. 기능적으로, 이들은 ClickHouse의 insert 트리거와 유사합니다. Materialized views는 여러 웹사이트에서 자세히 문서화되어 있는 다양한 유스케이스에 사용될 수 있습니다.

공식 문서의 섹션을 읽어서 이들이 어떻게 동작하는지에 대해 더 잘 이해하는 것을 권장합니다.

문서를 인용하면 다음과 같습니다:

ClickHouse의 Materialized views는 insert 트리거와 비슷하게 구현되어 있습니다. 뷰 쿼리에 어떤 집계(aggregation)가 있다면, 이는 새롭게 삽입된 데이터의 일괄처리(batch)에만 적용됩니다. 소스 테이블의 기존 데이터(예: 업데이트, 삭제, 파티션 삭제 등)의 변경 사항은 materialized view에 영향을 주지 않습니다.

안전하고 합리적인 기본값

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

사용자

파일: users.xmlconfig.xml.

주제 보안 요구사항 이유
user_name/password 사용자 이름은 비워둘 수 없으며 암호는 password_sha256_hex를 사용해야 하며 비워둘 수 없습니다. plaintextpassword_double_sha1_hex는 보안에 취약합니다. 사용자 이름이 지정되지 않으면, 기본값이 암호 없이 사용됩니다.
access_management 서버 구성 파일인 users.xmlconfig.xml을 사용하세요. SQL-driven workflow를 피하세요. SQL-driven workflow는 최소한 하나의 사용자가 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 <interserver_https_port>9010</interserver_https_port>)를 선호하여 interserver_http_host를 비활성화하세요. 데이터 이동 중 데이터 암호화. (층별방어 원칙)

저장소

주제 보안 요구 사항 이유
권한 설정 ClickHouse는 기본적으로 clickhouse 사용자로 실행됩니다. root로 실행할 필요가 없습니다. /etc/clickhouse-server, /var/lib/clickhouse, /var/log/clickhouse-server 폴더에 대한 최소한의 권한 원칙을 사용하세요. 이러한 폴더는 clickhouse 사용자 및 그룹에 속해야 하며 다른 시스템 사용자가 액세스하지 않아야 합니다. 기본 암호, 포트 및 규칙은 “열려 있는 문”입니다. (안전하게 실패하고 안전한 기본값 사용 원칙)
암호화 RED 데이터가 처리된다면 로그 및 데이터에 대해 암호화된 저장소를 사용하세요. Kubernetes에서 사용되는 StorageClass는 암호화되어야 합니다. GKEEKS는 이미 취약한 자료의 모든 데이터를 암호화합니다. 이 경우 자체 키를 사용하는 것이 최선이지만 필수는 아닙니다. 데이터를 안정하게 보호합니다. (층별 방어)

로깅

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

예시 가리기 규칙

<query_masking_rules>
    <rule>
        <name>주민등록번호 가리기</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>