서버 설정 (config.xml, users.xml, 설정 프로필, 쿼터, 메모리 한도)
서버 설정과 사용자 설정이 어디에 갈리는지, config.d 와 users.d 로 덧씌우는 방법, 설정 프로필과 제약, 쿼터, 메모리 한도를 운영 기준으로 정리합니다.
설정은 두 층입니다
ClickHouse 설정은 크게 두 층으로 나뉩니다. 이 구분이 머리에 들어와 있으면 "어디를 고쳐야 하나"가 바로 보입니다.
| 층 | 파일 | 무엇을 정하나 | 확인 테이블 |
|---|---|---|---|
| 서버 설정 | config.xml (+ config.d/*.xml) | 포트, 경로, 로그, 서버 전체 메모리, 백그라운드 풀, Keeper, 클러스터, 스토리지 | system.server_settings |
| 사용자(쿼리) 설정 | users.xml (+ users.d/*.xml) 또는 SQL | 쿼리 한 건의 메모리, 스레드 수, 타임아웃, 읽기 전용 여부, 쿼터 | system.settings |
| MergeTree 설정 | config.xml 의 <merge_tree> 또는 테이블 SETTINGS | 파트 수 제한, 머지 크기, TTL 머지 간격 | system.merge_tree_settings |
기본 설치 경로는 /etc/clickhouse-server/ 이고, 데이터는 /var/lib/clickhouse/ 에 있습니다. config.xml 과 users.xml 자체는 건드리지 않고, config.d/ 와 users.d/ 에 조각 파일을 두어 덧씌우는 것이 운영 관례입니다. 패키지를 올려도 조각 파일은 그대로 남습니다.
팁 조각 파일은 알파벳 순서로 합쳐집니다.
10-network.xml,20-memory.xml처럼 숫자를 앞에 붙이면 순서가 눈에 보입니다. XML 대신 YAML(config.yaml)도 쓸 수 있지만 한 서버 안에서 섞지 않는 편이 덜 헷갈립니다.
서버 설정에서 꼭 보는 항목
<!-- /etc/clickhouse-server/config.d/10-server.xml -->
<clickhouse>
<listen_host>0.0.0.0</listen_host>
<tcp_port>9000</tcp_port>
<http_port>8123</http_port>
<interserver_http_port>9009</interserver_http_port>
<path>/var/lib/clickhouse/</path>
<logger>
<level>information</level>
<size>1000M</size>
<count>10</count>
</logger>
<max_server_memory_usage_to_ram_ratio>0.9</max_server_memory_usage_to_ram_ratio>
<max_concurrent_queries>200</max_concurrent_queries>
<background_pool_size>16</background_pool_size>
</clickhouse>listen_host: 기본은 localhost 만 듣습니다. 다른 서버에서 붙이려면0.0.0.0또는::로 열고, 방화벽을 같이 챙깁니다.tcp_port(9000)는 clickhouse-client 와 네이티브 드라이버,http_port(8123)는 HTTP 인터페이스,interserver_http_port(9009)는 복제본끼리 파트를 주고받는 포트입니다. 복제가 이상하면 이 포트가 막혀 있는지 먼저 봅니다. 자세한 것은 복제 지연과 Keeper 문제에 있습니다.max_server_memory_usage_to_ram_ratio: 서버 전체가 쓸 수 있는 메모리 비율입니다. 기본 0.9 이고, 같은 머신에 다른 프로세스가 있으면 낮춥니다. 절대값으로 주려면max_server_memory_usage를 바이트로 적습니다.background_pool_size: 머지와 뮤테이션을 돌리는 스레드 수입니다. 코어 수에 맞춰 올리면 머지가 빨라지지만 쿼리와 CPU 를 나눠 씁니다. Too many parts 문서에서 다룹니다.logger.level: 운영은information, 문제를 쫓을 때만debug나trace. trace 는 디스크를 금방 채웁니다.
대부분의 서버 설정은 파일을 고치면 자동으로 다시 읽힙니다. 다만 listen_host, 포트, path 처럼 프로세스가 뜰 때 정해지는 값은 재시작이 필요합니다. 즉시 반영하려면 SYSTEM RELOAD CONFIG 를 실행합니다.
SELECT name, value, changed, description
FROM system.server_settings
WHERE changed
ORDER BY name;사용자 설정: 파일과 SQL 두 길
사용자, 프로필, 쿼터는 users.xml 로 정하는 길과 SQL(CREATE USER, CREATE SETTINGS PROFILE, CREATE QUOTA)로 정하는 길이 있습니다. 둘 다 쓸 수 있지만, 운영에서는 SQL 쪽(RBAC)이 감사 로그와 권한 위임 면에서 유리합니다. SQL 로 관리하려면 관리자 계정에 access_management 를 켭니다.
<!-- /etc/clickhouse-server/users.d/10-admin.xml -->
<clickhouse>
<users>
<admin>
<password_sha256_hex>...</password_sha256_hex>
<networks><ip>10.0.0.0/8</ip></networks>
<profile>default</profile>
<quota>default</quota>
<access_management>1</access_management>
</admin>
<default>
<!-- 기본 사용자는 비밀번호 없이 열려 있으니 운영에서는 막습니다 -->
<networks><ip>::1</ip><ip>127.0.0.1</ip></networks>
</default>
</users>
</clickhouse>주의 기본
default사용자는 비밀번호가 없습니다.listen_host를 열어 둔 서버에서default를 그대로 두면 누구나 접속합니다. 네트워크를 localhost 로 묶거나 비밀번호를 걸고, 애플리케이션은 전용 사용자를 씁니다.
SQL 로는 이렇게 씁니다.
CREATE USER app_writer IDENTIFIED WITH sha256_password BY '...'
HOST IP '10.0.0.0/8' SETTINGS PROFILE 'writer';
GRANT INSERT ON logs.* TO app_writer;권한 모델(역할, 행 정책, 열 마스킹)은 네트워크와 보안 문서에서 Cloud 와 함께 정리했습니다.
설정 프로필과 제약
프로필은 쿼리 설정 묶음입니다. 사용자에게 프로필을 붙이면 그 사용자의 모든 쿼리가 그 값을 기본으로 씁니다. 사용자가 세션에서 SET 으로 바꿀 수 있는데, 못 바꾸게 막으려면 제약(constraints)을 둡니다.
CREATE SETTINGS PROFILE analyst SETTINGS
max_memory_usage = 8000000000 MAX 16000000000,
max_execution_time = 300 READONLY,
max_threads = 8,
readonly = 2 CONST,
max_result_rows = 1000000;MAX: 사용자가 올려도 이 값까지만.READONLY또는CONST: 사용자가 바꿀 수 없음.readonly = 1은 읽기만 되고 설정도 못 바꿉니다.readonly = 2는 읽기만 되지만 설정은 바꿀 수 있어서 BI 도구 계정에 적당합니다.allow_ddl = 0으로 DDL 만 막을 수도 있습니다.
설정이 적용되는 우선순위는 "서버 기본값 < 프로필 < 사용자 < 세션 SET < 쿼리 끝의 SETTINGS 절" 입니다. 지금 세션에 무엇이 걸려 있는지는 이렇게 봅니다.
SELECT name, value, changed, min, max, readonly
FROM system.settings
WHERE changed;팁 쿼리 하나에만 설정을 주고 싶을 때는 끝에
SETTINGS max_threads = 2, max_memory_usage = 4e9를 붙입니다. 대시보드 도구에서 세션 설정을 못 바꿀 때 특히 유용합니다.
메모리 한도 세 겹
메모리 한도는 쿼리, 사용자, 서버의 세 겹으로 걸립니다. 어디서 걸렸는지 에러 메시지에 적혀 나오니 그 말을 그대로 읽으면 됩니다.
| 한도 | 설정 | 메시지 | 기본값 |
|---|---|---|---|
| 쿼리 하나 | max_memory_usage | Memory limit (for query) exceeded | 설정 자체는 0(무제한), 기본 users.xml 프로필은 10 GB |
| 사용자 전체 | max_memory_usage_for_user | Memory limit (for user) exceeded | 0(무제한) |
| 서버 전체 | max_server_memory_usage (또는 ..._to_ram_ratio) | Memory limit (total) exceeded | RAM 의 90% |
메모리가 넘칠 때 디스크로 흘리는 설정(max_bytes_before_external_group_by, max_bytes_before_external_sort)과 조인 알고리즘 선택은 메모리 초과 트러블슈팅에서 자세히 다룹니다. 여기서는 "쿼리 한도는 서버 한도의 절반 이하로, 사용자 한도는 쿼리 한도보다 크게" 정도의 감만 잡으면 됩니다.
쿼터
쿼터는 일정 시간 창 안에서 사용자(또는 키)가 쓸 수 있는 자원 총량입니다. 설정 프로필은 쿼리 한 건의 상한이고, 쿼터는 기간 합계라는 점이 다릅니다.
CREATE QUOTA bi_quota
KEYED BY user_name
FOR INTERVAL 1 hour MAX queries = 2000, errors = 100,
read_rows = 50000000000, execution_time = 7200
TO bi_user;KEYED BY는user_name,ip_address,client_key,forwarded_ip_address등을 고를 수 있습니다. HTTP 로 들어오는 여러 서비스를 한 사용자로 묶어 쓰면client_key로 서비스별로 나눌 수 있습니다.- 소진 상황은
system.quota_usage,system.quotas_usage에서 봅니다. - 쿼터를 넘으면
Quota for user ... has been exceeded로 거절되고, 창이 지나면 다시 풀립니다.
쿼리 한 건에 거는 안전장치
운영 서버에서 애널리스트 계정에 꼭 거는 값들입니다.
| 설정 | 뜻 | 권장 출발점 |
|---|---|---|
max_execution_time | 초 단위 실행 시간 상한 | 300 (대시보드는 60) |
max_rows_to_read, max_bytes_to_read | 읽을 수 있는 행, 바이트 상한 | 데이터 크기에 맞춰 |
max_result_rows, result_overflow_mode | 결과 행 상한, 넘으면 끊기(break) 또는 에러 | 100만, break |
max_threads | 쿼리 하나가 쓰는 스레드 | 코어 수의 절반 |
max_concurrent_queries_for_user | 사용자당 동시 쿼리 | 10 |
join_use_nulls, join_algorithm | 조인 동작 | JOIN 전략 참고 |
timeout_before_checking_execution_speed, min_execution_speed | 너무 느린 쿼리 조기 중단 | 필요할 때 |
max_rows_to_read 를 넘기면 Limit for rows (controlled by 'max_rows_to_read' setting) exceeded 로 바로 끊기므로, 실수로 전체 테이블을 긁는 쿼리를 막는 데 좋습니다. 인덱스를 못 타는 쿼리를 잡아내는 효과도 있습니다. 인덱스 활용은 쿼리 최적화를 보세요.
자주 손대는 MergeTree 설정
테이블 단위로 SETTINGS 절에 적거나, 서버 전체 기본값을 <merge_tree> 에 둡니다.
<clickhouse>
<merge_tree>
<parts_to_delay_insert>1000</parts_to_delay_insert>
<parts_to_throw_insert>3000</parts_to_throw_insert>
<!-- 150 GiB -->
<max_bytes_to_merge_at_max_space_in_pool>161061273600
</max_bytes_to_merge_at_max_space_in_pool>
<ttl_only_drop_parts>1</ttl_only_drop_parts>
</merge_tree>
</clickhouse>ALTER TABLE logs.events MODIFY SETTING ttl_only_drop_parts = 1;
SELECT name, value, changed FROM system.merge_tree_settings WHERE changed;이 값들이 하는 일은 MergeTree 엔진과 TTL, 디스크 티어링에 있습니다.
ClickHouse Cloud 에서는
Cloud 에서는 config.xml 을 직접 만질 수 없습니다. 서버 설정은 ClickHouse 쪽이 관리하고, 바꾸고 싶은 값은 지원팀을 통하거나 콘솔의 설정 메뉴에서 바꿉니다. 사용자 설정과 프로필, 쿼터, 역할은 전부 SQL 로 똑같이 됩니다. 셀프 호스팅과 Cloud 의 다른 점은 ClickHouse Cloud 개요에 정리했습니다.
설정 바꿀 때 습관
- 바꾸기 전에
system.settings또는system.server_settings로 현재 값과changed를 기록해 둡니다. - 조각 파일 하나에 관련 설정만 넣고, 파일 맨 위 주석에 왜 바꿨는지 날짜와 함께 적습니다.
- 바꾼 뒤
system.text_log또는 서버 로그에서Loaded config와 경고를 확인합니다. 오타가 나면 전체 조각이 무시될 수 있습니다. - 기본값이 버전마다 바뀌는 설정이 있습니다. 업그레이드 뒤에는
system.settings_changes를 봅니다. 백업과 복원, 업그레이드에 절차가 있습니다.