clickhouse-local

clickhouse-local

clickhouse-local은 완전한 데이터베이스 서버를 설치하지 않고도 로컬 및 원격 파일에 대해 SQL로 빠른 처리를 수행해야 하는 개발자에게 이상적인, 사용하기 쉬운 ClickHouse 버전이에요.

출처: 문서

본문

clickhouse-local vs. ClickHouse, 언제 사용할까 (When to use clickhouse-local vs. ClickHouse)

clickhouse-local은 완전한 데이터베이스 서버를 설치할 필요 없이, 로컬 및 원격 파일에 대해 SQL을 사용해 빠른 처리를 수행해야 하는 개발자에게 이상적인, 사용하기 쉬운 ClickHouse 버전입니다. clickhouse-local을 사용하면 개발자는 명령줄에서 직접 (ClickHouse SQL 방언을 사용하는) SQL 명령을 사용할 수 있어, 전체 ClickHouse 설치 없이도 ClickHouse 기능에 접근하는 간단하고 효율적인 방법을 제공합니다. clickhouse-local의 주요 장점 중 하나는 clickhouse-client를 설치할 때 이미 포함된다는 것입니다. 즉, 복잡한 설치 과정 없이 clickhouse-local을 빠르게 시작할 수 있습니다.

clickhouse-local은 개발과 테스트 목적, 그리고 파일 처리에 훌륭한 도구이지만, 최종 사용자나 애플리케이션을 서빙하기에는 적합하지 않습니다. 이러한 시나리오에서는 오픈소스 ClickHouse를 사용하는 것이 좋습니다. ClickHouse는 대규모 분석 워크로드를 처리하도록 설계된 강력한 OLAP 데이터베이스입니다. 대규모 데이터셋에 대한 복잡한 쿼리를 빠르고 효율적으로 처리하며, 고성능이 중요한 프로덕션 환경에 이상적입니다. 또한 ClickHouse는 복제, 샤딩, 고가용성 같은 다양한 기능을 제공하며, 이는 대규모 데이터셋을 처리하고 애플리케이션을 서빙하기 위해 확장하는 데 필수적입니다. 더 큰 데이터셋을 다루거나 최종 사용자·애플리케이션을 서빙해야 한다면 clickhouse-local 대신 오픈소스 ClickHouse를 사용하는 것을 권장합니다.

clickhouse-local의 예시 사용 사례를 보여주는 아래 문서를 읽어 보세요. 예를 들어 로컬 파일 쿼리 또는 AWS S3의 Parquet 파일 읽기가 있습니다.

clickhouse-local 다운로드하기 (Download clickhouse-local)

clickhouse-local은 ClickHouse 서버와 clickhouse-client를 실행하는 것과 같은 clickhouse 바이너리로 실행됩니다. 최신 버전을 다운로드하는 가장 쉬운 방법은 다음 명령입니다:

curl https://clickhouse.com/ | sh

방금 다운로드한 바이너리는 모든 종류의 ClickHouse 도구와 유틸리티를 실행할 수 있습니다. ClickHouse를 데이터베이스 서버로 실행하려면 Quick Start를 확인하세요.

SQL로 파일의 데이터 쿼리하기 (Query data in a file using SQL)

clickhouse-local의 일반적인 용도는 파일에 대한 애드혹 쿼리를 실행하는 것입니다. 데이터를 테이블에 삽입하지 않아도 됩니다. clickhouse-local은 파일에서 임시 테이블로 데이터를 스트리밍하고 SQL을 실행할 수 있어요.

파일이 clickhouse-local과 같은 머신에 있으면 로드할 파일을 간단히 지정할 수 있습니다. 다음 reviews.tsv 파일에는 Amazon 제품 리뷰의 샘플이 들어 있습니다:

./clickhouse local -q "SELECT * FROM 'reviews.tsv'"

이 명령은 다음의 축약형입니다:

