Skip to main content
사용자 정의 함수(UDF)를 사용하면 1,000개가 넘는 기본 제공 FUNCTION만으로는 제공되지 않는 ClickHouse의 기능까지 확장할 수 있습니다. ClickHouse Cloud에서 사용자 정의 함수를 생성하고 관리하는 방법은 여러 가지입니다:
  1. SQL 사용
  2. 콘솔과 직접 작성한 코드 사용
  3. Cloud API 사용(베타)
  4. Terraform 사용(베타)
실행형 UDF는 AWS, GCP, Azure에서 사용할 수 있습니다. 모든 조직에서 기본으로 활성화되어 있으므로 별도로 설정할 필요가 없습니다. 추가 요금도 부과되지 않습니다. UDF 프로세스는 서비스의 파드 내부에서 실행되며 해당 서비스의 CPU와 메모리를 사용합니다.

SQL 사용자 정의 함수

SQL UDF는 람다 표현식으로 CREATE FUNCTION SQL 문을 사용해 생성할 수 있습니다. 이 예시에서는 간단한 실행형 사용자 정의 함수 isBusinessHours를 생성합니다. 이 함수는 특정 타임스탬프가 일반적인 업무 시간 내에 해당하는지 확인하고, 해당하면 true를, 그렇지 않으면 false를 반환합니다.
  1. Cloud Console에 로그인한 다음 SQL 콘솔을 엽니다
  2. 다음 SQL 쿼리를 작성하여 isBusinessHours 함수를 생성합니다:
  1. 새로 생성한 UDF를 테스트하려면 아래 명령을 실행하세요:
다음과 같은 결과가 반환됩니다:
  1. 방금 생성한 UDF를 삭제하려면 DROP FUNCTION 명령을 사용할 수 있습니다:
중요ClickHouse Cloud의 UDF는 사용자 수준 설정을 상속하지 않습니다. UDF는 기본 시스템 설정으로 실행됩니다.
이는 다음을 의미합니다:
  • 세션 수준 설정(SET 문로 설정)은 UDF 실행 Context로 전달되지 않습니다
  • 사용자 프로필 설정은 UDF에 상속되지 않습니다
  • 쿼리 수준 설정은 UDF 실행 중에는 적용되지 않습니다

실행형 사용자 정의 함수

실행형 UDF는 서비스의 각 레플리카와 함께 동작하는 샌드박스 프로세스에서 코드를 실행합니다. python3.11 런타임에서 실행되는 Python 스크립트를 업로드하거나, Native 런타임에서 실행되는 사전 컴파일된 바이너리를 업로드할 수 있습니다. 이 예시에서는 특정 타임스탬프가 일반적인 업무 시간에 해당하는지 확인하는 동일한 간단한 실행형 사용자 정의 함수 isBusinessHours를 생성합니다. 이전에는 SQL로 이를 생성했지만, 이번에는 Python으로 작성하고 콘솔을 통해 구성합니다.
1

Python 파일을 생성하십시오

로컬에 새 파일 main.py를 생성하십시오.
Python 런타임은 python3.11입니다. Python 스크립트에서 타사 패키지를 가져오는 경우, 해당 패키지를 requirements.txt 파일에 나열하면 ClickHouse Cloud가 지원하는 두 가지 CPU 아키텍처(x86-64 및 ARM64) 모두에 맞게 자동으로 설치합니다. 의존성을 ZIP 파일에 직접 포함할 수도 있지만, 이 경우 두 CPU 아키텍처용으로 캐시된 패키지를 모두 포함해야 하므로 requirements.txt를 사용하는 편이 더 간단합니다. 예시는 다음과 같습니다.
ClickHouse Cloud는 다음 단계에서 콘솔을 통해 업로드할 zip 파일에 main.py가 포함되어 있어야 합니다. 파일 이름을 다르게 지정하면 오류가 발생합니다.
2

의존성과 로컬 파일을 함께 패키징하십시오

