[Clickhouse] 사용량 제한

Clickhouse는 기본적으로 폭주기관차 같은 DB다.
쿼리를 잘 짜면 빠르지만, 쿼리 패턴이 이상하면 리소스를 미친듯이 쳐먹으면서 전체 DB를 거의 멈추게 하는 것이 매우 쉽다.

그래서 실제 운영 환경에서는 합리적인 수준의 사용량 제한을 걸어서 혹시나 모를 비효율적인 쿼리 패턴을 차단하는 것이 꽤 중요하다고 할 수 있겠다.

사용량 제한을 잘 걸려면 계정 분리를 먼저 좀 해주는 편이 좋다. 권장되는 방법이 각각의 용도를 가진 계정마다 별도의 사용량 제한을 거는 것이다.

그리고 사용량 제한을 거는 방법도 크게 2가지가 있다.
quota 기준으로 쿼리 사용량 제한을 거는 것과, 시스템 리소스 기준으로 제약을 거는 것이다.
사용 패턴에 따라서 둘다 사용해도 되고, 하나만 사용해도 된다.




Quota 제한

CREATE QUOTA 쿼리를 사용해서 특정 계정에 쿼타를 지정할 수 있다.
예를 들어 다음 쿼리는, 1시간마다 초기화되는 쿼타를 지정한다.

CREATE QUOTA metabase_quata 
FOR INTERVAL 1 hour 
    MAX queries = 100, -- 1시간 내의 최대 쿼리 횟수 100번
    MAX execution_time = 3600,  -- 총합 3600초동안 쿼리할 수 있음
    MAX result_rows = 1000000, -- 총합 1000000행 만큼의 최종 결과를 볼 수 있음
    MAX result_bytes = 1000000000, -- 총합 1000000000바이트 만큼의 최종 결과를 볼 수 있음
    MAX read_rows = 10000000, -- 총합 1000000행 만큼의 내부 Read를 할 수 있음
    MAX read_bytes = 10000000000 -- 총합 10000000000바이트 만큼의 내부 Read를 할 수 있음
TO metabase_viewer;

row 수나 byte 수로 제한을 거는 것은 사실 좀 지나친 설정일 수도 있다.
query 횟수나 실행시간 기준으로 제한을 거는 것은 유용하다.

이건 다른 조직이나 서비스에 한정적인 사용량 제한을 부여하는 데 용이하다.




PROFILE 수준 제한

혹은, 계정 PROFILE 세팅을 기준으로 제한을 설정할 수도 있다.
이건 특정 시간 범위의 쿼타가 아니라, 한 사용자가 한번에 사용할 수 있는 리소스를 제한한다.

아래는 예제 쿼리다.

CREATE SETTINGS PROFILE limit_metabase
SETTINGS 
    max_memory_usage = 40000000000,              -- 메모리는 최대 40GB만큼 사용
    max_execution_time = 30,                     -- 최대 30초 사용
    max_threads = 10,                            -- 최대 10개 스레드 사용
    max_concurrent_queries_for_user = 8,         -- 동시 쿼리 8개
TO metabase_viewer;

이러면 아무리 쿼리를 많이 날려도 40GB를 먹는 선에서 제한을 걸고, 30초가 넘으면 제한을 거는 식이 된다.
스레드나 쿼리도 너무 미친듯이 보내지 않게 제한을 할 수 있다.

개인적으로는 쿼타보다는 이 기능이 더 유연하고 유효했다.
같은 조직 내에서, 그냥 실수를 방지하고 안정성을 강화하는 측면에서는 이게 더 적합하다.



참조
https://clickhouse.com/docs/operations/quotas
https://clickhouse.com/docs/sql-reference/statements/create/quota
https://clickhouse.com/docs/sql-reference/statements/create/settings-profile