./clickhouse local -q "SELECT * FROM file('reviews.tsv')"

ClickHouse는 파일 이름 확장자에서 파일이 탭으로 구분된 형식을 사용함을 압니다. 형식을 명시적으로 지정해야 한다면 여러 ClickHouse 입력 형식 중 하나를 추가하면 됩니다:

./clickhouse local -q "SELECT * FROM file('reviews.tsv', 'TabSeparated')"

file 테이블 함수는 테이블을 만들고, DESCRIBE로 추론된 스키마를 볼 수 있습니다:

./clickhouse local -q "DESCRIBE file('reviews.tsv')"

파일 이름에 glob을 사용할 수 있습니다(glob 치환 참고). 예시:

./clickhouse local -q "SELECT * FROM 'reviews*.jsonl'"
./clickhouse local -q "SELECT * FROM 'review_?.csv'"
./clickhouse local -q "SELECT * FROM 'review_{1..3}.csv'"

데이터가 로컬일 필요는 없습니다. 파일 이름 대신 URL을 사용할 수 있으며, URL 스킴이 매칭되는 테이블 엔진을 선택합니다(http://https://url 함수처럼, s3://s3 함수처럼, file://file 함수처럼 읽힙니다):

./clickhouse local -q "SELECT * FROM 'https://datasets-documentation.s3.eu-west-3.amazonaws.com/aapl_stock.csv' LIMIT 3"
./clickhouse local -q "SELECT count() FROM 's3://clickhouse-public-datasets/hits_compatible/athena_partitioned/hits_1.parquet'"
marketplace    Nullable(String)
customer_id    Nullable(Int64)
review_id    Nullable(String)
product_id    Nullable(String)
product_parent    Nullable(Int64)
product_title    Nullable(String)
product_category    Nullable(String)
star_rating    Nullable(Int64)
helpful_votes    Nullable(Int64)
total_votes    Nullable(Int64)
vine    Nullable(String)
verified_purchase    Nullable(String)
review_headline    Nullable(String)
review_body    Nullable(String)
review_date    Nullable(Date)

가장 높은 평점을 가진 제품을 찾아봅시다:

./clickhouse local -q "SELECT
    argMax(product_title,star_rating),
    max(star_rating)
FROM file('reviews.tsv')"
Monopoly Junior Board Game    5

AWS S3의 Parquet 파일 데이터 쿼리하기 (Query data in a Parquet file in AWS S3)

S3에 파일이 있다면 clickhouse-locals3 테이블 함수를 사용해 그 자리에서 파일을 쿼리할 수 있습니다(데이터를 ClickHouse 테이블에 삽입하지 않고). 공개 버킷에 영국에서 판매된 부동산의 주택 가격이 들어 있는 house_0.parquet라는 파일이 있습니다. 행 수를 확인해 봅시다:

./clickhouse local -q "
SELECT count()
FROM s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/house_parquet/house_0.parquet')"

파일에는 2.7M 행이 있습니다:

2772030

ClickHouse가 파일에서 결정한 추론된 스키마를 보는 것은 항상 유용합니다:

./clickhouse local -q "DESCRIBE s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/house_parquet/house_0.parquet')"
price    Nullable(Int64)
date    Nullable(UInt16)
postcode1    Nullable(String)
postcode2    Nullable(String)
type    Nullable(String)
is_new    Nullable(UInt8)
duration    Nullable(String)
addr1    Nullable(String)
addr2    Nullable(String)
street    Nullable(String)
locality    Nullable(String)
town    Nullable(String)
district    Nullable(String)
county    Nullable(String)

가장 비싼 동네들을 확인해 봅시다:

./clickhouse local -q "
SELECT
    town,
    district,
    count() AS c,
    round(avg(price)) AS price,
    bar(price, 0, 5000000, 100)
FROM s3('https://datasets-documentation.s3.eu-west-3.amazonaws.com/house_parquet/house_0.parquet')
GROUP BY
    town,
    district
HAVING c >= 100
ORDER BY price DESC
LIMIT 10"
LONDON    CITY OF LONDON    886    2271305    █████████████████████████████████████████████▍
LEATHERHEAD    ELMBRIDGE    206    1176680    ███████████████████████▌
LONDON    CITY OF WESTMINSTER    12577    1108221    ██████████████████████▏
LONDON    KENSINGTON AND CHELSEA    8728    1094496    █████████████████████▉
HYTHE    FOLKESTONE AND HYTHE    130    1023980    ████████████████████▍
CHALFONT ST GILES    CHILTERN    113    835754    ████████████████▋
AMERSHAM    BUCKINGHAMSHIRE    113    799596    ███████████████▉
VIRGINIA WATER    RUNNYMEDE    356    789301    ███████████████▊
BARNET    ENFIELD    282    740514    ██████████████▊
NORTHWOOD    THREE RIVERS    184    731609    ██████████████▋

파일을 ClickHouse에 삽입할 준비가 되면 ClickHouse 서버를 시작하고 files3 테이블 함수의 결과를 MergeTree 테이블에 삽입하세요. 자세한 내용은 Quick Start를 참고하세요.

형식 변환 (Format Conversions)

clickhouse-local을 사용해 서로 다른 형식 간에 데이터를 변환할 수 있습니다. 예시:

$ clickhouse-local --input-format JSONLines --output-format CSV --query "SELECT * FROM table" < data.json > data.csv

형식은 파일 확장자에서 자동 감지됩니다:

$ clickhouse-local --query "SELECT * FROM table" < data.json > data.csv

단축으로 --copy 인자를 사용해 작성할 수도 있습니다:

$ clickhouse-local --copy < data.json > data.csv

사용법 (Usage)

기본적으로 clickhouse-local은 같은 호스트의 ClickHouse 서버 데이터에 접근할 수 있으며, 서버의 설정에 의존하지 않습니다. 또한 --config-file 인자를 사용한 서버 설정 로드도 지원합니다. 임시 데이터를 위해 기본적으로 고유한 임시 데이터 디렉터리가 생성됩니다.

기본 사용법 (Linux):

$ clickhouse-local --structure "table_structure" --input-format "format_of_incoming_data" --query "query"

기본 사용법 (Mac):

$ ./clickhouse local --structure "table_structure" --input-format "format_of_incoming_data" --query "query"

clickhouse-local은 WSL2를 통한 Windows에서도 지원됩니다.

인자:

  • -S, --structure — 입력 데이터의 테이블 구조.
  • --input-format — 입력 형식, 기본값은 TSV.
  • -F, --file — 데이터 경로, 기본값은 stdin.
  • -q, --query; 구분자로 실행할 쿼리. --query는 여러 번 지정할 수 있습니다, 예: --query "SELECT 1" --query "SELECT 2". --queries-file와 동시에 사용할 수 없습니다.
  • --queries-file — 실행할 쿼리가 있는 파일 경로. --queries-file은 여러 번 지정할 수 있습니다, 예: --query queries1.sql --query queries2.sql. --query와 동시에 사용할 수 없습니다.
  • --multiquery, -n — 지정하면 --query 옵션 뒤에 세미콜론으로 구분된 여러 쿼리를 나열할 수 있습니다. 편의를 위해 --query를 생략하고 --multiquery 뒤에 쿼리를 직접 전달할 수도 있습니다.
  • -N, --table — 출력 데이터를 넣을 테이블 이름, 기본값은 table.
  • -f, --format, --output-format — 출력 형식, 기본값은 TSV.
  • -d, --database — 기본 데이터베이스, 기본값은 _local.
  • --stacktrace — 예외 발생 시 디버그 출력을 덤프할지 여부.
  • --echo [ <bool> ] — 실행 전에 각 쿼리를 출력합니다. 선택적 boolean 값을 받습니다. 대화형 모드에서 기본 활성화, 배치 모드에서 비활성화. 참고: --echo가 이제 선택적 값을 받으므로, 맨 --echo 바로 뒤에 위치한 위치 인자 쿼리는 그 값으로 소비됩니다. 대신 --echo --query "...", --echo -q "...", --echo=false, 또는 파이프된 stdin을 사용하세요.
  • --echo-formatted [ <bool> ] — 에코된 쿼리를 포맷합니다. 선택적 boolean 값을 받습니다. 대화형 모드에서 기본 활성화, 배치 모드에서 비활성화.
  • --echo-query-id [ <bool> ] — 실행 전에 query_id를 출력합니다. 선택적 boolean 값을 받습니다. 대화형 모드에서 기본 활성화, 배치 모드에서 비활성화.
  • --echo-query-separator <string> — 포맷된 에코 쿼리 앞에 이 구분자를 출력합니다(--echo-formatted 필요), 입력한 쿼리와 재포맷된 에코를 구분하기 쉽게 해 줍니다. 기본값은 비어 있음(비활성화).
  • --highlight, --hilite <bool> — 명령 프롬프트와 에코된 쿼리의 구문 강조를 전환합니다. 기본 활성화. 강조는 터미널에 쓸 때만 적용됩니다.
  • --hints <bool> — 커서가 입력 끝에 있을 때 가장 잘 매칭되는 제안에 대한 입력 중 자동완성 힌트(인라인 "유령" 텍스트)를 표시합니다. Up/Down(또는 Ctrl-Up/Ctrl-Down)으로 힌트를 탐색하고, Tab 또는 Right로 인라인 힌트를 수락합니다. Enter는 명시적으로 선택된 후에만 힌트를 수락하고 그렇지 않으면 쿼리를 실행합니다. Tab은 또한 기존 완성 목록을 엽니다. --highlight가 필요합니다(힌트는 색상이 필요). 제안 힌트는 제안 메커니즘도 필요하므로 --disable_suggestion는 그것들을 끕니다; 클라이언트의 /-commands는 정적 목록이며 --hints--highlight가 켜져 있는 한 힌트가 유지됩니다. Tab은 힌트가 꺼져 있어도 /-commands를 완성합니다. 기본 활성화.
  • --verbose — 쿼리 실행에 대한 더 많은 세부 정보.
  • --logger.console — 콘솔에 기록.
  • --logger.log — 로그 파일 이름.
  • --logger.level — 로그 레벨.
  • --ignore-error — 쿼리가 실패해도 처리를 멈추지 않습니다.
  • -c, --config-file — ClickHouse 서버와 같은 형식의 구성 파일 경로, 기본값은 빈 구성.
  • --no-system-tables — 시스템 테이블을 연결하지 않습니다.
  • --helpclickhouse-local의 인자 참조.
  • -V, --version — 버전 정보를 출력하고 종료합니다.

또한 --config-file 대신 더 흔히 사용되는 각 ClickHouse 구성 변수에 대한 인자도 있습니다.

구성 파일 (Configuration files)

clickhouse-local은 같은 호스트에 설치된 ClickHouse 서버의 구성을 사용하지 않습니다 - 자체 메인 구성 파일을 찾아 다음 중 첫 번째로 존재하는 것을 사용합니다:

  1. --config-file로 전달된 경로;
  2. ./config.xml;
  3. ./clickhouse-local.xml, ./clickhouse-local.yaml 또는 ./clickhouse-local.yml;
  4. ~/.clickhouse-local/config.xml, ~/.clickhouse-local/config.yaml 또는 ~/.clickhouse-local/config.yml;
  5. /etc/clickhouse-local/config.xml, /etc/clickhouse-local/config.yaml 또는 /etc/clickhouse-local/config.yml.

clickhouse-server와 마찬가지로, 메인 구성 파일 옆의 merge 디렉터리에 있는 .xml, .yaml, .yml, .conf 파일이 그 파일로 병합됩니다: config.xml에는 config.dconf.d, clickhouse-local.yaml에는 clickhouse-local.dconf.d 등입니다.

현재 디렉터리의 merge 디렉터리는 메인 구성 파일이 없어도 적용됩니다: ./config.d./conf.d가 바이너리에 내장된 최소 구성으로 병합됩니다. 이는 디렉터리를 자기 설명적(self-describing)으로 만듭니다. 예를 들어

config.d/datasets.yaml

storage_configuration:
  disks:
    datasets:
      type: object_storage
      object_storage_type: s3
      metadata_type: plain_rewritable
      endpoint: https://data.clickhouse.com/public-datasets/db/
      no_sign_request: true
      readonly: true
      skip_access_check: true

이 디렉터리에서 시작된 모든 clickhouse-localdatasets 디스크를 가지며, 이를 위해 config.xml을 만들 필요가 없습니다.

명령 (Commands)

LS 명령 (LS Command)

clickhouse-local이 접근할 수 있는 현재 작업 디렉터리의 모든 파일을 나열합니다. 대화형 모드에서 다음과 같이 실행할 수 있습니다:

쿼리

ClickHouse local version 26.3.1.1.

:) ls

