Snowpark Container Services: como trabalhar com serviços

O Snowpark Container Services permite implantar, gerenciar e dimensionar facilmente aplicativos em contêineres. Depois de criar um aplicativo e fazer upload da imagem do aplicativo para um repositório em sua conta do Snowflake, você poderá executar os contêineres do aplicativo como um serviço ou um trabalho. Este tópico explica como trabalhar com serviços.

Um serviço é de longa duração e, como um serviço web, não termina automaticamente. Depois de criar um serviço, o Snowflake gerencia o serviço em execução. Por exemplo, se um contêiner de serviço parar, por qualquer motivo, o Snowflake reinicia esse contêiner para que o serviço seja executado ininterruptamente. Se seu serviço precisar de mais recursos, como mais poder de computação, o Snowflake provisionará nós adicionais no pool de computação.

Operações básicas de serviço

O Snowpark Container Services fornece um conjunto de comandos SQL que você pode usar para criar e gerenciar um serviço. Isso inclui: CREATE SERVICE, ALTER SERVICE, DROP SERVICE, SHOW SERVICES e DESC[RIBE] SERVICE.

As informações mínimas necessárias para criar um serviço incluem:

  • Uma especificação de serviço: esta especificação fornece ao Snowflake as informações necessárias para executar seu serviço. A especificação é um arquivo YAML. Você pode definir a especificação diretamente em uma instrução CREATE SERVICE ou fazer upload da especificação para um estágio Snowflake e referenciar as informações do estágio na instrução CREATE SERVICE.

    Na maioria dos casos, durante o desenvolvimento, você pode escolher a especificação embutida. No entanto, quando implementar o serviço em um ambiente de produção, é aconselhável aplicar o princípio de design da separação de interesses e carregar a especificação para um estágio.

  • Um pool de computação: o Snowflake executa seu serviço no pool de computação especificado.

Exemplos

  • Crie um serviço usando uma especificação embutida:

    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
  • Crie um serviço usando informações de estágio:

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

Depois de criar um serviço, você pode usar o comando ALTER SERVICE para suspender ou retomar o serviço.

Criação das várias instâncias de serviço e configuração do dimensionamento automático

Por padrão, o Snowflake executa uma instância do serviço no pool de computação especificado. Para gerenciar cargas de trabalho pesadas, você pode executar várias instâncias de serviço definindo as propriedades MIN_INSTANCES e MAX_INSTANCES, que especificam o número mínimo de instâncias do serviço para começar e o número máximo de instâncias para as quais o Snowflake pode escalar quando necessário.

Exemplo

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

Quando várias instâncias de serviço estão em execução, o Snowflake fornece automaticamente um balanceador de carga para distribuir as solicitações recebidas.

Para configurar o Snowflake para dimensionar automaticamente o número de instâncias de serviço em execução, siga estas etapas:

  1. Especifique os requisitos de memória e CPU para sua instância de serviço no arquivo de especificação de serviço. Para obter mais informações, consulte a campo container.resources.

    Exemplo

    resources:
      requests:
       memory: <memory-reserved>
       cpu: <cpu-units>
    
    Copy
  2. Ao executar o comando CREATE SERVICE, defina os parâmetros MIN_INSTANCES e MAX_INSTANCES. Você também pode usar ALTER SERVICE para alterar esses valores.

O Snowflake começa criando o número mínimo de instâncias de serviço no pool de computação especificado e depois dimensiona automaticamente o número de instâncias conforme necessário. Snowflake usa um limite de 80% (para CPU e memória) para aumentar ou diminuir o número de instâncias de serviço.

A qualquer momento, uma ou mais instâncias de serviço podem estar em execução no pool de computação especificado. O Snowflake monitora continuamente a utilização de recursos (memória ou CPU) no pool de computação, agregando os dados de uso de todas as instâncias de serviço em execução no momento.

