쿼터(Quotas)

쿼터(Quotas)

쿼터를 사용하면 일정 기간 동안의 리소스 사용을 제한하거나 리소스 사용을 추적할 수 있습니다. 이 문서에서는 users.xml에서 쿼터를 설정하는 방법과 각 제한 항목의 의미를 설명할게요.

출처: 문서

본문

ClickHouse Cloud의 쿼터 쿼터는 ClickHouse Cloud에서 지원되지만 DDL 구문으로 생성해야 합니다. 아래에 문서화된 XML 구성 방식은 지원되지 않습니다.

쿼터를 사용하면 일정 기간 동안의 리소스 사용을 제한하거나 리소스 사용을 추적할 수 있습니다. 쿼터는 보통 'users.xml'인 사용자 설정에 설정됩니다. 시스템에는 단일 쿼리의 복잡성을 제한하는 기능도 있습니다. 쿼리 복잡성 제한 섹션을 참고하세요. 쿼리 복잡성 제한과 대조적으로 쿼터는:

  • 단일 쿼리를 제한하는 대신 일정 기간 동안 실행될 수 있는 쿼리 집합에 제한을 둡니다.
  • 분산 쿼리 처리를 위해 모든 원격 서버에서 소비된 리소스를 계산에 포함합니다.

쿼터를 정의하는 'users.xml' 파일의 섹션을 살펴보겠습니다.

<!-- Quotas -->
<quotas>
    <!-- 쿼터 이름. -->
    <default>
        <!-- 시간 기간에 대한 제한. 서로 다른 제한을 가진 여러 간격을 설정할 수 있습니다. -->
        <interval>
            <!-- 간격의 길이. -->
            <duration>3600</duration>

            <!-- 무제한. 지정된 시간 간격 동안 데이터만 수집합니다. -->
            <queries>0</queries>
            <query_selects>0</query_selects>
            <query_inserts>0</query_inserts>
            <errors>0</errors>
            <result_rows>0</result_rows>
            <read_rows>0</read_rows>
            <execution_time>0</execution_time>
        </interval>
    </default>
</quotas>

기본적으로 쿼터는 사용을 제한하지 않고 매시간 리소스 소비를 추적합니다. 각 간격에 대해 계산된 리소스 소비는 각 요청 후 서버 로그에 출력됩니다.

<statbox>
    <!-- 시간 기간에 대한 제한. 서로 다른 제한을 가진 여러 간격을 설정할 수 있습니다. -->
    <interval>
        <!-- 간격의 길이. -->
        <duration>3600</duration>

        <queries>1000</queries>
        <query_selects>100</query_selects>
        <query_inserts>100</query_inserts>
        <written_bytes>5000000</written_bytes>
        <errors>100</errors>
        <result_rows>1000000000</result_rows>
        <read_rows>100000000000</read_rows>
        <execution_time>900</execution_time>
        <failed_sequential_authentications>5</failed_sequential_authentications>
    </interval>

    <interval>
        <duration>86400</duration>

        <queries>10000</queries>
        <query_selects>10000</query_selects>
        <query_inserts>10000</query_inserts>
        <errors>1000</errors>
        <result_rows>5000000000</result_rows>
        <result_bytes>160000000000</result_bytes>
        <read_rows>500000000000</read_rows>
        <result_bytes>16000000000000</result_bytes>
        <execution_time>7200</execution_time>
    </interval>
</statbox>

'statbox' 쿼터의 경우 매시간과 매 24시간(86,400초)마다 제한이 설정됩니다. 시간 간격은 구현 정의된 고정 시점부터 계산됩니다. 즉 24시간 간격이 반드시 자정에 시작되지는 않습니다. 간격이 끝나면 수집된 모든 값이 지워집니다. 다음 시간 동안 쿼터 계산이 다시 시작됩니다. 제한할 수 있는 항목은 다음과 같습니다: queries – 총 요청 수. query_selects – 총 select 요청 수. query_inserts – 총 insert 요청 수. errors – 예외를 던진 쿼리 수. result_rows – 결과로 주어진 총 행 수. result_bytes - 결과로 주어진 행의 총 크기. read_rows – 모든 원격 서버에서 쿼리를 실행하기 위해 테이블에서 읽은 총 소스 행 수. read_bytes - 모든 원격 서버에서 쿼리를 실행하기 위해 테이블에서 읽은 총 크기. written_bytes - 쓰기 작업의 총 크기. execution_time – 총 쿼리 실행 시간(초, 벽시계 시간). failed_sequential_authentications - 총 순차 인증 오류 수. queries_per_normalized_hash – 단일 정규화된 쿼리의 최대 실행 횟수. 정규화된 쿼리는 리터럴이 플레이스홀더로 대체된 쿼리이므로, SELECT 1SELECT 2는 같은 정규화된 쿼리로 간주됩니다. 이 제한은 고유한 정규화된 쿼리 패턴별로 독립적으로 추적됩니다. 적어도 하나의 시간 간격에 대해 한도가 초과되면, 어떤 제한이 어느 간격에서 초과되었는지와 새 간격이 언제 시작되는지(쿼리를 다시 보낼 수 있는 때)에 대한 텍스트가 포함된 예외가 발생합니다.