SELECT _file AS file
FROM file('*', 'One')
ORDER BY file ASC

응답

┌─file────────┐
│ file1.csv   │
│ file2.json  │
│ file3.xml   │
└─────────────┘

-q 인자를 사용해 쿼리로도 실행할 수 있습니다:

./clickhouse-local -q ls

응답

file1.csv
file2.json
file3.xml

CLEAR 명령 (CLEAR command)

터미널 화면을 지웁니다(Linux의 clear 명령이나 많은 터미널의 Ctrl+L과 유사). 이는 클라이언트 측 동작입니다: SQL 엔진으로 전송되지 않습니다.

clickhouse-local에서 이 메타 명령은 대화형 모드와 -q, --queries-file 입력에서 인식됩니다(-q와 같은 클라이언트 경로, ls와 같은 개념). 따라서 맨 clearUNKNOWN_IDENTIFIER 오류를 만들지 않습니다. 원격 **clickhouse-client --queries-file**은 변경되지 않습니다: 파일 내용은 SQL로만 실행됩니다(텍스트 수준 메타 명령 없음).

clickhouse-client에서는 대화형 모드에서만 인식됩니다. -q 또는 쿼리 파일에서는 clear가 여전히 SQL로 파싱되므로, 자동화는 오타를 조용한 no-op으로 만들지 않고 이전의 오류 동작을 유지합니다.

