Snowpark Container Services: 서비스 사용하기

Snowpark Container Services 를 사용하면 컨테이너화된 애플리케이션을 쉽게 배포, 관리, 확장할 수 있습니다. 애플리케이션을 만들고 Snowflake 계정의 리포지토리에 애플리케이션 이미지를 업로드하면 애플리케이션 컨테이너를 서비스 또는 작업 으로 실행할 수 있습니다. 이 항목에서는 서비스를 사용하는 방법을 설명합니다.

서비스는 장기간 실행되며 웹 서비스처럼 자동으로 종료되지 않습니다. 서비스를 생성하면 Snowflake가 실행 중인 서비스를 관리합니다. 예를 들어 서비스 컨테이너가 어떤 이유로든 중지되면 Snowflake는 해당 컨테이너를 다시 시작하여 서비스가 중단 없이 실행됩니다. 더 많은 컴퓨팅 성능과 같이, 서비스에 더 많은 리소스가 필요한 경우 Snowflake는 컴퓨팅 풀 에 노드를 추가로 프로비저닝합니다.

기본 서비스 운영

Snowpark Container Services는 서비스를 생성하고 관리하는 데 사용할 수 있는 SQL 명령 세트를 제공합니다. CREATE SERVICE, ALTER SERVICE, DROP SERVICE, SHOW SERVICES, DESC[RIBE] SERVICE 등의 명령이 포함됩니다.

서비스를 만드는 데 필요한 최소 정보는 다음과 같습니다.

  • 서비스 사양:사양 은 Snowflake에 서비스 실행에 필요한 정보를 제공합니다. 사양은 YAML 파일입니다. CREATE SERVICE 문 내에서 직접 사양을 정의하거나 Snowflake 스테이지에 사양을 업로드하고 CREATE SERVICE 문에서 스테이지 정보를 참조할 수 있습니다.

    대부분의 경우 개발 중에 인라인 사양을 선택할 수 있습니다. 그러나 프로덕션 환경에 서비스를 배포할 때는 관심사 분리 설계 원칙을 적용하고 사양을 스테이지에 업로드하는 것이 좋습니다.

  • 컴퓨팅 풀: Snowflake는 지정된 컴퓨팅 풀 에서 서비스를 실행합니다.

  • 인라인 사양을 사용하여 서비스를 만듭니다.

    CREATE SERVICE echo_service
       IN COMPUTE POOL tutorial_compute_pool
       FROM SPECIFICATION $$
       spec:
         containers:
         - name: echo
           image: /tutorial_db/data_schema/tutorial_repository/my_echo_service_image:tutorial
           readinessProbe:
             port: 8000
             path: /healthcheck
         endpoints:
         - name: echoendpoint
           port: 8000
           public: true
       $$;
    
    Copy
  • 스테이지 정보를 사용하여 서비스를 만듭니다.

    CREATE SERVICE echo_service
      IN COMPUTE POOL tutorial_compute_pool
      FROM @tutorial_stage
      SPECIFICATION_FILE='echo_spec.yaml';
    
    Copy

서비스를 만들면 ALTER SERVICE 명령을 사용하여 서비스를 일시 중단하거나 재개할 수 있습니다.

여러 서비스 인스턴스 만들기 및 자동 크기 조정 구성하기

기본적으로, Snowflake는 지정된 컴퓨팅 풀에서 서비스 인스턴스를 하나 실행합니다. 과도한 워크로드를 관리하려면 시작할 서비스의 최소 인스턴스 수와 필요할 때 Snowflake가 확장할 수 있는 최대 인스턴스 수를 지정하는 MIN_INSTANCES 및 MAX_INSTANCES 속성을 설정하여 여러 서비스 인스턴스를 실행할 수 있습니다.

CREATE SERVICE echo_service
   IN COMPUTE POOL tutorial_compute_pool
   FROM @tutorial_stage
   SPECIFICATION_FILE='echo_spec.yaml'
   MIN_INSTANCES=2
   MAX_INSTANCES=4;
Copy

여러 서비스 인스턴스가 실행 중인 경우 Snowflake는 수신 요청을 분산하기 위해 로드 밸런서를 자동으로 제공합니다.

실행 중인 서비스 인스턴스 수를 자동으로 조정하도록 Snowflake를 구성하려면 다음 단계를 따르십시오.

  1. 서비스 사양 파일에서 서비스 인스턴스에 대한 메모리 및 CPU 요구 사항을 지정합니다. 자세한 내용은 컨테이너 리소스 필드를 참조하십시오.

    resources:
      requests:
       memory: <memory-reserved>
       cpu: <cpu-units>
    
    Copy
  2. CREATE SERVICE 명령을 실행할 때 MIN_INSTANCES 및 MAX_INSTANCES 매개 변수를 설정합니다. 또한 ALTER SERVICE를 사용하여 이러한 값을 변경할 수도 있습니다.

