Esecuzione di query con funzioni definite dall'utente - Amazon Athena

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Esecuzione di query con funzioni definite dall'utente

Funzioni definite dall'utente (FDU) in Amazon Athena consentono di creare funzioni personalizzate per elaborare registri o gruppi di registri. Una funzione definita dall'utente accetta parametri, esegue il lavoro e quindi restituisce un risultato.

Per utilizzare una funzione definita dall'utente in Athena, scrivi una clausola USING EXTERNAL FUNCTION prima di un'istruzione SELECT in una query SQL. L'istruzione SELECT fa riferimento alla funzione definita dall'utente e definisce le variabili che vengono passate alla funzione definita dall'utente quando viene eseguita la query. La query SQL richiama una funzione Lambda utilizzando il runtime Java quando chiama la funzione definita dall'utente. Le funzioni definite dall'utente sono definite all'interno della funzione Lambda come metodi in un pacchetto di distribuzione Java. Più funzioni definite dall'utente possono essere definite nello stesso pacchetto di distribuzione Java per una funzione Lambda. Puoi anche specificare il nome della funzione Lambda nella clausola USING EXTERNAL FUNCTION.

Sono disponibili due opzioni per la distribuzione di una funzione Lambda per le funzioni Athena definite dall'utente. Puoi distribuire la funzione direttamente utilizzando Lambda oppure puoi utilizzare AWS Serverless Application Repository. Per trovare le funzioni Lambda esistenti per le UDF, puoi cercare nell'archivio pubblico AWS Serverless Application Repository o privato e quindi distribuirle su Lambda. Puoi inoltre creare o modificare il codice sorgente Java, creare un pacchetto in un file JAR e distribuirlo utilizzando Lambda o il AWS Serverless Application Repository. Per esempi di codice origine e pacchetti Java con cui iniziare, consulta Creazione e distribuzione di una funzione definita dall'utente utilizzando Lambda. Per ulteriori informazioni su Lambda, consulta la Guida per gli sviluppatori di AWS Lambda. Per ulteriori informazioni in merito, consulta la Guida per gli AWS Serverless Application Repository sviluppatori.AWS Serverless Application Repository

Per un esempio che utilizza UDF con Athena per tradurre e analizzare il testo, consulta AWS l'articolo del Machine Learning Blog Tradurre e analizzare il testo utilizzando le funzioni SQL con Amazon Athena, Amazon Translate e Amazon Comprehend oppure guarda il. video

Per un esempio di utilizzo delle UDF per l'estensione delle query geospaziali in Amazon Athena, consulta Estensione delle query geospaziali in Amazon Athena con UDF e AWS Lambda nel Blog sui Big Data di AWS .