지원되는 형태: clear, CLEAR, /clear(선택적인 뒤따르는 ;는 무시됨). 표준 출력이 터미널이 아니면(예: 출력을 파이핑할 때) 메타 명령은 인식되면 수락되지만 제어 시퀀스를 방출하지 않습니다.

clickhouse-local-q 사용 시:

./clickhouse-local -q clear

예시 (Examples)

쿼리

$ echo -e "1,2\n3,4" | clickhouse-local --structure "a Int64, b Int64" \
    --input-format "CSV" --query "SELECT * FROM table"
Read 2 rows, 32.00 B in 0.000 sec., 5182 rows/sec., 80.97 KiB/sec.
1   2
3   4

이전 예시는 다음과 같습니다:

쿼리

$ echo -e "1,2\n3,4" | clickhouse-local -n --query "
    CREATE TABLE table (a Int64, b Int64) ENGINE = File(CSV, stdin);
    SELECT a, b FROM table;
    DROP TABLE table;"
Read 2 rows, 32.00 B in 0.000 sec., 4987 rows/sec., 77.93 KiB/sec.
1   2
3   4

stdin이나 --file 인자를 사용할 필요가 없으며, file 테이블 함수를 사용해 원하는 만큼 파일을 열 수 있습니다:

쿼리

$ echo 1 | tee 1.tsv
1