Quando o uso de recursos agregados (em todas as instâncias de serviço) ultrapassa 80%, o Snowflake implanta uma instância de serviço adicional no pool de computação. Se o uso de recursos agregados cair abaixo de 80%, o Snowflake reduz a escala removendo uma instância de serviço em execução. Snowflake usa uma janela de estabilização de cinco minutos para evitar o dimensionamento frequente.

Observe os seguintes comportamentos de dimensionamento:

  • O dimensionamento das instâncias de serviço é limitada pelos parâmetros MIN_INSTANCES e MAX_INSTANCES configurados para o serviço.

  • Se o dimensionamento for necessário e os nós do pool de computação não tiverem a capacidade de recursos necessária para iniciar outra instância de serviço, o escalonamento automático do pool de computação poderá ser acionado. Para obter mais informações, consulte Dimensionamento automático de nós do pool de computação.

  • Se você especificar os parâmetros MAX_INSTANCES e MIN_INSTANCES ao criar um serviço, mas não especificar os requisitos de memória e CPU para sua instância de serviço no arquivo de especificação de serviço, nenhum dimensionamento automático ocorrerá; Snowflake começa com o número de instâncias especificado pela propriedade MIN_INSTANCES e não será dimensionado automaticamente.

Listagem de serviços

Você pode usar vários comandos SHOW SERVICES para listar os serviços atuais:

  • SHOW SERVICES: lista os serviços no banco de dados e esquema atual para os quais você tem permissões.

  • SHOW SERVICES IN ACCOUNT: lista os serviços em sua conta Snowflake, independentemente do banco de dados ou esquema ao qual os serviços pertencem. Isso é útil se você tiver serviços Snowflake criados em vários bancos de dados e esquemas em sua conta. Como todos os outros comandos, SHOW SERVICES IN ACCOUNTS é controlado por privilégios, retornando apenas os serviços para os quais a função que você está usando tem permissões de exibição.

  • SHOW SERVICES IN SCHEMA: lista serviços no esquema especificado.

Listagem de serviços em um pool de computação específico é um processo de duas etapas:

  1. Execute SHOW SERVICES para obter uma lista de serviços.

  2. Verifique a lista da consulta anterior (usando RESULT_SCAN) em busca de serviços no pool de computação específico.

Exemplo

No script de exemplo a seguir, o comando SHOW SERVICES primeiro lista os serviços no banco de dados e no esquema atuais que possuem uma cadeia de caracteres específica no nome do serviço.

Em seguida, a consulta SELECT filtra o conjunto de resultados para retornar apenas os serviços no pool de computação especificado. Observe que a consulta usa a função RESULT_SCAN para obter o conjunto de resultados do comando SHOW SERVICES anterior.

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

Monitoramento de um serviço

Use SYSTEM$GET_SERVICE_STATUS para obter o status detalhado do tempo de execução de um serviço. Por exemplo, você pode chamar essa função para determinar se o serviço ainda está em execução ou se houve falha ao iniciar. Se o serviço não for iniciado, a função fornecerá mais detalhes sobre a falha.

Ao chamar esta função, passe o nome do serviço.

Exemplo

CALL SYSTEM$GET_SERVICE_STATUS('echo_service');
Copy