Snowflake는 지정된 컴퓨팅 풀에 최소 서비스 인스턴스 수를 생성하는 것으로 시작한 다음 필요에 따라 인스턴스 수를 자동으로 조정합니다. Snowflake는 (CPU와 메모리 모두에 대해) 80%의 임계값을 사용하여 서비스 인스턴스 수를 확장하거나 축소합니다.

언제든지 지정된 컴퓨팅 풀에서 하나 이상의 서비스 인스턴스가 실행될 수 있습니다. Snowflake는 컴퓨팅 풀 내의 리소스 사용률(메모리 또는 CPU)을 지속적으로 모니터링하여 현재 실행 중인 모든 서비스 인스턴스의 사용량 데이터를 집계합니다.

(모든 서비스 인스턴스에서) 집계된 리소스 사용량이 80%를 초과하면 Snowflake는 컴퓨팅 풀 내에 추가 서비스 인스턴스를 배포합니다. 집계된 리소스 사용량이 80% 미만으로 떨어지면 Snowflake는 실행 중인 서비스 인스턴스를 제거하여 규모를 축소합니다. Snowflake는 빈번한 크기 조정을 방지하기 위해 5분의 안정화 기간을 사용합니다.

다음 크기 조정 동작에 유의하십시오.

  • 서비스 인스턴스의 확장은 서비스용으로 구성된 MIN_INSTANCES 및 MAX_INSTANCES 매개 변수로 제한됩니다.

  • 확장이 필요하고 컴퓨팅 풀 노드에 다른 서비스 인스턴스를 시작하는 데 필요한 리소스 용량이 부족한 경우 컴퓨팅 풀 자동 크기 조정이 트리거될 수 있습니다. 자세한 내용은 컴퓨팅 풀 노드 자동 크기 조정 섹션을 참조하십시오.

  • 서비스를 생성할 때 MAX_INSTANCES 및 MIN_INSTANCES 매개 변수를 지정하지만 서비스 사양 파일에서 서비스 인스턴스의 메모리 및 CPU 요구 사항을 지정하지 않으면 자동 크기 조정이 이루어지지 않습니다. Snowflake는 MIN_INSTANCES 속성으로 지정된 인스턴스 수로 시작하며 크기가 자동으로 조정되지 않습니다.

서비스 나열하기

다양한 SHOW SERVICES 명령을 사용하여 현재 서비스를 나열할 수 있습니다.

  • SHOW SERVICES: 권한이 있는 현재 데이터베이스와 스키마의 서비스를 나열합니다.

  • SHOW SERVICES IN ACCOUNT: 서비스가 속한 데이터베이스 또는 스키마에 관계없이 Snowflake 계정의 서비스를 나열합니다. 이는 계정의 여러 데이터베이스와 스키마에서 생성된 Snowflake 서비스가 있는 경우 유용합니다. 다른 모든 명령과 마찬가지로 SHOW SERVICES IN ACCOUNTS는 권한으로 제어되며, 사용 중인 역할에 보기 권한이 있는 서비스만 반환합니다.

  • SHOW SERVICES IN SCHEMA: 지정된 스키마의 서비스를 나열합니다.

특정 컴퓨팅 풀의 서비스 나열은 다음 2단계 프로세스로 이루어집니다.

  1. SHOW SERVICES를 실행하여 서비스 목록을 가져옵니다.

  2. 특정 컴퓨팅 풀의 서비스에 대해 (RESULT_SCAN 을 사용하여) 이전 쿼리에서 목록을 스캔합니다.

다음 예제 스크립트에서 SHOW SERVICES 명령은 먼저 서비스 이름에 특정 문자열이 있는 현재 데이터베이스와 스키마의 서비스를 나열합니다.

다음으로, SELECT 쿼리는 지정된 컴퓨팅 풀의 서비스만 반환하도록 결과 세트를 필터링합니다. 쿼리는 RESULT_SCAN 함수를 사용하여 이전 SHOW SERVICES 명령의 결과 세트를 가져옵니다.

SHOW SERVICES like '%tutorial%' in account;
SELECT *
    FROM TABLE(RESULT_SCAN(last_query_id()))
    WHERE "compute_pool" = 'TUTORIAL_COMPUTE_POOL';
Copy

서비스 모니터링하기