Considerazioni e limitazioni

  • Funzioni Athena integrate: le funzioni integrate in Athena sono progettate per essere altamente performanti. Ti consigliamo di utilizzare funzioni incorporate anziché funzioni definite dall'utente quando possibile. Per ulteriori informazioni sulle funzioni incorporate, consulta Funzioni in Amazon Athena.

  • Solo UDF scalari — Athena supporta solo le UDF scalari, che elaborano una riga alla volta e restituiscono un singolo valore di colonna. Athena passa un batch di righe, potenzialmente in parallelo, all'UDF ogni volta che invoca Lambda. Durante la progettazione di funzioni definite dall'utente e query, sii consapevole del potenziale impatto sul traffico di rete di questo processo.

  • Le funzioni del gestore UDF utilizzano un formato abbreviato: usa il formato abbreviato (non il formato completo) per le funzioni UDF (ad esempio, package.Class anziché package.Class::method).

  • I metodi UDF devono essere scritti in lettere minuscole: i metodi UDF devono essere scritti in lettere minuscole; la notazione a cammello non è consentita.

  • I metodi UDF richiedono parametri: i metodi UDF devono avere almeno un parametro di input. Il tentativo di richiamare un file UDF definito senza parametri di input comporta un'eccezione di runtime. Le UDF sono concepite per eseguire funzioni su record di dati, ma una UDF senza argomenti non accetta dati, quindi si verifica un'eccezione.

  • Supporto per Java Runtime— Attualmente, le UDF Athena supportano Java Runtime 8 e 11 per Lambda. Per ulteriori informazioni, consulta Creazione di funzioni Lambda con Java nella Guida per gli sviluppatori di AWS Lambda .

  • Autorizzazioni IAM — Per eseguire e creare istruzioni di query UDF in Athena, l'entità principale IAM che esegue la query deve essere autorizzata a eseguire operazioni in aggiunta alle funzioni Athena. Per ulteriori informazioni, consulta Esempio di policy di autorizzazione IAM per consentire le funzioni definite dall'utente (UDF) di Amazon Athena.

  • Quote di Lambda — Le quote lambda si applicano alle UDF. Per ulteriori informazioni, consulta la sezione Quote Lambda nella Guida per gli sviluppatori di AWS Lambda .

  • Filtraggio a livello di riga: il filtro a livello di riga di Lake Formation non è supportato per le UDF.

  • Visualizzazioni: non è possibile utilizzare le visualizzazioni con UDF.

  • Problemi noti: per l' up-to-dateelenco più completo dei problemi noti, consulta Limitazioni e problemi nella sezione awslabs/ di. aws-athena-query-federation GitHub

Video

Guarda i video seguenti per sapere di più sull'utilizzo delle UDF in Athena.

Video: Introduzione delle funzioni definite dall'utente (UDF) in Amazon Athena

Il video seguente mostra come utilizzare le UDF in Amazon Athena per redigere informazioni sensibili.

Nota

La sintassi in questo video è precedente al rilascio, ma i concetti sono gli stessi. Utilizza Athena senza il gruppo di lavoro AmazonAthenaPreviewFunctionality.

Video: Tradurre, analizzare e redigere campi di testo utilizzando query SQL in Amazon Athena

Il seguente video mostra come utilizzare le UDF in Amazon Athena insieme ad altri Servizi AWS per tradurre e analizzare il testo.

Nota

La sintassi in questo video è precedente al rilascio, ma i concetti sono gli stessi. Per la sintassi corretta, vedere il post del blog correlato Tradurre, redigere e analizzare il testo utilizzando le funzioni SQL con Amazon Athena, Amazon Translate e Amazon Comprehend sulblog AWS Machine Learning.

Sintassi query funzione definita dall'utente

La clausola USING EXTERNAL FUNCTION specifica una o più funzioni definite dall'utente a cui è possibile fare riferimento da un'istruzione SELECT successiva nella query. È necessario il nome del metodo per la funzione definita dall'utente e il nome della funzione Lambda che ospita la funzione definita dall'utente. Al posto del nome della funzione Lambda, puoi utilizzare l'ARN Lambda. Negli scenari con più account, è necessario l'utilizzo dell'ARN Lambda.

Riepilogo

USING EXTERNAL FUNCTION UDF_name(variable1 data_type[, variable2 data_type][,...]) RETURNS data_type LAMBDA 'lambda_function_name_or_ARN' [, EXTERNAL FUNCTION UDF_name2(variable1 data_type[, variable2 data_type][,...]) RETURNS data_type LAMBDA 'lambda_function_name_or_ARN'[,...]] SELECT [...] UDF_name(expression) [, UDF_name2(expression)] [...]

Parametri

UTILIZZO DELLA FUNZIONE ESTERNA UDF_name(variable1 data_type[, variable2 data_type][,...])

UDF_name specifica il nome della funzione definita dall'utente, che deve corrispondere a un metodo Java all'interno della funzione Lambda di riferimento. Ogni variabile data_type specifica una variabile denominata e il tipo di dati corrispondente, che l'UDF accetta come input. data_type deve essere uno dei tipi di dati Athena supportati nella seguente tabella e mappato al tipo di dati Java corrispondente.

