ClickHouse 사용 및 테이블 설계 소개
PostgreSQL과의 차이
소개 페이지는 ClickHouse에 대한 개요를 제공하는 데 매우 유용합니다.
ClickHouse는 PostgreSQL과 같은 전통적인 OLTP(온라인 트랜잭션 처리) 데이터베이스와 많은 차이가 있습니다. 기본 아키텍처가 약간 다르며, 처리는 전통적인 데이터베이스보다 훨씬 CPU 중심입니다. ClickHouse는 불변성이 핵심 요소인 로그 중심 데이터베이스입니다. 이러한 접근 방식의 장점은 잘 문서화되어 있지만, 업데이트를 훨씬 어렵게 만듭니다. UPDATE/DELETE 지원을 제공하는 작업에 대해서는 ClickHouse 문서를 참조하십시오. 이러한 작업은 빈번하지 않을 것으로 예상됩니다.
이 차이는 테이블을 설계할 때 중요합니다. 다음 중 하나여야 합니다:
- 업데이트가 필요하지 않음 (최상의 경우)
- 필요한 경우, 쿼리 실행 중에 실행되어서는 안 됨
ACID 호환성
ClickHouse는 트랜잭션 지원에 대한 조금 다른 전망을 가지고 있으며, 여기에서 보증은 특정 테이블에 삽입된 데이터 블록까지만 적용됩니다. 세부 정보는 트랜잭션(ACID) 지원 문서를 참조하십시오.
단일 쓰기에 대한 여러 삽입은 트랜잭션 지원이 여러 테이블에 걸쳐 적용되지 않기 때문에 피해야 합니다.
ClickHouse는 분석 쿼리에 대한 최고의 지원을 제공하기 위해 많은 노력이 기울어졌습니다. 집계와 같은 작업이 매우 빠르며, 이러한 기능을 보강하는 여러 기능이 있습니다. ClickHouse에는 집계에 대한 자세한 내용을 다룬 좋은 블로그 글이 있습니다.
주요 인덱스, 정렬 인덱스 및 딕셔너리
ClickHouse의 인덱스에 대한 이해를 얻기 위해 “ClickHouse의 주요 인덱스에 대한 실용적인 소개”를 매우 권장합니다.
특히 ClickHouse의 데이터베이스 인덱스 설계가 PostgreSQL과 같은 트랜잭션 데이터베이스와 어떻게 다른지에 주목해야 합니다.
주요 인덱스 설계는 쿼리 성능에 매우 중요한 역할을 합니다. 대부분의 쿼리는 완전한 데이터 스캔으로 인해 시간이 오래 걸릴 수 있으므로 주요 인덱스에 의존해야 합니다.
MergeTree Table 엔진(ClickHouse의 기본 테이블 엔진)에서의 쿼리 성능에 인덱스가 어떻게 영향을 미칠 수 있는지에 대한 자세한 정보는 primary keys and indexes in queries 문서를 참조하십시오.
ClickHouse의 보조 인덱스는 다른 시스템에서 제공되는 것과 다릅니다. 이들은 데이터 블록을 건너뛰는 데 사용되는 데이터 스킵 인덱스로도 불립니다. 데이터 스킵 인덱스 문서를 참조하십시오.
ClickHouse는 또한 쿼리 실행 중에 값을 조회하는 데 사용될 수 있는 “Dictionaries”를 제공합니다. 딕셔너리는 메모리로부터로드되며 쿼리 실행 시 값을 조회하는 데 사용할 수 있습니다.
데이터 유형 및 파티셔닝
ClickHouse는 SQL 호환 데이터 유형과 LowCardinality
, UUID, Maps, Nested와 같은 몇 가지 전문화된 데이터 유형을 제공합니다. 특히, Nested는 열 내에 테이블을 시뮬레이트하는 흥미로운 데이터 유형입니다.
테이블을 설계할 때 가장 중요한 설계 측면 중 하나는 파티션 키입니다. 파티션은 월, 일 또는 주와 같은 시간 기간과 같은 임의의 식일 수 있지만, ClickHouse는 가장 작은 파티션 집합을 사용하여 읽은 데이터를 최소화하기 위해 최선을 다하고 있습니다.
권장 읽기:
샤딩 및 복제
샤딩은 데이터를 여러 ClickHouse 노드로 분할하여 처리량을 증가시키고 지연 시간을 감소시키는 기능입니다. 샤딩 기능은 로컬 테이블을 기반으로 하는 분산 엔진을 사용합니다. 분산 엔진은 데이터를 저장하지 않는 “가상” 테이블입니다. 이것은 데이터를 삽입하고 쿼리하는 데 사용되는 인터페이스로 사용됩니다.
ClickHouse 문서와 복제 및 샤딩에 대한 이 섹션을 참조하십시오. ClickHouse는 Zookeeper 또는 ClickHouse Keeper라는 구성 요소를 통해 호환되는 자체 API를 사용하여 일치를 유지합니다.
노드 설정 후에는 클라이언트로부터 노드가 보이지 않게되며, 쓰기 및 읽기 쿼리를 어떤 노드에게든 발행할 수 있습니다.
대부분의 경우, 클러스터는 고정된 수의 노드(~샤드)로 시작합니다. 샤드 균형 조정은 운영적으로 번거롭고 엄격한 테스트가 필요합니다.
MergeTree Table 엔진은 복제를 지원하며, 자세한 정보는 복제 섹션에 나와 있습니다. ClickHouse는 분산 협의 구성 요소(Zookeeper 또는 ClickHouse Keeper)를 활용하여 참여하는 노드를 추적합니다. 복제는 비동기적이며 멀티 리더입니다. 어떤 노드에 있든 삽입이 발행될 수 있으며 일정한 지연 시간이 지나면 다른 노드에 나타날 수 있습니다. 원하는 경우 특정 노드에 대한 접근성을 사용하여 읽기가 최신 데이터를 확인하도록 할 수 있습니다.
머티얼라이즈드 뷰
ClickHouse의 가장 특징적인 기능 중 하나는 머티얼라이즈드 뷰(materialized views)입니다. 기능적으로 이는 ClickHouse의 삽입 트리거와 유사합니다.
공식 문서의 뷰 섹션을 읽어서 이들이 어떻게 작동하는지에 대해 더 잘 이해하세요.
문서를 인용하면:
ClickHouse의 머티얼라이즈드 뷰는 삽입 트리거와 유사하게 구현되어 있습니다. 뷰 쿼리에서 집계가 있으면 이는 최신으로 삽입된 데이터의 일괄에만 적용됩니다. 기존 데이터에 대한 변경(업데이트, 삭제, 파티션 삭제 등)은 머티얼라이즈드 뷰를 변경하지 않습니다.
보안 및 합리적인 기본값
ClickHouse 인스턴스는 이러한 보안 권고를 따라야 합니다:
사용자
파일: users.xml
및 config.xml
.
주제 | 보안 요구 사항 | 이유 |
---|---|---|
user_name/password
| 사용자 이름은 반드시 공백이 아니어야 합니다. 암호는 password_sha256_hex 를 사용해야 하며 공백이 아니어야 합니다.
|
plain text 및 password_double_sha1_hex 는 보안에 취약합니다. 사용자 이름이 지정되지 않으면, 기본값 이 비밀번호 없이 사용됩니다.
|
access_management
| 서버 구성 파일 users.xml 및 config.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 (inter-server_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는 암호화되어야 합니다. GKE 및 EKS는 이미 쉬 닥시 모든 데이터를 암호화합니다. 이 경우 자체 키를 사용하는 것이 가장 좋지만 필수는 아닙니다. | 데이터를 정지 상태에서 암호화하세요. (깊이 방어) |
로깅
주제 | 보안 요구 사항 | 이유 |
---|---|---|
logger
|
Log 및 errorlog 은 clickhouse 에 의해 정의되고 쓰기가 가능해야 합니다.
| 로그가 저장되도록합니다. |
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>