서비스의 자세한 런타임 상태를 가져오려면 SYSTEM$GET_SERVICE_STATUS를 사용하십시오. 예를 들어 이 함수를 호출하여 서비스가 아직 실행 중인지 또는 서비스 시작에 실패했는지 확인할 수 있습니다. 서비스가 시작하지 못한 경우 이 함수는 실패에 대한 세부 정보를 제공합니다.

이 함수를 호출할 때 서비스 이름을 전달합니다.

CALL SYSTEM$GET_SERVICE_STATUS('echo_service');
Copy

다음은 예시 출력입니다.

  • 하나의 인스턴스를 실행 중이고 하나의 컨테이너가 있는 서비스의 샘플 출력:

    [
       {
          "status":"READY",
          "message":"Running",
          "containerName":"echo",
          "instanceId":"0",
          "serviceName":"ECHO_SERVICE",
          "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_echo_service_image:tutorial",
          "restartCount":0,
          "startTime":"2023-01-01T00:00:00Z"
       }
    ]
    
    Copy

    instanceId 는 컨테이너가 속한 서비스 인스턴스 ID입니다. 이 서비스의 두 인스턴스를 실행하는 경우 출력에는 해당 오브젝트 두 개가 포함되고 각 서비스 인스턴스에 대한 컨테이너 상태가 제공됩니다. 이 경우 인스턴스 ID는 0과 1입니다.

  • 하나의 인스턴스를 실행 중이고 세 개의 컨테이너가 있는 서비스의 샘플 출력:

    [
       {
          "status":"READY",
          "message":"Running",
          "containerName":"some-proxy",
          "instanceId":"0",
          "serviceName":"example_service",
          "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_service_image_proxy:tutorial",
          "restartCount":0,
          "startTime":"2023-01-01T00:00:00Z"
       },
       {
          "status":"READY",
          "message":"Running",
          "containerName":"some-server",
          "instanceId":"0",
          "serviceName":"example_service",
          "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_server:tutorial",
          "restartCount":0,
          "startTime":"2023-01-01T00:00:00Z"
       },
       {
          "status":"READY",
          "message":"Running",
          "containerName":"movies",
          "instanceId":"0",
          "serviceName":"example_service",
          "image":"<account>.registry.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_movies:tutorial",
          "restartCount":0,
          "startTime":"2023-01-01T00:00:00Z"
       }
    ]
    
    Copy

    출력에는 각 컨테이너에 대한 상태 정보가 포함됩니다. 이러한 모든 컨테이너는 인스턴스 ID가 0인 단일 서비스 인스턴스에 속합니다.

SYSTEM$GET_SERVICE_STATUS는 선택적 timeout_secs 인자를 사용합니다. timeout_secs 가 지정되지 않거나 0의 값으로 지정된 경우 함수는 즉시 현재 상태를 반환합니다. timeout_secs 가 지정된 경우 Snowflake는 서비스 상태를 반환하기 전에 지정된 시간 내에 서비스가 종료 상태(READY 또는 FAILED)에 도달할 때까지 기다립니다. 서비스가 지정된 시간 내에 종료 상태에 도달하지 않으면 Snowflake는 지정된 시간 간격이 끝날 때 현재 상태를 반환합니다.

지정하는 제한 시간은 서비스가 준비될 것으로 예상하는 시간을 기준으로 한 대략적인 값이며, 이는 Snowflake가 다른 서비스 및 작업을 중지하고 다른 서비스를 시작하기 전에 지정된 컴퓨팅 풀에서 리소스를 확보하기를 기다리는 경우와 같은 상황을 식별하는 데 도움이 될 수 있습니다. 다음 SYSTEM$GET_SERVICE_STATUS 함수는 10초의 시간 제한을 지정합니다.

call SYSTEM$GET_SERVICE_STATUS('echo_service', 10);
Copy

로컬 컨테이너 로그에 액세스하기

Snowflake는 애플리케이션 컨테이너의 코드가 표준 출력 또는 표준 오류로 출력하는 모든 것을 수집합니다. 코드가 서비스를 디버깅하는 데 유용한 정보를 출력하도록 해야 합니다.

Snowflake는 이러한 컨테이너 로그에 액세스하는 두 가지 방법을 제공합니다.

  • SYSTEM$GET_SERVICE_LOGS 시스템 함수 사용: 특정 컨테이너의 로그에 대한 액세스 권한을 부여합니다. 컨테이너가 종료된 후에도 잠시 동안 시스템 함수를 사용하여 로그에 계속 액세스할 수 있습니다. 시스템 함수는 서비스나 작업을 처음 작성할 때 개발 및 테스트 중에 가장 유용합니다. 자세한 내용은 SYSTEM$GET_SERVICE_LOGS 를 참조하십시오.

  • 이벤트 테이블 사용: 이벤트 테이블을 사용하면 모든 서비스에 걸쳐 여러 컨테이너의 로그에 액세스할 수 있습니다. Snowflake는 나중에 액세스할 수 있도록 이벤트 테이블에 로그를 유지합니다. 이벤트 테이블은 서비스와 작업의 회고적 분석에 가장 적합합니다. 자세한 내용은 이벤트 테이블 사용하기 섹션을 참조하십시오.