이 튜토리얼에는 의존성이나 추가 파일이 없으므로 아카이브에는 main.py만 포함하면 됩니다:
의존성 패키지와 기타 로컬 파일(requirements.txt, 휠 파일, 설정 파일, 데이터 파일 등)을 함께 포함하려면 해당 파일을 main.py와 같은 디렉터리에 두고, 그 디렉터리 안에서 zip을 실행하여 main.py가 아카이브의 최상위에 위치하도록 하십시오:
Python 코드에서 os.path.dirname(os.path.abspath(__file__))를 사용하면 로컬에 번들된 파일의 기본 디렉터리 경로를 참조할 수 있습니다. 이 코드는 ZIP 아카이브 안에서 main.py가 위치한 디렉터리의 절대 경로를 반환하므로, 이를 통해 함께 번들된 다른 파일에 액세스할 수 있습니다:
이 기능은 다음과 같은 경우에 유용합니다.
  • UDF와 함께 번들로 제공되는 설정 파일에 액세스해야 하는 경우
  • 사용자 정의 의존성을 위한 휠 패키지를 로드해야 하는 경우
  • 추가 스크립트나 데이터 파일을 참조해야 하는 경우
심볼릭 링크는 허용되지 않습니다ClickHouse Cloud는 심볼릭 링크(symbolic link)가 포함된 UDF 아카이브를 거부합니다. ZIP bundle에는 일반 파일과 디렉터리만 포함되어야 합니다. 심볼릭 링크가 포함된 파일을 업로드하면 유효성 검사에 실패합니다.
3

콘솔에서 UDF를 생성하십시오

  1. Cloud console 홈페이지에서 왼쪽 하단 메뉴에 있는 조직 이름을 클릭하십시오.
  2. 메뉴에서 User-defined functions를 선택하십시오.
  3. 사용자 정의 함수 페이지에서 Set up a UDF를 클릭하십시오. 화면 오른쪽에 구성 패널이 열립니다.
  4. 함수 이름을 입력하십시오. 이 예시에서는 isBusinessHours를 사용합니다.
  5. 함수 유형으로 Executable pool 또는 Executable 중 하나를 선택하십시오.
    • Executable pool: 오래 실행되는 프로세스 풀을 한 번 시작한 후 여러 블록과 쿼리에서 재사용합니다. 거의 모든 워크로드에 권장됩니다.
    • Executable: 데이터 블록을 처리할 때마다 새 프로세스를 시작합니다. 호출 간에 프로세스가 상태를 유지해서는 안 되는 경우에만 사용하십시오.
  6. Runtime type을 선택하십시오. 이 예시에서는 python3.11을 그대로 둡니다. 미리 컴파일된 바이너리를 업로드하려면 Native를 선택하십시오. 자세한 내용은 네이티브 런타임을 참조하십시오.
  7. 이 예시에서는 기본 설정을 사용합니다. 전체 구성 매개변수 목록과 Cloud 기본값은 구성 참고를 참조하십시오.
  8. Browse File을 클릭하여 이 튜토리얼을 시작할 때 생성한 .zip 파일을 업로드하십시오.
  9. 새 인수를 추가하십시오. 이 예시에서는 유형이 DateTime인 timestamp 인수를 추가합니다.
  10. 반환 유형을 선택하십시오. 이 예시에서는 Bool을 선택합니다.
  11. Create UDF를 클릭하십시오. 대화 상자에 현재 빌드 상태가 표시됩니다.
    • 문제가 발생하면 상태가 error로 바뀝니다.
    • 문제가 없으면 상태가 building에서 provisioning으로 넘어갑니다. 프로비저닝을 완료하려면 서비스가 활성 상태여야 합니다. 서비스가 유휴 상태라면 UDF details 패널에서 서비스 이름 옆의 Wake Up Service를 클릭하십시오.
    • 완료되면 상태가 deployed로 바뀝니다.
4

UDF 테스트

  1. 페이지 왼쪽 상단에서 Settings - return to your service view를 클릭하여 SQL 콘솔 홈 페이지로 돌아갑니다
  2. 왼쪽 메뉴에서 SQL Console을 클릭합니다
  3. 다음 쿼리를 작성합니다:
다음과 같은 결과가 표시됩니다:
5

새 버전을 생성하십시오