$ echo 2 | tee 2.tsv
2

$ clickhouse-local --query "
    select * from file('1.tsv', TSV, 'a int') t1
    cross join file('2.tsv', TSV, 'b int') t2"
1    2

이제 각 Unix 사용자의 메모리 사용량을 출력해 봅시다:

쿼리

$ ps aux | tail -n +2 | awk '{ printf("%s\t%s\n", $1, $4) }' \
    | clickhouse-local --structure "user String, mem Float64" \
        --query "SELECT user, round(sum(mem), 2) as memTotal
            FROM table GROUP BY user ORDER BY memTotal DESC FORMAT Pretty"

응답

Read 186 rows, 4.15 KiB in 0.035 sec., 5302 rows/sec., 118.34 KiB/sec.
┏━━━━━━━━━━┳━━━━━━━━━━┓
┃ user     ┃ memTotal ┃
┡━━━━━━━━━━╇━━━━━━━━━━┩
│ bayonet  │    113.5 │
├──────────┼──────────┤
│ root     │      8.8 │
├──────────┼──────────┤
...

TCP 및 HTTP 리스너 시작하기 (Starting TCP and HTTP Listeners)

clickhouse-local은 TCP(네이티브 프로토콜)와 HTTP 연결을 수락하는 경량 서버로 변환될 수 있습니다. 이는 다른 ClickHouse 도구나 애플리케이션이 실행 중인 clickhouse-local 인스턴스의 데이터베이스와 테이블에 접근할 수 있게 하려 할 때 유용합니다. 각 수신 연결은 자체 세션을 얻는다는 점을 기억하세요: 대화형 clickhouse-local 세션의 임시 테이블과 세션 레벨 설정은 외부 연결에 보이지 않습니다.