SYSTEM$GET_SERVICE_LOGS 사용하기

서비스 이름, 인스턴스 ID, 컨테이너 이름, 선택적으로 검색할 가장 최근 로그 줄 수를 제공합니다. 하나의 서비스 인스턴스만 실행 중인 경우 서비스 인스턴스 ID는 0입니다. 예를 들어, 다음 GET_SERVICE_LOGS 명령은 echo_service 라는 서비스의 인스턴스 0에 속한 echo 라는 컨테이너의 로그에서 후행 10줄을 검색합니다.

CALL SYSTEM$GET_SERVICE_LOGS('echo_service', '0', 'echo', 10);
Copy

서비스 정보(예: 인스턴스 ID 또는 컨테이너 이름)를 모르는 경우 먼저 GET_SERVICE_STATUS를 실행하여 각 인스턴스에서 실행 중인 서비스 인스턴스와 컨테이너에 대한 정보를 얻을 수 있습니다.

출력 예:

+--------------------------------------------------------------------------+
| SYSTEM$GET_SERVICE_LOGS                                                  |
|--------------------------------------------------------------------------|
| 10.16.6.163 - - [11/Apr/2023 21:44:03] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:08] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:13] "GET /healthcheck HTTP/1.1" 200 - |
| 10.16.6.163 - - [11/Apr/2023 21:44:18] "GET /healthcheck HTTP/1.1" 200 - |
+--------------------------------------------------------------------------+
1 Row(s) produced. Time Elapsed: 0.878s

SYSTEM$GET_SERVICE_LOGS 출력에는 다음과 같은 제한 사항이 있습니다.

  • 단순히 표준 출력과 표준 오류 스트림을 병합하므로, 일반 출력과 오류 메시지를 구별하는 것이 불가능합니다.

  • 단일 서비스 인스턴스의 특정 컨테이너에 대해 캡처된 데이터를 보고합니다.

  • 실행 중인 컨테이너에 대한 로그만 보고합니다. 이 함수는 다시 시작된 이전 컨테이너 또는 중지되거나 삭제된 서비스의 컨테이너에서 로그를 가져올 수 없습니다.

  • 이 함수는 최대 100KB의 데이터를 반환합니다.

이벤트 테이블 사용하기

Snowflake는 컨테이너의 표준 출력 및 표준 오류를 캡처하여 계정용으로 구성된 이벤트 테이블에 기록할 수 있습니다. 자세한 내용은 로깅 및 추적 개요 를 참조하십시오.

예를 들어 다음 SELECT 쿼리는 지난 한 시간 동안 기록된 Snowflake 서비스 및 작업 이벤트를 검색합니다.

SELECT TIMESTAMP, RESOURCE_ATTRIBUTES, RECORD_ATTRIBUTES, VALUE
FROM <current-event-table-for-your-account>
WHERE timestamp > dateadd(hour, -1, current_timestamp())
AND RESOURCE_ATTRIBUTES:"snow.executable.type" = 'SnowparkContainers'
ORDER BY timestamp DESC
LIMIT 10;
Copy

이 예에 표시된 것처럼 이벤트 테이블 쿼리의 WHERE 절에 타임스탬프를 포함하는 것이 좋습니다. 다양한 Snowflake 구성 요소에서 생성될 수 있는 데이터의 양 때문에 이 점이 특히 중요합니다. 필터를 적용하면 더 작은 데이터 하위 세트를 검색할 수 있으므로 쿼리 성능이 향상됩니다.

서비스 사양 파일의 spec.logExporters 필드 를 사용하여 이벤트 테이블에 유지하려는 로그 수준(모두, 오류만 또는 없음)을 제어합니다.