UDF의 코드나 설정을 변경하려면 새 버전을 생성하십시오. 버전은 생성 후 변경할 수 없습니다. Edit 패널에서는 UDF를 할당할 서비스만 관리할 수 있으며, 이 패널에서 파일을 업로드해도 배포된 코드는 대체되지 않습니다.
  1. Cloud console 홈페이지에서 왼쪽 하단 메뉴에 있는 조직 이름을 클릭하세요.
  2. 메뉴에서 User-defined functions를 선택하세요.
  3. isBusinessHours UDF의 Actions 아래에 있는 점 3개를 선택한 다음 Create new version을 클릭하세요.
  4. 수정한 코드가 담긴 zip 파일을 업로드하거나 설정을 변경한 후, 새 버전을 적용할 서비스를 선택하고 Create new version을 클릭하세요.
새 버전은 이전 버전의 서비스 어태치먼트를 상속하지 않습니다. 새 버전 패널에는 서비스 셀렉터가 있으므로, 한 서비스에서 먼저 버전을 테스트한 후 서비스별로 새 버전을 적용하거나 이전 버전으로 되돌릴 수 있습니다. 각 서비스에는 한 번에 하나의 함수 버전만 적용됩니다.executable_pool UDF는 풀을 다시 로드하기 전까지 장기 실행 풀 프로세스가 이전 버전을 계속 실행합니다. UDF 패널에서 해당 서비스 옆에 있는 Reload UDF 작업을 사용하십시오. 이 작업은 해당 서비스에서 SYSTEM RELOAD FUNCTION ON CLUSTER default isBusinessHours를 실행합니다.이제 콘솔을 통해 첫 번째 사용자 정의 함수를 추가하고 정상적으로 실행되는지 확인했으며, 필요할 때 새 버전을 생성하는 방법도 살펴보았습니다.

네이티브 런타임(컴파일된 바이너리)

네이티브 런타임을 사용하면 Python 스크립트 대신 미리 컴파일된 바이너리를 업로드할 수 있습니다. UDF를 생성할 때 Runtime type을 Native로 설정하십시오(API에서는 runtime: native). 샌드박스에는 아무것도 자동으로 설치되지 않으므로, 바이너리 실행에 필요한 모든 요소는 바이너리에 함께 컴파일되어 있어야 합니다. 현재 지원되는 언어는 Rust, Go, C++, 그리고 Bun으로 바이너리로 컴파일한 JavaScript입니다. Bun은 1.4.0 및 1.4.2 버전에서 테스트되었으며, 다른 버전에서는 정상적으로 동작하지 않을 수 있습니다. 아카이브에는 CPU 아키텍처별로 실행 파일이 하나씩 포함되어야 하며, 각 실행 파일은 별도의 폴더에 있어야 합니다:
ClickHouse Cloud 서비스는 두 아키텍처 모두에서 실행되므로 두 아키텍처용 바이너리가 모두 필요합니다. 실행 파일의 이름은 반드시 main이어야 하며, 인수 없이 실행됩니다. 모드나 하위 명령은 일반 함수 인수로 전달하십시오. 정적으로 링크된 바이너리를 사용할 것을 강력히 권장합니다. 정적 바이너리는 호스트의 시스템 라이브러리에 의존하지 않는데, 이러한 라이브러리의 시스템 호출은 서버 버전마다 다를 수 있습니다. 또한 샌드박스의 시스템 호출 정책도 정적 바이너리에 맞게 조정되어 있습니다. 동적으로 링크된 바이너리는 glibc에만 링크되어 있고 glibc 2.35 이하 버전으로 빌드된 경우에만 동작합니다. Bun으로 컴파일한 JavaScript는 항상 동적으로 링크됩니다.
데이터 파일 경로는 실행 파일 기준으로 지정하십시오아키텍처 폴더의 파일은 바이너리와 같은 위치에 배포되지만, 프로세스가 해당 디렉터리에서 시작되지는 않습니다. 따라서 파일 경로는 작업 디렉터리가 아닌 실행 파일 자체의 경로를 기준으로 지정해야 합니다. Go에서는 filepath.Dir(os.Args[0]) 또는 os.Executable()을, Rust에서는 std::env::current_exe()를 사용하십시오. 필요한 파일이 없으면 별도 알림 없이 폴백하지 말고, stderr에 메시지를 출력한 뒤 0이 아닌 코드로 종료하십시오.
네이티브 UDF에서는 네트워크를 활성화할 수 없으며, 아웃바운드 네트워크 액세스는 Python 런타임에서만 사용할 수 있습니다. 자세한 내용은 네트워크 액세스를 참조하십시오. 두 아키텍처용 바이너리를 각각 빌드하십시오. Rust에서는 두 타깃을 한 번만 추가한 다음 각각 빌드합니다:
Go 예시:
폴더를 zip으로 압축하기 전에 각 출력 파일을 amd64/main과 arm64/main에 복사하십시오. wire 프로토콜은 Python 런타임과 동일합니다. 프로세스는 stdin에서 인수를 읽고, 구성된 포맷으로 결과를 stdout에 씁니다. 자세한 내용은 포맷 및 청크 헤더를 참조하십시오. llm-token-udf 리포지토리에서 빌드 스크립트가 포함된 Rust 및 Go Native UDF를 확인할 수 있습니다.