쿼터 계산에서 제외되는 쿼리 쿼터가 소진된 경우에도 쿼터 구성과 사용을 검사할 수 있도록, 다음 시스템 테이블 중 하나에서만 읽는 SELECT 쿼리는 쿼터에 청구되지 않으며 쿼리 복잡성 제한의 적용을 받지 않습니다:

  • system.quotas
  • system.quota_limits
  • system.quota_usage
  • system.quotas_usage
  • system.one

쿼터는 "쿼터 키(quota key)" 기능을 사용해 여러 키에 대한 리소스를 독립적으로 보고할 수 있습니다. 예는 다음과 같습니다:

<!-- 글로벌 리포트 디자이너용. -->
<web_global>
    <!-- keyed – quota_key "key"가 쿼리 매개변수로 전달되고,
            쿼터는 각 키 값에 대해 별도로 추적됩니다.
        예를 들어 키로 사용자 이름을 전달할 수 있으므로,
            쿼터가 각 사용자 이름에 대해 별도로 계산됩니다.
        키 사용은 quota_key가 사용자가 아닌 프로그램에 의해 전송될 때만 의미가 있습니다.

        또한 <keyed_by_ip />를 쓸 수 있으며, 그러면 IP 주소가 쿼터 키로 사용됩니다.
        (단, 사용자는 IPv6 주소를 상당히 쉽게 변경할 수 있다는 점을 기억하세요.)

        <keyed_by_ip /> 대신 <keyed_by_forwarded_ip />를 사용해
            X-Forwarded-For 헤더의 주소를 쿼터 키로 사용할 수 있습니다.

        <keyed_by_ip />와 <keyed_by_forwarded_ip /> 둘 다에 대해 추가로
        <ipv4_prefix_bits>와 <ipv6_prefix_bits>를 지정해 단일 주소 대신 서브넷별로
        클라이언트를 그룹화할 수 있습니다: IP 주소는 쿼터 키로 사용되기 전에
        주어진 접두사 길이로 마스킹됩니다. 예를 들어 <ipv4_prefix_bits>24</ipv4_prefix_bits>는
        /24 IPv4 서브넷 전체가 하나의 버킷을 공유하고, <ipv6_prefix_bits>64</ipv6_prefix_bits>는
        /64 IPv6 서브넷 전체가 하나의 버킷을 공유합니다. 이 요소들은 <keyed_by_ip /> 또는
        <keyed_by_forwarded_ip />와 함께만 사용할 수 있습니다.
    -->
    <keyed />
</web_global>

또한 정규화된 쿼리 해시로 쿼터를 키잉할 수 있어, 각 고유 쿼리 패턴이 자체적으로 독립적인 쿼터 버킷을 가지게 됩니다. XML 구성에서 이것은 <keyed_by_normalized_query_hash />로 작성됩니다:

<my_quota>
    <keyed_by_normalized_query_hash />
    <interval>
        <duration>3600</duration>
        <queries>100</queries>
    </interval>
</my_quota>

같은 것을 DDL 구문으로 표현할 수도 있습니다:

CREATE QUOTA my_quota KEYED BY normalized_query_hash FOR INTERVAL 1 hour MAX queries = 100 TO my_user;

이 예제에서 사용자는 시간당 각 고유 정규화된 쿼리 패턴을 최대 100번 실행할 수 있습니다. SELECT number FROM numbers(1)SELECT number FROM numbers(2)는 같은 버킷을 공유하지만(정규화된 형태가 같으므로), SELECT number, number FROM numbers(1)은 별도의 버킷을 사용합니다. 쿼터는 설정의 'users' 섹션에서 사용자에게 할당됩니다. "접근 권한" 섹션을 참고하세요. 분산 쿼리 처리의 경우 누적된 양은 요청자 서버에 저장됩니다. 따라서 사용자가 다른 서버로 가면 그곳의 쿼터는 "다시 시작"됩니다. 서버가 재시작되면 쿼터가 재설정됩니다.

관련 콘텐츠

더 알아보기 (Learn more)