이벤트 테이블에는 Snowflake가 컨테이너에서 수집한 로그에 관한 유용한 정보를 제공하는 다음 열이 포함됩니다.

  • TIMESTAMP: Snowflake가 로그를 수집한 시점을 표시합니다.

  • RESOURCE_ATTRIBUTES: 이 열의 각 오브젝트는 어떤 Snowflake 서비스와 해당 서비스의 컨테이너가 로그를 생성했는지 식별합니다. 예를 들어 서비스가 실행될 때 지정된 서비스 이름, 컨테이너 이름, 컴퓨팅 풀 이름과 같은 세부 정보를 제공합니다.

    {
    "snow.containers.compute_pool.id": 549816068,
    "snow.containers.compute_pool.name": "TUTORIAL_COMPUTE_POOL",
    "snow.containers.container.name": "echo",
    "snow.containers.instance.name": "0",
    "snow.containers.restart.id": "cd0cf2",
    "snow.database.id": 549816076,
    "snow.database.name": "TUTORIAL_DB",
    "snow.executable.id": 980991015,
    "snow.executable.name": "ECHO_SERVICE",
    "snow.executable.type": "SnowparkContainers",
    "snow.schema.id": 549816076,
    "snow.schema.name": "DATA_SCHEMA"
    }
    
    Copy
  • RECORD_ATTRIBUTES: Snowflake 서비스의 경우 오류 출처(표준 출력 또는 표준 오류)를 식별합니다.

    { "log.iostream": "stdout" }
    
    Copy
  • VALUE: 표준 출력과 표준 오류는 줄로 나뉘며, 각 줄은 이벤트 테이블에 레코드를 생성합니다.

    "echo-service [2023-10-23 17:52:27,429] [DEBUG] Sending response: {'data': [[0, 'Joe said hello!']]}"
    

이벤트 테이블 구성하기

자세한 내용은 로깅 및 추적 개요 를 참조하십시오.

서비스 사용하기

향후 서비스(아직 생성되지 않은 서비스)에 대한 사용 권한을 역할에 부여할 수 있습니다. 예:

GRANT USAGE ON FUTURE SERVICES IN [DATABASE <name> | SCHEMA <name>]TO ROLE <name>
Copy

서비스를 생성하면 지원되는 다음 세 가지 방법 중 하나를 사용하여 서비스와 통신할 수 있습니다.

  • 서비스 함수: 서비스와 연결된 서비스 함수(UDF)를 생성합니다. 그런 다음 서비스 함수를 사용하여 SQL 쿼리에서 서비스와 통신합니다. 예를 보려면 자습서 1 을 참조하십시오.

  • 수신: 서비스에서 노출하는 공용 엔드포인트를 사용하여 Snowflake 외부에서 서비스에 액세스합니다. 이 경우 Snowflake가 액세스 제어를 관리합니다. 예를 보려면 자습서 1 을 참조하십시오.

  • 서비스 간 통신: 서비스 간 통신에는 Snowflake에서 할당한 서비스 DNS 이름을 사용합니다. 예를 보려면 자습서 3 을 참조하십시오.

다음 섹션에서는 세부 정보를 제공합니다.

서비스 함수: SQL 쿼리에서 서비스 사용하기

서비스 함수는 CREATE FUNCTION을 사용하여 생성하는 사용자 정의 함수(UDF)입니다. 그러나 UDF 코드를 직접 작성하는 대신 UDF를 서비스와 연결합니다. 예를 들어 자습서 1 에서는 서비스 사양에 정의된 대로 하나의 엔드포인트(echoendoint)를 노출하는 echo_service 라는 서비스를 만듭니다.

spec:

  endpoints:
  - name: echoendpoint
    port: 8080
Copy

echoendpoint 는 해당 포트(8080)를 나타내는 사용자에게 친숙한 엔드포인트 이름입니다. 이 서비스 엔드포인트와 통신하려면 다음과 같이 SERVICE 및 ENDPOINT 매개 변수를 제공하여 서비스 함수를 만듭니다.

CREATE FUNCTION my_echo_udf (text varchar)
   RETURNS varchar
   SERVICE=echo_service
   ENDPOINT=echoendpoint
   AS '/echo';
Copy

AS 매개 변수는 서비스 코드에 대한 HTTP 경로를 제공합니다. 이 경로 값은 서비스 코드에서 가져옵니다(예: 자습서 1 의 service.py 참조).

@app.post("/echo")
def echo():
...
Copy

서비스 함수를 호출하면 Snowflake는 요청을 연결된 서비스 엔드포인트와 경로로 보냅니다.

참고

서비스 함수는 작업이 아닌 서비스와 통신하는 데 사용됩니다. 즉, (작업이 아니라) 서비스만 서비스 함수와 연결할 수 있습니다.