리스너를 열려면 SYSTEM START LISTEN을, 닫으려면 SYSTEM STOP LISTEN을 사용하세요:

clickhouse-local \
    --listen_host 127.0.0.1 \
    --tcp_port 9000 \
    --http_port 8123 \
    --query "
        SYSTEM START LISTEN TCP;
        SYSTEM START LISTEN HTTP;
        SELECT * FROM url('http://127.0.0.1:8123/?query=SELECT+42', LineAsString);
        SYSTEM STOP LISTEN TCP;
        SYSTEM STOP LISTEN HTTP;
    "

--listen_host, --tcp_port, --http_port 옵션은 바인드 주소와 포트를 구성합니다. 기본 포트는 TCP용 9000, HTTP용 8123입니다.

HTTP 리스너는 기본 clickhouse-server 구성과 같은 관대한 헤더로 CORS preflight 요청에 응답하므로, 웹 애플리케이션이 브라우저에서 바로 쿼리할 수 있습니다 — origin이 nullfile:// URL에서 열린 웹 UI를 포함해서요. 이를 제한하려면 --config-file로 전달된 구성 파일에 자체 http_options_response 섹션을 정의하세요. 그것이 기본값을 완전히 대체합니다.

보안 기본적으로 clickhouse-local은 임시 사용자 설정으로 실행되므로, 열리는 어떤 리스너든 인증되지 않습니다. users_config 설정을 커스텀 users.xml(예: --config-file로)을 가리켜 사용자와 접근 제어를 명시적으로 구성하지 않는 한 루프백 주소(127.0.0.1 또는 ::1)에 바인드하세요. 인증 없이 비-루프백 주소에서 수신하면 선택한 포트에 도달할 수 있는 누구에게나 로컬 인스턴스의 데이터가 노출됩니다. 루프백 주소도 브라우저에서 도달 가능하다는 점을 기억하세요: HTTP 리스너가 열려 있는 동안 방문하는 어떤 웹 페이지든 로컬 인스턴스를 쿼리할 수 있고, 기본 CORS 헤더 덕분에 결과를 읽을 수 있습니다.

더 알아보기 (Learn more)