본문으로 건너뛰기
clickhouse검색
운영과 트러블슈팅

서버 설정 (config.xml, users.xml, 설정 프로필, 쿼터, 메모리 한도)

서버 설정과 사용자 설정이 어디에 갈리는지, config.d 와 users.d 로 덧씌우는 방법, 설정 프로필과 제약, 쿼터, 메모리 한도를 운영 기준으로 정리합니다.

config.xmlusers.xml설정 프로필쿼터max_memory_usage2026-10 기준, 약 14분

설정은 두 층입니다

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_usageMemory limit (for query) exceeded설정 자체는 0(무제한), 기본 users.xml 프로필은 10 GB
사용자 전체max_memory_usage_for_userMemory limit (for user) exceeded0(무제한)
서버 전체max_server_memory_usage (또는 ..._to_ram_ratio)Memory limit (total) exceededRAM 의 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 개요에 정리했습니다.

설정 바꿀 때 습관

  1. 바꾸기 전에 system.settings 또는 system.server_settings 로 현재 값과 changed 를 기록해 둡니다.
  2. 조각 파일 하나에 관련 설정만 넣고, 파일 맨 위 주석에 왜 바꿨는지 날짜와 함께 적습니다.
  3. 바꾼 뒤 system.text_log 또는 서버 로그에서 Loaded config 와 경고를 확인합니다. 오타가 나면 전체 조각이 무시될 수 있습니다.
  4. 기본값이 버전마다 바뀌는 설정이 있습니다. 업그레이드 뒤에는 system.settings_changes 를 봅니다. 백업과 복원, 업그레이드에 절차가 있습니다.

공식 문서

이 문서에서