서비스의 여러 인스턴스를 실행할 때 선택적 MAX_BATCH_ROWS 매개 변수를 지정하여 Snowflake가 서비스에 일괄적으로 전송하는 최대 행 수인 배치 크기 를 제한함으로써 서비스 함수를 생성할 수 있습니다. 예를 들어, MAX_BATCH_ROWS 가 10이고 100개의 입력 행으로 my_echo_udf 서비스 함수를 호출한다고 가정합니다. Snowflake는 각 배치에 최대 10개의 행이 포함되도록 입력 행을 여러 배치로 분할하고 요청 본문에 행 배치가 포함된 일련의 요청을 서비스에 보냅니다. 배치 크기를 구성하면 처리 시간이 적지 않게 소요될 때 도움이 될 수 있으며, 사용 가능한 모든 서버에 행을 분산시켜도 도움이 될 수 있습니다.

ALTER FUNCTION을 사용하여 서비스 함수를 변경할 수 있습니다. 다음 ALTER FUNCTION 명령은 연결되는 서비스 엔드포인트와 배치 크기를 변경합니다.

ALTER FUNCTION my_echo_udf(VARCHAR)
   SET SERVICE=other_service
   ENDPOINT=otherendpoint
   MAX_BATCH_ROWS=100
Copy

데이터 교환 형식

서비스 함수와 컨테이너 간의 데이터 교환을 위해 Snowflake는 외부 함수가 사용하는 것과 동일한 형식을 따릅니다(데이터 형식 참조). 예를 들어 테이블(input_table)에 데이터 행이 저장되어 있다고 가정합니다.

"Alex", "2014-01-01 16:00:00"
"Steve", "2015-01-01 16:00:00"

이 데이터를 서비스로 보내려면 다음 행을 매개 변수로 전달하여 서비스 함수를 호출합니다.

SELECT service_func(col1, col2) FROM input_table;
Copy

Snowflake는 요청 본문에 다음 형식의 데이터 행 배치를 사용하여 일련의 요청을 컨테이너에 보냅니다.

{
   "data":[
      [
         0,
         "Alex",
         "2014-01-01 16:00:00"
      ],
      [
         1,
         "Steve",
         "2015-01-01 16:00:00"
      ],
      …
      [
         <row_index>,
         "<column1>",
         "<column2>"
      ],
   ]
}
Copy

그런 다음 컨테이너는 다음 형식으로 출력을 반환합니다.

{
   "data":[
      [0, "a"],
      [1, "b"],
      …
      [ row_index,  output_column1]
   ]
}
Copy

표시된 출력 예에서는 결과가 행(“a”, “b”, …)이 있는 1열 테이블이라고 가정합니다.

여러 서비스 인스턴스가 실행 중인 경우 MAX_BATCH_ROWS 매개 변수를 사용하여 서비스 함수를 생성하여 처리할 입력 행을 사용 가능한 모든 서버에 배포할 수 있습니다.

서비스 함수를 생성하고 관리하는 데 필요한 권한

서비스 함수를 생성하고 관리하려면 역할에 다음 권한이 필요합니다.

  • 서비스 함수 생성 방법: 현재 역할에 참조되는 서비스에 대한 USAGE 권한이 있어야 합니다.

  • 서비스 함수 변경 방법: 서비스 함수를 변경하고 이를 다른 서비스와 연결할 수 있습니다. 현재 역할에 새로운 서비스에 대한 USAGE 권한이 있어야 합니다.

  • 서비스 함수 사용 방법: 현재 역할에 서비스 함수에 대한 USAGE 권한이 있어야 하며, 서비스 함수 소유자 역할에는 연결된 서비스에 대한 USAGE 권한이 있어야 합니다.

다음 예제 스크립트는 서비스 함수 사용 권한을 부여하는 방법을 보여줍니다.

USE ROLE service_owner;
GRANT USAGE ON service service_db.my_schema.my_service TO ROLE func_owner;

USE ROLE func_owner;
CREATE OR REPLACE test_udf(v VARCHAR)
  RETURNS VARCHAR
  SERVICE=service_db.my_schema.my_service
  ENDPOINT=endpointname1
  AS '/run';

SELECT test_udf(col1) FROM some_table;

ALTER FUNCTION test_udf(VARCHAR) SET
  SERVICE = service_db.other_schema.other_service
  ENDPOINT=anotherendpoint;

GRANT USAGE ON FUNCTION test_udf(varchar) TO ROLE func_user;
USE ROLE func_user;
SELECT my_test_udf('abcd');
Copy

수신: Snowflake 외부에서 서비스 사용하기

서비스는 사용자가 공용 웹에서 서비스를 사용할 수 있도록 하나 이상의 엔드포인트를 공용으로 노출할 수 있습니다.

참고

Public Private Preview의 경우 Snowflake 계정의 ACCOUNTADMIN이 다음 명령을 실행해야 합니다.

