Clean Room에서 Snowpark를 사용해요.
Clean Room에서 Snowpark를 사용해요.
지원 종료 공지
레거시 Provider 및 Consumer Data Clean Rooms는 지원이 중단될 예정이에요. 날짜와 마이그레이션 안내는 end-of-life timeline을 참고하세요.
출처: 문서
본문
소개
Snowflake Data Clean Rooms는 대규모 데이터를 쿼리하거나 처리해야 할 때 Clean Room에 더 강력한 컴퓨팅 성능을 제공하기 위해 Snowpark와 함께 작동할 수 있어요.
Clean Rooms는 두 가지 방식으로 Snowpark를 사용할 수 있어요:
-
Snowpark UDFs: Clean Room 코드에서 Snowpark API를 사용하여 Snowpark의 확장성과 처리 성능을 활용하는 Snowpark UDF를 만들 수 있어요.
-
Snowpark Container Services: Snowpark 환경을 더 세밀하게 제어하거나 Snowpark API에서 사용할 수 없는 라이브러리를 사용하려면 Clean Room 내에서 컨테이너를 구성하고 호스팅할 수 있어요. 이렇게 하면 특정 컴퓨팅 및 스토리지 요구 사항에 맞게 환경을 구성하고, 환경에서 사용할 수 있는 라이브러리를 맞춤 설정할 수 있어요.
메모리에 맞지 않을 정도로 큰 데이터를 로드해야 할 때는 to_pandas_batches()를 사용해서 반복 처리하면 돼요. 예를 들어:
df_iter = session.table(intermediary_table_name).to_pandas_batches()
for df in df_iter:
...
복잡한 사용 흐름의 일반적인 설계
하나의 템플릿을 호출해서 데이터를 생성하고 모두 표시할 수도 있지만, 많은 경우 데이터 생성 단계와 결과 조회 단계를 분리하는 것이 더 좋아요. 이렇게 하면 소비자가 매번 재계산을 실행하지 않고도 결과를 여러 번 조회하거나, 프로세스의 다양한 시점에서 데이터를 볼 수 있어요. 흐름을 사용자가 접근할 수 있는 여러 단계로 나누려면 데이터 생성이나 처리를 트리거하는 템플릿과 저장된 결과를 조회하는 템플릿을 각각 만드세요. 복잡한 사용 흐름 설계에 대해 자세히 알아보세요.
Clean Room에서 Snowpark UDF 사용하기
업로드한 Python 코드에서 Snowpark API를 사용하면 대규모 데이터 로드 처리를 가속화할 수 있어요. Clean Rooms는 Snowpark Python API만 지원해요. 프로바이더와 소비자 모두 업로드한 Python 코드에서 Snowpark Python API를 사용할 수 있어요.
사전 요구 사항
-
Snowpark UDF를 실행하는 Clean Rooms는 clean rooms API에서 실행해야 해요. clean rooms UI에서는 실행할 수 없어요.
-
다음 주제를 이해하고 있어야 해요:
-
내부 테이블을 이해하려면 다단계 흐름 설계에 대해 읽어보세요.
Clean Room에서 Snowpark API 사용하기
Clean Room Python 코드에서 Snowpark API를 사용하는 것은 다른 Python UDF를 업로드하고 실행하는 것과 동일해요. 단, snowflake-snowpark-python 라이브러리를 연결해야 해요.
UDF, UDTF, 프로시저를 만들 때는 Snowpark 데코레이터 대신 cleanroom 스키마에서 session.sql을 사용하여 SQL을 실행하세요. 예를 들어:
session.sql("CREATE OR REPLACE FUNCTION cleanroom.udf(...")
기본 단계
Clean Room에서 UDF 또는 UDTF를 통해 Snowpark API를 사용하는 기본 단계는 다음과 같아요:
프로바이더
표준 방식으로 Clean Room을 만들고, 기본 릴리스 지시문을 설정하고, 데이터를 연결하세요.
코드에 맞춰 매우 구체적인 사용 사례를 설계했을 가능성이 높으므로 Clean Room에 조인 정책이나 열 정책을 추가할 필요가 없을 거예요. 물론 추가할 수도 있어요.
provider.load_python_into_cleanroom을 호출하여 사용자 지정 Snowpark 핸들러 코드를 Clean Room에 로드하세요. 코드는 최소한 snowflake-snowpark-python 패키지와 필요한 다른 패키지를 로드해야 해요.
UDF는 데이터를 한 줄씩 처리하고 반환할 수 있지만, Snowpark 사용 사례에서는 일반적으로 별도의 결과 템플릿을 호출하여 읽는 출력 테이블을 생성해요.
기본 릴리스 지시문을 업데이트하세요 (코드 추가로 새 패치 버전이 생성되기 때문이에요).
Snowpark 코드를 실행하기 위한 사용자 지정 템플릿을 만들고 업로드하세요. UDF를 실행하는 유일한 방법은 UDF를 호출하는 템플릿에서 트리거하는 것이에요. UDF 호출 템플릿에 대한 몇 가지 세부 사항은 다음과 같아요:
-
provider.load_python_into_cleanroom에서 지정한 별칭과 매개 변수를 사용하여 함수를 호출해야 해요. 템플릿은 함수의 별칭을 호출할 때cleanroom네임스페이스를 사용해야 해요. -
UDF가 결과를 Clean Room의 테이블에 쓰고, 실행할 때마다 테이블 이름이 다르다면, 결과 생성 템플릿에서 결과 테이블의 이름을 반환해야 하고, 결과 템플릿은 사용자로부터 테이블 이름을 인수로 받아야 해요.
중간 결과 테이블을 생성한 경우 Snowpark UDF가 생성한 결과 테이블에 액세스할 수 있는 사용자 지정 SQL 템플릿을 업로드하세요. 하드코딩된 결과 테이블 이름을 사용하거나, 사용자가 코드로 생성되고 결과 생성 템플릿에서 반환된 테이블 이름을 전달하도록 할 수 있어요.
표준 방식으로 협업자를 추가하고 Clean Room을 게시하세요.
소비자
소비자는 표준 방식으로 Clean Room을 설치하고 분석을 실행해요. 데이터 생성과 결과 읽기가 별도의 템플릿으로 분리된 경우, 소비자는 각 템플릿을 순서대로 호출해야 해요.
예제 코드
다음 예제 코드는 "노출 수 대비 도달 수(reach on impression count)"의 선형 회귀를 업로드하고 실행하여 기울기를 추정하는 방법을 보여줘요.
소비자(consumer)는 먼저 prod_calculate_regression 템플릿을 실행해서 공급자(provider) UDF가 결과를 생성하도록 해요. 공급자 UDF는 다음 작업을 수행해요:
-
노출 데이터를 전처리해요. 공급자의 노출 데이터를 소비자의 데이터와 조인하고, 날짜별 노출 수와 도달 수의 고유 개수(distinct count)를 계산한 다음, 결과를 clean room 내부의 중간 테이블에 저장하는 동적 SQL을 생성해요. 소비자가 테이블을 제공하지 않으면 코드는 공급자의 전체 노출 테이블을 대상으로 실행돼요.
-
중간 테이블을 로드해요. 중간 테이블은 Snowpark 프로시저에 pandas DataFrame으로 로드돼요.
-
회귀 분석을 수행해요. 회귀 분석은
statsmodels라이브러리를 사용해 계산되며, 결과는 pandas DataFrame으로 반환돼요. -
결과를 clean room 내부 테이블에 작성해요. 결과는 clean room 내부의 결과 테이블에 작성되고, 테이블 이름의 ID 접미사가 소비자에게 반환돼요. Snowpark 프로시저가 clean room 내부에서 실행되기 때문에 데이터를 소비자 계정으로 활성화하는 기능은 제한적이에요. 대신 결과를 더 안전하게 유지하기 위해 clean room 내부의 테이블에 작성하고, 소비자가 다른 템플릿을 실행해서 결과 데이터를 읽어요.
-
중간 테이블을 삭제해요. clean room 내부에서 계산 중 생성된 중간 테이블 중 더 이상 필요하지 않은 테이블은 Snowpark 프로시저가 끝나기 전에 삭제돼요.
-
결과 테이블의 이름을 반환해요. 소비자에게 반환된 이름은 결과를 가져오는 템플릿을 실행할 때 지정해야 해요. 이전 실행의 결과가 모두 보관되기 때문이에요.
그런 다음 소비자는 get_results 템플릿을 실행해서 첫 번째 템플릿이 반환한 결과 테이블 접미사를 전달하면 결과를 볼 수 있어요.
아래 예제를 실행하려면 동일한 웹 호스팅 리전에 두 개의 계정이 필요해요(아직 cross-cloud auto-fulfillment을 구현하지 않은 경우). 하나는 공급자용 계정이고 다른 하나는 소비자용 계정이에요.
예제 코드는 추가적인 Snowpark 구성 없이 Snowflake 워크시트에서 실행되어야 해요. 다른 환경에서 실행한다면 Snowpark Python API를 설치하고 구성해야 할 수도 있어요.
추가 정보
clean room에서 Snowpark Container Services 사용하기
Python 코드를 실행하는 환경을 더 세밀하게 제어하려면 clean room 내에서 Snowpark Container Service를 실행할 수 있어요. 이렇게 하면 코드 실행 환경을 세밀하게 제어할 수 있고, 전문화된 컴퓨팅, 스토리지 또는 기타 리소스가 필요해서 성능을 최대화하고 비용을 최소화해야 하는 사용 사례나, 사용자 지정 패키지 또는 기타 환경 기능을 도입해야 하는 경우에 이상적이에요.
clean room에서 컨테이너 서비스를 호스팅하면 템플릿과 사용자 지정 Python 코드가 서비스에서 노출하는 함수를 호출할 수 있어요. Snowpark Container Services를 사용하는 것은 Snowpark에서 UDF를 사용하는 것과 비슷하지만, UDF가 템플릿이 호출할 HTTP 엔드포인트로 노출된다는 점이 달라요. 서비스와 엔드포인트를 정의하고 clean room에 업로드하면 돼요.
내부에서 호스팅되는 엔드포인트는 clean room 내부의 템플릿에서만 접근할 수 있으며, clean room 협업자가 직접 호출할 수는 없어요.
사전 요구 사항
clean room에서 Snowpark Container Services를 사용하려면 다음 주제를 이해하고 있어야 해요:
-
The Snowpark Python API 해당 API를 사용하는 경우.
-
데이터 처리와 결과 노출을 별도의 단계로 나누는 방법을 이해하려면 designing complex usage flows. 문서를 읽어보세요.
기본 단계
공급자
요청을 처리하는 서비스 사양, 코드, 엔드포인트를 생성해요.
이미지 저장소를 만들고 해당 저장소에 SAMOOHA_APP_ROLE 액세스 권한을 부여해요.
다음 단계를 위해 저장소 URL을 확보해요.
이미지를 빌드하고 저장소 URL에 업로드해요.
표준 방식으로 clean room을 만들고, 데이터를 연결하고, 조인 정책을 추가하고, 소비자를 추가해요.
서비스 엔드포인트를 호출하는 템플릿을 Define the templates 문서를 참조하여 정의하고, clean room에 업로드해요. 서비스 함수는 service_functions 네임스페이스에서 생성되고 호출돼요 (UDF는 cleanroom 네임스페이스에서 생성되고 호출되는 것과 달라요).
-- Template to call an SPCS function named train.
SELECT service_functions.train(
{{ source_table[0] }},
{{ provider_join_col }},
{{ my_table[0] }},
{{ consumer_join_col }},
{{ dimensions | sqlsafe }},
) AS train_result;
provider.load_service_into_cleanroom을 호출해서 서비스 세부 정보를 clean room에 업로드해요. 이렇게 하면 이미지 URL, endpoints, 그리고 다른 서비스 옵션이 정의돼요. 여기서 정의한 endpoint 이름은 서비스 사양과 일치해야 하며, 템플릿이 함수를 호출할 때 사용하는 이름이에요.
CALL samooha_by_snowflake_local_db.provider.load_service_into_cleanroom(
$cleanroom_name,
$$
spec:
containers:
- name: lal
image: /dcr_spcs/repos/lal_example/lal_service_image:latest
env:
SERVER_PORT: 8000
endpoints:
- name: lalendpoint
port: 8000
public: false
$$,
$$
functions:
- name: train
args: PROVIDER_TABLE VARCHAR, PROVIDER_JOIN_COL VARCHAR, CONSUMER_TABLE VARCHAR, CONSUMER_JOIN_COL VARCHAR, DIMENSIONS ARRAY, FILTER VARCHAR
returns: VARCHAR
endpoint: lalendpoint
path: /train
$$);
clean room의 기본 릴리스 지시문(default release directive)을 설정해요. 서비스를 업로드하거나 수정할 때마다 새로운 패치 버전이 생성돼요.
clean room을 게시해요.
이미지, 함수, 또는 코드를 변경할 때는 여러분과 consumer 모두 인스턴스를 업데이트해야 해요.
Consumer
-
표준 방식대로 clean room을 설치하고 필요한 데이터를 연결해요.
-
compute pool을 생성하고 clean room에 대한 액세스 권한을 부여해요.
-
쿼리를 실행할 예정이라면(거의 확실히 실행하게 될 거예요), 사용 중인 warehouse에 대해 clean room에 USAGE 권한도 부여해야 해요.
-
samooha_by_snowflake_local_db.consumer.start_or_update_service를 호출해서 service를 시작해요. 이때 clean room 이름, compute pool 이름, 그리고 warehouse 이름(warehouse를 사용하는 경우)을 전달해요. -
SHOW ENDPOINTS IN SERVICE SAMOOHA_CLEANROOM_APP_*clean_room_name*.services.service;를 실행해서 service에서 사용 가능한 endpoints를 확인해요. -
service가 실행 중이 되면, 표준 방식대로
consumer.run_analysis를 호출해서 service endpoints에 액세스하는 clean room 템플릿을 실행하기 시작할 수 있어요.
compute pool 생성
누가 pool을 소유하고 구성해야 하는지에 따라, provider는 clean room 안에 compute pool을 생성할 수도 있고, consumer는 clean room 밖에 compute pool을 생성할 수도 있어요.
compute pool이 clean room 밖에서 생성된 경우, pool에 액세스하고 service를 생성할 수 있도록 clean room에 적절한 권한을 부여해야 해요. 아래와 같이요:
-- Grant access to a warehouse to run queries. Needed only if the service queries Snowflake accounts.
USE ROLE ACCOUNTADMIN;
GRANT USAGE ON WAREHOUSE APP_WH TO APPLICATION SAMOOHA_CLEANROOM_APP_<CLEANROOM_NAME>;
-- Grant SAMOOHA_APP_ROLE privileges to create compute pools and create services
GRANT CREATE COMPUTE POOL ON ACCOUNT TO ROLE SAMOOHA_APP_ROLE WITH GRANT OPTION;
GRANT BIND SERVICE ENDPOINT ON ACCOUNT TO ROLE SAMOOHA_APP_ROLE WITH GRANT OPTION;
USE ROLE SAMOOHA_APP_ROLE;
-- Create the compute pool
CREATE COMPUTE POOL DCR_LAL_POOL
FOR APPLICATION SAMOOHA_CLEANROOM_APP_<CLEANROOM_NAME>
min_nodes = 1 max_nodes = 1
instance_family = highmem_x64_l
auto_resume = true;
-- Grant the clean room the privileges to access a pool running outside the clean room.
GRANT USAGE ON COMPUTE POOL DCR_LAL_POOL TO APPLICATION SAMOOHA_CLEANROOM_<CLEANROOM_NAME>;
-- Allow the clean room to create the service
GRANT BIND SERVICE ENDPOINT ON ACCOUNT TO APPLICATION SAMOOHA_CLEANROOM_APP_<CLEANROOM_NAME>;
서비스 코드 또는 구성 업데이트
provider가 이미지, service 사양, endpoint 이름, 또는 소스 코드를 업데이트하면, provider와 consumer 모두 다음 단계를 수행해야 해요.
1. Provider:
-
필요에 따라 이미지나 소스 코드를 업데이트해요.
-
provider.load_service_into_cleanroom을 호출해요. 그러면 새로운 패치 번호가 반환돼요. -
새 패치 번호와 함께
provider.set_default_release_directive를 호출해요.
2. Consumer:
consumer.start_or_update_service를 호출해요.
서비스 모니터링
기본적으로 consumer는 자신의 service를 모니터링할 수 있어요. 이 동작은 provider.load_service_into_cleanroom의 service_config 인수에 있는 allow_monitoring 값을 사용해서 변경할 수 있어요.
consumer 모니터링이 활성화되면, consumer는 특정 clean room service에 대한 모니터링 로그(형식: SAMOOHA_CLEANROOM_APP_SPCS_*cleanroom_name*.services.service), service ID, 그리고 container에 액세스할 수 있어요. 아래와 같이요:
SELECT VALUE AS log_line
FROM TABLE(
SPLIT_TO_TABLE(SYSTEM$GET_SERVICE_LOGS(
'SAMOOHA_CLEANROOM_APP_SPCS_Lookalike_Demo.services.service', 0, 'lal'), '\n')
);
consumer는 DESCRIBE SERVICE 명령을 사용해서 자신의 service 상태도 확인할 수 있어요. 아래와 같이요:
-- See the state of the service.
DESCRIBE SERVICE SAMOOHA_CLEANROOM_APP_SPCS_Lookalike_Demo.services.service;
SHOW ENDPOINTS IN SERVICE SAMOOHA_CLEANROOM_APP_*clean_room_name*.services.service;를 실행하면 service endpoints를 나열할 수 있어요. 예를 들어:
SHOW ENDPOINTS IN SERVICE SAMOOHA_CLEANROOM_APP_SPCS_Lookalike_Demo.services.service;
예제 코드
다음 노트북과 zip 파일은 clean room에서 Snowflake Container Services를 사용하는 방법을 보여줘요. clean room이 설치된 계정이 두 개 필요해요. 하나는 provider용이고 하나는 consumer용이에요. 두 계정은 같은 클라우드 호스팅 리전에 있어야 해요. 압축된 구성 파일을 사용해서 service를 정의해요.
더 알아보기 (Learn more)
- end-of-life timeline
- Read more about designing complex usage flows.
- Snowpark API
- Snowpark Python API
- The basics of creating a clean room in code.
- The Snowpark Python API.
- How to upload Python UDFs into a clean room.
- How to create custom templates.
- designing multi-step flows
- custom template
- cross-cloud auto-fulfillment
- Provider worksheet example