구성 참고

다음 설정은 콘솔과 API에서 제공됩니다. 기본값은 ClickHouse Cloud 기준이며, 일부 항목은 오픈 소스 기본값과 다릅니다. 다음 오픈 소스 설정은 ClickHouse Cloud에서 관리하므로 UDF별로 변경할 수 없습니다: command_termination_timeout, lifetime, stderr_reaction, check_exit_code, execute_direct. pool_size의 기본값은 오픈 소스에서는 16이지만 Cloud에서는 3입니다. 오픈 소스 설정 전체 목록은 실행형 사용자 정의 함수에서 확인할 수 있습니다. 함수 이름은 ^[A-Za-z][A-Za-z0-9_]*$ 패턴과 일치해야 하고, 조직 내에서 고유해야 하며, ClickHouse 내장 함수의 이름과 같을 수 없습니다. 예약된 이름은 API에서 거부됩니다. 모든 인수에는 같은 패턴을 따르는 이름을 지정해야 하며, API와 Terraform에서는 포맷과 관계없이 인수 이름이 필수입니다. 심볼릭 링크가 포함된 아카이브는 거부됩니다.

포맷과 청크 헤더

TabSeparated는 기본 포맷이자 가장 단순한 포맷입니다. 양쪽 모두에서 탭, 줄바꿈, 백슬래시를 이스케이프해야 합니다. RowBinary는 바이너리 데이터를 안전하게 처리하며 ClickHouse 측에서 텍스트 포맷 변환과 파싱을 거치지 않으므로, 큰 문자열을 다룰 때는 이 포맷을 사용하는 것이 좋습니다. Send chunk header를 켜면 ClickHouse는 각 청크 앞에 행 수를 10진수 텍스트로 쓰고 \n을 붙인 다음, 구성된 포맷으로 행을 씁니다. 프로세스는 정확히 그 수만큼 행을 읽고, 같은 수의 결과를 쓴 뒤, 한 번 플러시해야 합니다. 이 옵션을 끄면 TabSeparated, RowBinary, JSONEachRow 같은 행 지향 포맷을 읽으면서 출력을 버퍼링하는 프로세스는 블록이 언제 끝나는지 알 수 없으므로, 쿼리가 읽기 타임아웃이 발생할 때까지 멈추게 됩니다. 행마다 플러시하지 않는 UDF라면 반드시 이 옵션을 활성화하십시오. Native 포맷은 블록 경계 정보를 이미 포함하고 있으므로, Native UDF는 헤더 없이도 블록 하나를 읽고, 블록 하나를 쓰고, 플러시할 수 있습니다.

네트워크 액세스