CREATE SECURITY INTEGRATION SNOWSERVICES_INGRESS_OAUTH
TYPE=oauth
OAUTH_CLIENT=snowservices_ingress
ENABLED=true;
Copy

서비스 사양 파일에서 엔드포인트를 공용으로 표시합니다.

spec
  ...
  endpoints
  - name: <endpoint name>
    port: <port number>
    public: true
Copy

서비스 사양에 대한 자세한 내용은 사양 참조 를 확인하십시오.

공용 엔드포인트 액세스 및 인증

Snowpark Container Services에서는 공용 엔드포인트에 대한 요청을 인증하기 위해 Snowflake OAuth가 필요합니다. 예를 들어 사용자 이름과 비밀번호를 사용하여 로그인해야 합니다. 내부적으로는, 로그인하면 Snowflake에서 OAuth 토큰이 생성됩니다. 그런 다음 OAuth 토큰은 서비스 엔드포인트에 요청을 보내는 데 사용됩니다.

참고

  • Snowpark Containers는 Snowflake OAuth를 사용하여 수신을 활성화하므로 사용자의 기본 역할은 ACCOUNTADMIN, SECURITYADMIN, ORGADMIN을 포함한 권한 있는 역할이 될 수 없습니다. 자세한 내용은 통합 사용에서 특정 역할 차단하기 를 참조하십시오.

  • 모든 사람이 서비스에서 노출하는 공용 엔드포인트에 액세스할 수 있는 것은 아닙니다. 서비스에 대해 USAGE 권한이 있는 역할을 가진 동일한 Snowflake 계정의 사용자만 서비스의 공용 엔드포인트에 액세스할 수 있습니다.

브라우저를 사용하거나 프로그래밍 방식으로 공용 엔드포인트에 액세스할 수 있습니다.

  • 브라우저를 사용하여 공용 엔드포인트에 액세스: 브라우저를 사용하여 공용 엔드포인트에 액세스하면 사용자 인증을 위한 자동 리디렉션이 이루어집니다. 자습서 1 을 살펴보면 이 경험을 테스트할 수 있습니다.

  • 프로그래밍 방식으로 공용 엔드포인트에 액세스: 다음 Python 예제 코드는 Python용 Snowflake 커넥터 를 사용하여 먼저 신원을 나타내는 세션 토큰을 생성합니다. 그런 다음 이 코드는 세션 토큰을 사용하여 공용 엔드포인트에 로그인합니다.

    import snowflake.connector
    import requests
    
    ctx = snowflake.connector.connect(
       user="<username>",# username
       password="<password>", # insert password here
       account="<orgname>-<acct-name>",
       session_parameters={
          'PYTHON_CONNECTOR_QUERY_RESULT_FORMAT': 'json'
       })
    
    # Obtain a session token.
    token_data = ctx._rest._token_request('ISSUE')
    token_extract = token_data['data']['sessionToken']
    
    # Create a request to the ingress endpoint with authz.
    token = f'\"{token_extract}\"'
    headers = {'Authorization': f'Snowflake Token={token}'}
    # Set this to the ingress endpoint URL for your service
    url = 'http://<ingress_url>'
    
    # Validate the connection.
    response = requests.get(f'{url}', headers=headers)
    print(response.text)
    
    # Insert your code to interact with the application here
    
    Copy

    코드에서는 다음 사항이 적용됩니다.

    • 계정 정보(<orgname>-<acctname>)를 모르는 경우 자습서 일반 설정 을 참조하십시오.

    • SHOW ENDPOINTS 를 사용하여 서비스에서 노출된 공용 엔드포인트의 ingress_url 을 가져올 수 있습니다.

수신 요청의 사용자별 헤더

수신 엔드포인트에 대한 요청이 도착하면 Snowflake는 HTTP 요청과 함께 다음 헤더를 자동으로 컨테이너에 전달합니다.

Sf-Context-Current-User: <user_name>
Sf-Context-Current-User-Email: <email>
Copy

컨테이너 코드는 선택적으로 이러한 헤더를 읽고, 호출자가 누구인지 파악하고, 다양한 사용자에 대해 컨텍스트별 사용자 지정을 적용할 수 있습니다.

서비스 간 통신

서비스는 Snowflake가 각 서비스에 자동으로 할당하는 DNS 이름을 사용하여 서로 통신할 수 있습니다. 예를 보려면 자습서 3 을 참조하십시오.

DNS 이름 형식은 다음과 같습니다.

<service-name>.<schema-name>.<db-name>.snowflakecomputing.internal