A seguir estão exemplos de saídas:

  • Exemplo de saída de um serviço que está executando uma instância e possui um contêiner:

    [
       {
          "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 é a ID da instância de serviço à qual o contêiner pertence. Se você executar duas instâncias desse serviço, a saída incluirá dois desses objetos e fornecerá o status do contêiner para cada instância de serviço. Neste caso, as IDs das instâncias são 0 e 1.

  • Exemplo de saída de um serviço que está executando uma instância e possui três contêineres:

    [
       {
          "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

    A saída inclui informações de status para cada contêiner. Todos esses contêineres pertencem à única instância de serviço que possui a ID da instância 0.

SYSTEM$GET_SERVICE_STATUS recebe um argumento timeout_secs opcional. Se timeout_secs não for especificado ou for especificado com valor 0, a função retornará imediatamente o status atual. Se timeout_secs for especificado, o Snowflake aguardará até que o serviço atinja um estado terminal (READY ou FAILED) dentro do tempo especificado antes de retornar o status do serviço. Se o serviço não atingir o estado terminal dentro do tempo especificado, o Snowflake retornará o estado atual no fim do intervalo de tempo especificado.

O tempo limite especificado é uma aproximação baseada em quando você espera que o serviço esteja pronto e isso pode ajudar a identificar situações como quando o Snowflake está aguardando que outros serviços e trabalhos parem e liberem recursos no pool de computação especificado antes de iniciar outro serviço. A seguinte função SYSTEM$GET_SERVICE_STATUS especifica um tempo limite de 10 segundos:

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

Acesso a logs de contêiner locais

Snowflake coleta qualquer que seja o seu código nas saídas do contêiner do aplicativo para saída padrão ou erros padrão. Você deve garantir que seu código produza informações úteis para depurar um serviço.

O Snowflake oferece duas maneiras de acessar esses logs de contêiner:

  • Usando a função do sistema SYSTEM$GET_SERVICE_LOGS: dá acesso aos logs de um contêiner específico. Após a saída de um contêiner, você poderá continuar acessando os logs usando a função do sistema por um curto período. As funções do sistema são mais úteis durante o desenvolvimento e o teste, quando você está inicialmente criando um serviço ou um trabalho. Para obter mais informações, consulte SYSTEM$GET_SERVICE_LOGS.

  • Usando uma tabela de eventos: uma tabela de eventos dá acesso a logs de vários contêineres em todos os serviços. Snowflake persiste os logs na tabela de eventos para acesso posterior. As tabelas de eventos são melhor utilizadas para a análise retrospectiva de serviços e trabalhos. Para obter mais informações, consulte Como usar uma tabela de eventos.

Como usar SYSTEM$GET_SERVICE_LOGS

Forneça o nome do serviço, a ID da instância, o nome do contêiner e, opcionalmente, o número de linhas de log mais recentes a serem recuperadas. Se apenas uma instância de serviço estiver em execução, a ID da instância de serviço será 0. Por exemplo, o comando GET_SERVICE_LOGS a seguir recupera as 10 linhas finais do log de um contêiner chamado echo que pertence à instância 0 de um serviço chamado echo_service:

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

Se você não souber as informações do serviço (como a ID da instância ou o nome do contêiner), primeiro execute GET_SERVICE_STATUS para obter informações sobre as instâncias de serviço e os contêineres em execução em cada instância.

Exemplo de saída:

+--------------------------------------------------------------------------+
| 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

A saída SYSTEM$GET_SERVICE_LOGS tem as seguintes limitações:

  • Ele simplesmente mescla saída padrão e fluxos de erro padrão, o que torna impossível distinguir entre saída normal e mensagens de erro.

  • Ele relata os dados capturados para um contêiner específico em uma única instância de serviço.

  • Ele relata apenas logs de um contêiner em execução. A função não pode buscar logs de um contêiner anterior que foi reiniciado ou de um contêiner de um serviço que foi interrompido ou excluído.

  • A função retorna até 100 KB de dados.

Como usar uma tabela de eventos

O Snowflake pode capturar e registrar resultados padrão e erros padrão de seus contêineres na tabela de eventos configurada para sua conta. Para obter mais informações, consulte Visão geral do registro e do rastreamento.

Por exemplo, a consulta SELECT a seguir recupera eventos de trabalho e serviço do Snowflake registrados na última hora:

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

Snowflake recomenda incluir um carimbo de data/hora na cláusula WHERE das consultas da tabela de eventos, conforme mostrado neste exemplo. Isso é especialmente importante devido ao volume potencial de dados gerados por vários componentes do Snowflake. Ao aplicar filtros, você pode recuperar um subconjunto menor de dados, o que melhora o desempenho da consulta.

Você controla o nível de logs (todos, apenas erros ou nenhum) que deseja persistir em uma tabela de eventos usando o campo spec.logExporters no arquivo de especificação de serviço.

A tabela de eventos inclui as colunas a seguir, que fornecem informações úteis sobre os logs coletados pelo Snowflake do seu contêiner:

  • TIMESTAMP: mostra quando o Snowflake coletou o log.

  • RESOURCE_ATTRIBUTES: cada objeto nesta coluna identifica qual serviço Snowflake e contêiner no serviço geraram o log. Por exemplo, ele fornece detalhes como o nome do serviço, o nome do contêiner e o nome do pool de computação que foram especificados quando o serviço foi executado.

    {
    "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: para um serviço Snowflake, ele identifica uma origem de erro (saída padrão ou erro padrão).

    { "log.iostream": "stdout" }
    
    Copy
  • VALUE: a saída padrão e o erro padrão são divididos em linhas e cada linha gera um registro na tabela de eventos.

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

Configuração de uma tabela de eventos

Para obter mais informações, consulte Visão geral do registro e do rastreamento.

Como usar um serviço

Você pode conceder uso em serviços futuros (serviços ainda não criados) a uma função. Por exemplo:

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

Depois de criar um serviço, você pode usar qualquer um dos três métodos suportados a seguir para se comunicar com ele:

  • Função de serviço: crie uma função de serviço (UDF) associada ao serviço. Em seguida, use a função de serviço para se comunicar com um serviço a partir de uma consulta SQL. Para obter um exemplo, consulte Tutorial 1.

  • Entrada: use pontos de extremidade públicos expostos pelo serviço para acessar o serviço de fora do Snowflake. Nesse caso, Snowflake gerencia o controle de acesso. Para obter um exemplo, consulte Tutorial 1.

  • Comunicações serviço a serviço: use um nome de serviço DNS atribuído pelo Snowflake para comunicação serviço a serviço. Para obter um exemplo, consulte Tutorial 3.

As seções a seguir fornecem detalhes.

Funções de serviço: como usar um serviço de uma consulta SQL

Uma função de serviço é uma função definida pelo usuário (UDF) que você cria usando CREATE FUNCTION. No entanto, em vez de escrever o código da UDF diretamente, você associa a UDF ao seu serviço. Por exemplo, no Tutorial 1, você cria um serviço chamado echo_service que expõe um ponto de extremidade (ponto de extremidade de eco) conforme definido na especificação do serviço:

spec:

  endpoints:
  - name: echoendpoint
    port: 8080
Copy

echoendpoint é um nome de ponto de extremidade amigável que representa a porta correspondente (8080). Para se comunicar com esse ponto de extremidade de serviço, crie uma função de serviço fornecendo os parâmetros SERVICE e ENDPOINT conforme mostrado:

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

O parâmetro AS fornece o caminho HTTP para o código de serviço. Você obtém esse valor de caminho do código de serviço (por exemplo, consulte service.py no Tutorial 1).

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

Quando você invoca a função de serviço, o Snowflake direciona a solicitação para o ponto de extremidade do serviço e caminho de serviço associado.

Nota

Uma função de serviço é usada para se comunicar com um serviço e não com um trabalho. Em outras palavras, você só pode associar um serviço (não um trabalho) a uma função de serviço.

Ao executar várias instâncias do seu serviço, você pode criar uma função de serviço especificando o parâmetro opcional MAX_BATCH_ROWS para limitar o tamanho do lote, o máximo de linhas que o Snowflake envia em um lote para o serviço. Por exemplo, suponha que MAX_BATCH_ROWS seja 10 e você chame a função de serviço my_echo_udf com 100 linhas de entrada. O Snowflake particiona as linhas de entrada em lotes, com cada lote tendo no máximo 10 linhas, e envia uma série de solicitações ao serviço com o lote de linhas no corpo da solicitação. Configurar o tamanho do lote pode ajudar quando o processamento leva um tempo não trivial, e distribuir linhas por todos os servidores disponíveis também pode ajudar.

Você pode usar ALTER FUNCTION para alterar uma função de serviço. O comando ALTER FUNCTION a seguir altera o ponto de extremidade do serviço ao qual ele está associado e o tamanho do lote:

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

Formato de troca de dados

Para troca de dados entre uma função de serviço e um contêiner, o Snowflake segue o mesmo formato usado pelas funções externas (consulte Formatos de dados). Por exemplo, suponha que você tenha linhas de dados armazenadas em uma tabela (input_table):

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

Para enviar esses dados ao seu serviço, você invoca a função de serviço passando estas linhas como parâmetros:

SELECT service_func(col1, col2) FROM input_table;
Copy

Snowflake envia uma série de solicitações ao contêiner, com lotes de linhas de dados no corpo da solicitação neste formato:

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

O contêiner então retorna a saída no seguinte formato:

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

O exemplo de saída mostrado assume que o resultado é uma tabela de uma coluna com linhas («a», «b»…).

Quando diversas instâncias de serviço estão em execução, você pode criar uma função de serviço usando o parâmetro MAX_BATCH_ROWS para distribuir as linhas de entrada para processamento em todos os servidores disponíveis.

Privilégios necessários para criar e gerenciar funções de serviço

Para criar e gerenciar funções de serviço, uma função precisa dos seguintes privilégios:

  • Para criar uma função de serviço: a função atual deve ter o privilégio USAGE no serviço que está sendo referenciado.

  • Para alterar uma função de serviço: você pode alterar uma função de serviço e associá-la a outro serviço. A função atual deve ter o privilégio USAGE no novo serviço.

  • Para usar uma função de serviço: a função atual deve ter o privilégio USAGE na função de serviço e a função de proprietário da função de serviço deve ter o privilégio USAGE no serviço associado.

O script de exemplo a seguir mostra como você pode conceder permissão para usar uma função de serviço:

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

Entrada: usando um serviço de fora do Snowflake

Um serviço pode expor um ou mais pontos de extremidade como públicos para permitir que os usuários usem o serviço na web pública.

Nota

Para versão preliminar pública e privada, o ACCOUNTADMIN da sua conta Snowflake deve executar o seguinte comando:

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

Marque o ponto de extremidade como público em seu arquivo de especificação de serviço:

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

Para obter mais informações sobre especificações de serviço, consulte Referência de especificação.

Acesso e autenticação do ponto de extremidade público

O Snowpark Container Services exige que o Snowflake OAuth autentique solicitações para pontos de extremidade públicos. Por exemplo, você será solicitado a fazer login usando nome de usuário e senha. Nos bastidores, seu login gera um token OAuth do Snowflake. O token OAuth é então usado para enviar uma solicitação ao ponto de extremidade do serviço.

Nota

  • Como o Snowpark Containers usa Snowflake OAuth para ativar a entrada, a função padrão do usuário não pode ser nenhuma das funções privilegiadas, incluindo ACCOUNTADMIN, SECURITYADMIN e ORGADMIN. Para obter mais informações, consulte Bloqueio de funções específicas para o uso de integração.

  • Nem todos podem acessar os pontos de extremidade públicos expostos por um serviço. Somente usuários na mesma conta Snowflake com uma função com privilégio USAGE em um serviço podem acessar os pontos de extremidade públicos do serviço.

Você pode acessar o ponto de extremidade público usando um navegador ou programaticamente:

  • Acesso a um ponto de extremidade público usando um navegador: quando um navegador é usado para acessar um ponto de extremidade público, há um redirecionamento automático para autenticação do usuário. Você pode explorar o tutorial 1 para testar essa experiência.

  • Acesso a um ponto de extremidade público programaticamente: o código de exemplo Python a seguir usa Conector Snowflake para Python para gerar primeiro um token de sessão que representa sua identidade. O código então usa o token de sessão para fazer login no ponto de extremidade público.

    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

    No código:

    • Se você não conhecer as informações da sua conta (<nome da organização>-<nome da conta>), consulte o tutorial configuração comum.

    • Você pode obter o ingress_url do ponto de extremidade público exposto pelo serviço usando SHOW ENDPOINTS.

Cabeçalhos específicos do usuário em solicitações de entrada

Quando chega uma solicitação para um ponto de extremidade de entrada, o Snowflake passa automaticamente os seguintes cabeçalhos junto com a solicitação HTTP para o contêiner.

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

Opcionalmente, o código do contêiner pode ler esses cabeçalhos, saber quem é o chamador e aplicar personalização específica do contexto para diferentes usuários.

Comunicações serviço a serviço

Os serviços podem se comunicar entre si usando o nome DNS que o Snowflake atribui automaticamente a cada serviço. Para obter um exemplo, consulte Tutorial 3.

O formato do nome DNS é:

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

Use SHOW SERVICES (ou DESCRIBE SERVICE) para obter o nome DNS de um serviço. O nome DNS anterior é um nome completo. Os serviços criados no mesmo esquema podem se comunicar usando apenas o <nome-do-serviço>. Os serviços que estão no mesmo banco de dados, mas em esquemas diferentes, devem fornecer o nome do esquema, como <nome-do-serviço>.<nome-do-esquema>.

O Snowflake permite comunicações de rede entre serviços criados pela mesma função e bloqueia comunicações de rede entre serviços criados por funções diferentes. Se você quiser evitar que seus serviços se comuniquem entre si (por motivos como segurança), use diferentes funções do Snowflake para criar esses serviços.

Os nomes DNS têm as seguintes limitações:

  • Seu banco de dados, esquema ou nomes de serviço devem ser etiquetas DNS válidas. (consulte também https://www.ietf.org/rfc/rfc1035.html#section-2.3.1). Caso contrário, a criação de um serviço falhará.

  • Snowflake substitui um sublinhado (_) nos nomes (banco de dados, esquema e nome do serviço) por um traço (-) no nome DNS.

  • Após criar um serviço, não altere o banco de dados ou o nome do esquema, pois o Snowflake não atualizará o nome DNS do serviço.

  • Um nome DNS é apenas para comunicações internas no Snowflake entre serviços em execução na mesma conta. Não é acessível pela internet.

Atualização do código do seu serviço

Após criar um serviço, use ALTER SERVICE para atualizar o código do serviço. Primeiro, você faz upload do código do aplicativo modificado para seu repositório de imagens e, em seguida, chama ALTER SERVICE fornecendo a especificação de serviço em linha ou especificando o caminho para um arquivo de especificação no estágio Snowflake. Por exemplo:

  • Forneça a especificação em linha (a especificação parcial é mostrada).

    ALTER SERVICE echo_service
    FROM SPECIFICATION $$
    spec:
      
      
    $$;
    
    Copy
  • Forneça o caminho do arquivo do estágio do Snowflake:

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

Ao receber a solicitação, o Snowflake reimplanta o serviço usando o novo código.

ALTER SERVICE sempre usa a versão mais recente da imagem do seu repositório. Por exemplo, se você fizer upload de várias versões de uma imagem chamada “echo_service:latest” ou “echo_service:sometag”, o Snowflake usará a última versão da imagem enviada.

Você pode usar o comando DESCRIBE SERVICE para encontrar a versão da imagem que o serviço está executando. Se você for o proprietário do serviço, a saída DESCRIBE SERVICE incluirá a especificação do serviço, onde você obtém o resumo da imagem (SHA256 da imagem). Por exemplo:

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

Nota

Se você suspender e retomar um serviço, o Snowflake implantará a mesma versão de imagem, não será uma operação de atualização de serviço.

Privilégios

Privilégio

Uso

Notas

USAGE

Para se comunicar com um serviço. Necessário para criar uma função de serviço, usar pontos de extremidade públicos e conectar-se a partir de outro serviço.

MONITOR

Para monitorar um serviço e obter o status do tempo de execução.

OPERATE

Para suspender ou retomar um serviço.

OWNERSHIP

Controle total sobre o serviço. Somente uma única função pode ter este privilégio sobre um objeto específico de cada vez.

ALL [ PRIVILEGES ]

Concede todos os privilégios, exceto OWNERSHIP, no serviço.