네트워크 액세스는 Python 런타임에서만 사용할 수 있으며, Native UDF에서는 네트워크를 활성화할 수 없습니다. 콘솔에서 생성한 Python UDF는 네트워크 액세스가 활성화된 상태로 빌드되며, 이를 변경하는 콘솔 설정은 없습니다. API에서는 sandboxType으로 아웃바운드 연결을 허용하는 netenable과 허용하지 않는 basic 중 하나를 선택합니다. Terraform 프로바이더에서는 동일한 옵션을 sandbox_type으로 제공합니다. 네트워크 액세스를 사용하면 공용 인터넷 엔드포인트로의 아웃바운드 연결이 허용됩니다. 프라이빗 네트워크, 링크 로컬(link-local) 주소, 내부 주소로의 연결은 차단됩니다. 샌드박스(sandbox)에는 클라우드 아이덴티티가 없습니다. 즉, 인스턴스 역할, 메타데이터 엔드포인트, 상속된 환경 변수가 모두 없으므로 UDF는 사용자가 직접 제공한 자격 증명만 사용할 수 있습니다. 네트워크 액세스는 UDF 버전을 빌드할 때 적용되므로, 네트워크 액세스 없이 생성된 기존 버전에서 이를 사용하려면 새 버전을 생성해야 합니다. 아직 UDF용 시크릿 저장소는 제공되지 않습니다. 구성 파일을 zip에 함께 포함하고 __file__ 기준 상대 경로로 읽으십시오. 키는 절대 SQL에 포함하지 마십시오.

메모리 제한

**메모리 제한(Memory limit)**은 각 샌드박스 프로세스가 사용할 수 있는 최대 메모리를 MiB 단위로 설정합니다. 설정하지 않으면 샌드박스 기본값인 4 GiB가 적용됩니다. 이 제한은 상주 메모리(resident memory)가 아니라 가상 주소 공간(virtual address space)을 기준으로 적용됩니다. 따라서 넓은 주소 범위를 미리 예약하는 런타임에는 실제 사용량보다 훨씬 넉넉한 여유 용량(headroom)을 두어야 합니다. 예를 들어 Go는 시작 시점에 1 GiB를 크게 웃도는 주소 공간을 예약합니다. 프로세스가 제한을 초과하면 프로세스 내부에서 메모리 할당이 실패합니다. 이 경우 Python UDF는 MemoryError 트레이스백을 출력하며 종료되고, 쿼리는 해당 stderr 내용을 오류 메시지에 포함한 채 실패합니다.

결정론적 함수와 쿼리 캐시

기본적으로 UDF는 비결정적 함수로 취급됩니다. use_query_cache = 1이 설정된 상태에서 UDF를 호출하는 쿼리는 query_cache_nondeterministic_function_handling 값을 변경하지 않는 한 QUERY_CACHE_USED_WITH_NONDETERMINISTIC_FUNCTIONS 오류와 함께 실패합니다. Deterministic은 함수가 동일한 인수에 대해 항상 동일한 결과를 반환하는 경우에만 활성화하십시오. 이 옵션을 활성화하면 쿼리 캐시가 해당 함수를 호출하는 쿼리의 결과를 저장하고 재사용할 수 있습니다. 다만 같은 쿼리에 now, today, rand 등 다른 비결정적 함수가 포함되어 있으면 기본 처리 방식인 throw에서는 여전히 캐싱되지 않습니다. query_cache_nondeterministic_function_handling = 'save'로 설정하면 이러한 쿼리도 캐싱되며, 'ignore'로 설정하면 캐싱하지 않고 쿼리를 실행합니다.

서비스 재시작

첫 번째 UDF를 연결하면 서비스가 재시작됩니다서비스에 첫 번째 UDF를 연결하면 서비스의 파드에 헬퍼 컨테이너(helper container)가 추가되고 롤링 재시작이 수행됩니다. 이후 UDF를 추가로 연결할 때는 재시작되지 않습니다. 서비스에서 마지막 UDF를 제거하면 다시 롤링 재시작이 수행됩니다. 이 점을 고려하여 첫 번째 UDF의 연결 시점을 계획하십시오.

모니터링