SHOW SERVICES(또는 DESCRIBE SERVICE)를 사용하여 서비스의 DNS 이름을 가져옵니다. 앞의 DNS 이름은 전체 이름입니다. 동일한 스키마에서 생성된 서비스는 <service-name> 만 사용하여 통신할 수 있습니다. 동일한 데이터베이스에 있지만 스키마는 다른 서비스는 <service-name>.<schema-name> 과 같은 스키마 이름을 제공해야 합니다.

Snowflake는 동일한 역할로 생성된 서비스 간의 네트워크 통신을 허용하고, 서로 다른 역할에 의해 생성된 서비스 간의 네트워크 통신을 차단합니다. (보안 등의 이유로) 서비스가 서로 통신하지 못하도록 하려면 다른 Snowflake 역할을 사용하여 해당 서비스를 생성하십시오.

DNS 이름에는 다음과 같은 제한 사항이 있습니다.

  • 데이터베이스, 스키마 또는 서비스 이름은 유효한 DNS 레이블이어야 합니다. (https://www.ietf.org/rfc/rfc1035.html#section-2.3.1 참조). 그렇지 않으면 서비스 생성이 실패합니다.

  • Snowflake는 이름(데이터베이스, 스키마 및 서비스 이름)의 밑줄(_)을 DNS 이름의 대시(-)로 바꿉니다.

  • Snowflake는 서비스의 DNS 이름을 업데이트하지 않으므로 서비스를 생성한 후에는 데이터베이스 또는 스키마 이름을 변경하지 마십시오.

  • DNS 이름은 동일한 계정에서 실행되는 서비스 사이에서 Snowflake 내의 내부 통신에만 사용됩니다. 인터넷에서는 액세스할 수 없습니다.

서비스 코드 업데이트하기

서비스를 생성한 후 ALTER SERVICE 를 사용하여 서비스 코드를 업데이트하십시오. 먼저 수정된 애플리케이션 코드를 이미지 리포지토리에 업로드한 다음 서비스 사양을 인라인으로 제공하거나 Snowflake 스테이지에서 사양 파일 경로를 지정하여 ALTER SERVICE를 호출합니다. 예:

  • 사양을 인라인으로 제공합니다(부분 사양이 표시됨).

    ALTER SERVICE echo_service
    FROM SPECIFICATION $$
    spec:
      
      
    $$;
    
    Copy
  • Snowflake 스테이지 파일 경로를 제공합니다.

    ALTER SERVICE echo_service
    FROM @tutorial_stage
    SPECIFICATION_FILE='echo_spec.yaml';
    
    Copy

요청을 받으면 Snowflake는 새 코드를 사용하여 서비스를 다시 배포합니다.

ALTER SERVICE는 항상 리포지토리에서 가장 최신 버전의 이미지를 사용합니다. 예를 들어 “echo_service:latest” 또는 “echo_service:sometag” 라는 이미지의 여러 버전을 업로드하는 경우 Snowflake는 최신 업로드 이미지 버전을 사용합니다.

DESCRIBE SERVICE 명령을 사용하여 서비스가 실행 중인 이미지 버전을 찾을 수 있습니다. 서비스 소유자인 경우 DESCRIBE SERVICE 출력에는 이미지 다이제스트(이미지의 SHA256)를 가져오는 서비스 사양이 포함됩니다. 예:

spec:
containers:
- name: "echo"
   image: "orgname-acctname.registry-dev.snowflakecomputing.com/tutorial_db/data_schema/tutorial_repository/my_echo_service_image:latest"
   sha256: "@sha256:8d912284f935ecf6c4753f42016777e09e3893eed61218b2960f782ef2b367af"
   env:
      SERVER_PORT: "8000"
      CHARACTER_NAME: "Bob"
   readinessProbe:
      port: 8000
      path: "/healthcheck"
endpoints:
- name: "echoendpoint"
   port: 8000
   public: true
Copy

참고

서비스를 일시 중단하고 재개하는 경우 Snowflake는 동일한 이미지 버전을 배포하는데, 이는 서비스 업데이트 작업이 아닙니다.

권한

권한

사용법

참고

USAGE

서비스와 통신할 권한입니다. 서비스 함수를 생성하고, 공용 엔드포인트를 사용하고, 다른 서비스에서 연결하는 데 필요합니다.

MONITOR

서비스를 모니터링하고 런타임 상태를 가져올 권한입니다.

OPERATE

서비스를 일시 중단하거나 재개할 권한입니다.

OWNERSHIP

서비스를 완벽하게 제어할 권한입니다. 특정 오브젝트에 대해 한 번에 단 하나의 역할만 이 권한을 보유할 수 있습니다.

ALL [ PRIVILEGES ]

OWNERSHIP을 제외하고 서비스에 대한 모든 권한을 부여합니다.