Tipo di dati Athena Tipo di dati Java

TIMESTAMP

java.time. LocalDateTime (UTC)

DATE

java.time. LocalDate (UTC)

TINYINT

java.lang.Byte

SMALLINT

java.lang.Short

REAL

java.lang.Float

DOUBLE

java.lang.Double

DECIMAL (vd. nota RETURNS)

java.matematica. BigDecimal

BIGINT

java.lang.Long

INTEGER

java.lang.Int

VARCHAR

java.lang.String

VARBINARY

byte[]

BOOLEAN

java.lang.Boolean

ARRAY

java.util.List

ROW

java.util.Map<String, Object>

RETURNS data_type

data_type specifica il tipo di dati SQL restituito dall'UDF come output. I tipi di dati Athena elencati nella tabella precedente sono supportati. Per il tipo di dati DECIMAL, utilizzare la sintassi RETURNS DECIMAL(precision, scale) dove precision e scale sono numeri interi.

LAMBDA 'lambda_function'

lambda_function specifica il nome della funzione da richiamare durante l'esecuzione della funzione Lambda definita dall'utente.

SELEZIONA [...] UDF_name(expression) [...]

La query SELECT che trasmette i valori all'UDF e restituisce un risultato. UDF_name specifica l'UDF da utilizzare, seguito da un'espressione che viene valutata per trasmettere i valori. I valori passati e restituiti devono corrispondere ai tipi di dati corrispondenti specificati per la funzione definita dall'utente nella clausola USING EXTERNAL FUNCTION.

Esempi

Per le query ad esempio basate sul codice AthenaUDFHandler.java su GitHub, consulta la pagina del connettore GitHub Amazon Athena UDF.

Creazione e distribuzione di una funzione definita dall'utente utilizzando Lambda

Per creare una funzione definita dall'utente personalizzata, crea una nuova classe Java estendendo la classe UserDefinedFunctionHandler. Il codice sorgente del UserDefinedFunctionHandlerfile.java nell'SDK è disponibile nel athena-federation-sdk repository awslabs/aws-athena-query-federation/, insieme GitHub a esempi di implementazioni UDF che puoi esaminare e modificare per creare una UDF personalizzata.

La procedura in questa sezione illustra la scrittura e la creazione di un file Jar della funzione definita dall'utente personalizzata utilizzando Apache Maven dalla riga di comando e una distribuzione.

Duplicazione dell'SDK e preparazione dell'ambiente di sviluppo

Prima di iniziare, assicurati che git sia installato sul tuo sistema utilizzando sudo yum install git -y.

AWS Per installare l'SDK di federazione delle query
  • Immettere quanto segue nella riga di comando per clonare il repository SDK. Questo repository include l'SDK, esempi e una suite di connettori di origine dati. Per ulteriori informazioni sui connettori di origine dati, consulta Utilizzo di Amazon Athena Federated Query.

    git clone https://github.com/awslabs/aws-athena-query-federation.git
Per installare i prerequisiti per questa procedura

Se state lavorando su una macchina di sviluppo su cui sono già installati Apache Maven AWS CLI, lo strumento di AWS Serverless Application Model compilazione e sviluppo, potete saltare questo passaggio.

  1. Dalla radice della directory aws-athena-query-federation creata durante la clonazione, esegui lo script prepare_dev_env.sh che prepara l'ambiente di sviluppo.

  2. Aggiorna la shell per generare nuove variabili create dal processo di installazione o riavvia la sessione del terminale.

    source ~/.profile
    Importante

    Se salti questo passaggio, in seguito riceverai degli errori relativi all'impossibilità dello strumento AWS CLI o AWS SAM build di pubblicare la tua funzione Lambda.

Creazione del progetto Maven