ClickHouse 26.6 이상에서는 실행형 UDF의 리소스 사용량을 8개의 카운터에 기록하며, 이 카운터는 모두 ExecutableUserDefinedFunction 접두사로 시작합니다. 쿼리 단위로는 system.query_log의 ProfileEvents 맵 컬럼에 엔트리로 기록됩니다. 서버 전체 단위로는 서버 시작 이후의 누적값이 system.events의 행으로 기록되고, 시간에 따라 샘플링된 값이 system.metric_log의 ProfileEvent_<name> 컬럼으로 기록됩니다. 카운터 접미사는 다음과 같습니다. system.asynchronous_metrics에는 ExecutableUserDefinedFunctionProcesses와 ExecutableUserDefinedFunctionMemoryResidentBytes가 있습니다. 후자는 현재 실행 중인 UDF 프로세스들의 VmRSS를 합한 값입니다. 공유 페이지가 프로세스마다 중복 집계되므로 이 값은 상한값으로 보아야 합니다.
system.query_log.memory_usage는 ClickHouse 서버 프로세스의 메모리 사용량만 반영하며, UDF 프로세스의 메모리 사용량은 포함하지 않습니다.

성능 가이드

executable_pool을 사용하십시오. executable을 사용하면 데이터 블록마다 새 프로세스가 시작되므로, 블록마다 시작 비용이 발생합니다. 모든 호출에는 고정 비용이 따릅니다. 처리된 행 수에 비해 ExecutableUserDefinedFunctionInvocations 값이 매우 높다면, 해당 쿼리의 preferred_block_size_bytes 값을 높여 블록마다 더 많은 행이 담기도록 하십시오. 단일 쿼리는 한 번에 최대 max_threads개의 풀 프로세스만 사용하므로, 풀 크기를 max_threads보다 크게 설정해도 해당 쿼리의 성능은 개선되지 않습니다. 처음에는 풀 크기를 작게 설정하고, ExecutableUserDefinedFunctionPoolWaitMicroseconds 값이 무시할 수 없는 수준이 되면 늘리십시오. 모든 행은 프로세스 경계를 넘어 전달됩니다. UDF는 SQL로 표현할 수 없는 로직에 사용하는 것이며, 내장 함수나 SQL UDF로 처리할 수 있는 단순한 행 단위 작업에는 적합하지 않습니다.

문제 해결

UDF 실행이 실패하면 쿼리는 오류 코드 754(UDF_EXECUTION_FAILED)와 함께 실패합니다. 자식 프로세스의 stderr 출력이 오류 메시지에 포함되므로, 진단 정보는 stderr에 기록하고 0이 아닌 종료 코드로 종료하십시오.
자주 발생하는 사례는 다음과 같습니다.
  • 쿼리가 멈춘 뒤 타임아웃으로 실패하는 경우: 프로세스가 Send chunk header를 활성화하지 않은 상태에서 행 지향 포맷으로 출력을 버퍼링했기 때문입니다. 이 옵션을 활성화하고 청크마다 한 번씩 플러시하거나, Native 포맷을 사용한다면 블록마다 한 번씩 플러시하십시오.
  • 반환 코드 1과 함께 MemoryError 트레이스백이 발생하는 경우(Python): 메모리 한도를 초과했기 때문입니다. Memory limit 값을 늘리거나 프로세스당 메모리 사용량을 줄이십시오.
  • 부하가 높을 때 executable 유형에서 간헐적으로 실패하는 경우: executable_pool로 전환하십시오.
  • 빌드 상태가 오류인 경우: zip 루트에 main.py(Python) 또는 amd64/main 및 arm64/main(Native)이 없거나, 아카이브에 심볼릭 링크가 포함되어 있기 때문입니다.
  • 함수를 생성할 수 없는 경우: 함수 이름이 내장 함수와 충돌하기 때문입니다.

Cloud API를 사용하여 UDF 관리

콘솔의 수명 주기 작업은 ClickHouse Cloud API를 통해 프로그래밍 방식으로도 사용할 수 있습니다. UDF 엔드포인트를 사용하면 소스 아카이브 업로드, FUNCTION 및 버전 생성, 서비스 ATTACH 및 분리, 버전 및 FUNCTION 삭제를 스크립트로 처리할 수 있습니다. API에는 다시 로드 작업이 없으므로, executable_pool UDF의 새 버전을 서비스에 ATTACH한 후에는 풀 프로세스가 새 버전을 사용하도록 해당 서비스에서 SQL로 SYSTEM RELOAD FUNCTION ON CLUSTER default <name>을 실행하십시오.
이 엔드포인트는 베타이며 API 계약은 변경될 수 있습니다.
API를 통해 UDF를 생성하고 배포하는 일반적인 워크플로는 다음과 같습니다.
  1. 사전 서명된 application/zip 업로드 URL을 받기 위해 업로드 URL을 생성한 다음, 해당 URL로 ZIP 아카이브를 업로드합니다. 각 업로드 ID는 생성 또는 버전 생성 시도에 한 번만 사용할 수 있습니다. 재시도할 때는 새 업로드 URL을 요청하십시오.
  2. 업로드한 아카이브로부터 FUNCTION 이름, 런타임, 인수 및 반환 유형을 지정하여 UDF를 생성합니다.
  3. UDF를 서비스에 ATTACH합니다. 버전을 생략하면 준비된 최신 버전이 ATTACH됩니다. 서비스가 실행 중이어야 하며, 유휴 상태인 서비스는 먼저 시작할 수 있습니다.
위에서 설명한 기능을 지정하는 요청 필드는 다음과 같습니다. 전체 엔드포인트 목록은 다음과 같습니다. 요청 및 응답 스키마는 UDF API 참조를 확인하십시오.

Terraform으로 UDF 관리

공식 ClickHouse Terraform 프로바이더에는 Infrastructure as Code 방식으로 UDF를 관리할 수 있는 2개의 리소스가 포함되어 있습니다.
  • clickhouse_udf는 FUNCTION 자체를 관리합니다. FUNCTION 소스 코드가 포함된 ZIP 아카이브를 사용하며, 아카이브 hash가 변경될 때마다 새 버전을 publish하고 빌드가 완료될 때까지 기다립니다.
  • clickhouse_udf_attachment는 UDF 버전을 서비스에 ATTACH합니다. 서비스에는 한 번에 FUNCTION의 버전을 최대 1개만 ATTACH할 수 있습니다. 고정 버전 번호를 지정하거나 clickhouse_udf.<name>.version을 참조하여 서비스를 최신 버전으로 자동 업데이트할 수 있습니다.
이 리소스는 프로바이더 버전 3.24.0 이상에서 사용할 수 있습니다. 베타 상태이므로 향후 프로바이더 버전에서 동작이 변경될 수 있습니다.
예를 들어, 앞선 예시의 isBusinessHours UDF를 Terraform으로 배포하려면 다음과 같이 합니다.
위에 표시된 필수 속성 외에도 clickhouse_udf 리소스는 format, pool_size, max_command_execution_time, command_read_timeout, command_write_timeout, send_chunk_header, sandbox_type, sandbox_version, return_name, fail_on_build_error를 지원합니다. 전체 스키마는 리소스 문서를 참조하십시오. 새 버전을 프로덕션에 반영하기 전에 개발 서비스에서 먼저 테스트하려면, attachment 하나는 최신 버전을 추적하도록 하고 다른 하나는 변수로 버전을 고정하십시오. 개발 attachment는 새 빌드가 나올 때마다 자동으로 해당 버전을 따라가고, 프로덕션 attachment는 var.prod_udf_version을 변경할 때만 업데이트됩니다.
프로바이더는 아직 deterministic 및 메모리 제한 설정을 지원하지 않습니다. 두 항목 모두 버전을 생성할 때 설정되므로, 프로바이더를 통해 publish된 버전에는 이 항목을 지정할 수 없습니다. 이 항목을 사용하려면 콘솔 또는 API를 통해 해당 버전을 생성하세요.
ATTACH는 준비된 상태인 버전에서만 성공하며, 완료하는 데 몇 분이 걸릴 수 있습니다. 유휴 상태의 서비스는 자동으로 시작됩니다. 또한 프로바이더는 풀을 다시 로드하지 않습니다. executable_pool UDF는 ATTACH된 버전이 변경된 후 해당 서비스에서 SYSTEM RELOAD FUNCTION ON CLUSTER default <name>을 실행하세요. clickhouse_udf 리소스를 삭제하면 해당 FUNCTION의 모든 버전이 제거되고 모든 서비스에서 분리됩니다.