Esegui il comando seguente per creare il progetto Maven. Sostituisci GroupiD con l'ID univoco della tua organizzazione e my-athena-udfsostituiscilo con il nome della tua applicazione Per ulteriori informazioni, vedi Come faccio a creare il mio primo progetto Maven? nella documentazione di Apache Maven.

mvn -B archetype:generate \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DgroupId=groupId \ -DartifactId=my-athena-udfs

Aggiunta di dipendenze e plugin al progetto Maven

Aggiungi le seguenti configurazioni al file pom.xml del progetto Maven. Per un esempio, consultate il file pom.xml in. GitHub

<properties> <aws-athena-federation-sdk.version>2022.47.1</aws-athena-federation-sdk.version> </properties> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-athena-federation-sdk</artifactId> <version>${aws-athena-federation-sdk.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.1</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build>

Scrittura di codice Java per le funzioni definite dall'utente

Crea una nuova classe estendendo UserDefinedFunctionHandler.java. Scrivi le funzioni definite dall'utente all'interno della classe.

Nell'esempio seguente, due metodi Java per funzioni definite dall'utente, compress() e decompress(), vengono creati all'interno della classe MyUserDefinedFunctions.

*package *com.mycompany.athena.udfs; public class MyUserDefinedFunctions extends UserDefinedFunctionHandler { private static final String SOURCE_TYPE = "MyCompany"; public MyUserDefinedFunctions() { super(SOURCE_TYPE); } /** * Compresses a valid UTF-8 String using the zlib compression library. * Encodes bytes with Base64 encoding scheme. * * @param input the String to be compressed * @return the compressed String */ public String compress(String input) { byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8); // create compressor Deflater compressor = new Deflater(); compressor.setInput(inputBytes); compressor.finish(); // compress bytes to output stream byte[] buffer = new byte[4096]; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(inputBytes.length); while (!compressor.finished()) { int bytes = compressor.deflate(buffer); byteArrayOutputStream.write(buffer, 0, bytes); } try { byteArrayOutputStream.close(); } catch (IOException e) { throw new RuntimeException("Failed to close ByteArrayOutputStream", e); } // return encoded string byte[] compressedBytes = byteArrayOutputStream.toByteArray(); return Base64.getEncoder().encodeToString(compressedBytes); } /** * Decompresses a valid String that has been compressed using the zlib compression library. * Decodes bytes with Base64 decoding scheme. * * @param input the String to be decompressed * @return the decompressed String */ public String decompress(String input) { byte[] inputBytes = Base64.getDecoder().decode((input)); // create decompressor Inflater decompressor = new Inflater(); decompressor.setInput(inputBytes, 0, inputBytes.length); // decompress bytes to output stream byte[] buffer = new byte[4096]; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(inputBytes.length); try { while (!decompressor.finished()) { int bytes = decompressor.inflate(buffer); if (bytes == 0 && decompressor.needsInput()) { throw new DataFormatException("Input is truncated"); } byteArrayOutputStream.write(buffer, 0, bytes); } } catch (DataFormatException e) { throw new RuntimeException("Failed to decompress string", e); } try { byteArrayOutputStream.close(); } catch (IOException e) { throw new RuntimeException("Failed to close ByteArrayOutputStream", e); } // return decoded string byte[] decompressedBytes = byteArrayOutputStream.toByteArray(); return new String(decompressedBytes, StandardCharsets.UTF_8); } }

Compilazione del file JAR

Esegui mvn clean install per compilare il progetto. Al termine della compilazione, viene creato un file JAR nella cartella target del progetto denominato artifactId-version.jar, dove artifactId è il nome fornito nel progetto Maven, ad esempio my-athena-udfs.

Distribuisci il JAR su AWS Lambda

Hai a disposizione due opzioni per distribuire il codice in Lambda:

  • Distribuisci utilizzando AWS Serverless Application Repository (consigliato)

  • Creazione di una funzione Lambda dal file JAR

Opzione 1: distribuzione su AWS Serverless Application Repository

Quando si distribuisce il file JAR su AWS Serverless Application Repository, si crea un file YAML AWS SAM modello che rappresenta l'architettura dell'applicazione. Quindi devi specificare questo file YAML e un bucket Amazon S3 in cui gli artefatti dell'applicazione vengono caricati e resi disponibili ad AWS Serverless Application Repository. Nella procedura riportata di seguito viene utilizzato lo script publish.sh che si trova nella directory athena-query-federation/tools dell'SDK di Athena Query Federation clonato in precedenza.

Per ulteriori informazioni e requisiti, consulta Pubblicazione di applicazioni nella AWS Serverless Application Repository Developer Guide, concetti di AWS SAM template nella AWS Serverless Application Model Developer Guide e Pubblicazione di applicazioni serverless utilizzando la AWS SAM CLI.

Nell'esempio seguente vengono illustrati i parametri in un file YAML. Aggiungi parametri simili al file YAML e salvalo nella directory del progetto. Vedi athena-udf.yaml in per un esempio completo. GitHub

Transform: 'AWS::Serverless-2016-10-31' Metadata: 'AWS::ServerlessRepo::Application': Name: MyApplicationName Description: 'The description I write for my application' Author: 'Author Name' Labels: - athena-federation SemanticVersion: 1.0.0 Parameters: LambdaFunctionName: Description: 'The name of the Lambda function that will contain your UDFs.' Type: String LambdaTimeout: Description: 'Maximum Lambda invocation runtime in seconds. (min 1 - 900 max)' Default: 900 Type: Number LambdaMemory: Description: 'Lambda memory in MB (min 128 - 3008 max).' Default: 3008 Type: Number Resources: ConnectorConfig: Type: 'AWS::Serverless::Function' Properties: FunctionName: !Ref LambdaFunctionName Handler: "full.path.to.your.handler. For example, com.amazonaws.athena.connectors.udfs.MyUDFHandler" CodeUri: "Relative path to your JAR file. For example, ./target/athena-udfs-1.0.jar" Description: "My description of the UDFs that this Lambda function enables." Runtime: java8 Timeout: !Ref LambdaTimeout MemorySize: !Ref LambdaMemory

Copia lo script publish.sh nella directory del progetto in cui è stato salvato il file YAML ed esegui il comando seguente:

./publish.sh MyS3Location MyYamlFile

Ad esempio, se la posizione del bucket è s3://DOC-EXAMPLE-BUCKET/mysarapps/athenaudf e il file YAML è stato salvato come my-athena-udfs.yaml:

./publish.sh DOC-EXAMPLE-BUCKET/mysarapps/athenaudf my-athena-udfs
Per creare una funzione Lambda
  1. Apri la console Lambda all'indirizzo https://console.aws.amazon.com/lambda/, scegli Crea funzione, quindi scegliere Sfoglia il repository delle app serverless

  2. Scegliere Private applications (Applicazioni private), trovare l'applicazione nell'elenco o cercarla usando le parole chiave e selezionarla.

  3. Rivedere e fornire i dettagli dell'applicazione, quindi scegliere Deploy (Distribuisci).

    È ora possibile utilizzare i nomi dei metodi definiti nel file JAR della funzione Lambda come funzioni definite dall'utente in Athena.

Opzione 2: Creare direttamente una funzione Lambda

Puoi anche creare una funzione Lambda direttamente utilizzando la console o. AWS CLI L'esempio seguente illustra l'utilizzo del comando CLI della create-function Lambda.

aws lambda create-function \ --function-name MyLambdaFunctionName \ --runtime java8 \ --role arn:aws:iam::1234567890123:role/my_lambda_role \ --handler com.mycompany.athena.udfs.MyUserDefinedFunctions \ --timeout 900 \ --zip-file fileb://./target/my-athena-udfs-1.0-SNAPSHOT.jar