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
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
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
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. Ognivariabile 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 datiDECIMAL
, utilizzare la sintassiRETURNS DECIMAL(
doveprecision
,scale
)precision
escale
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 clausolaUSING EXTERNAL FUNCTION
.
Esempi
Per le query ad esempio basate sul codice AthenaUDFHandler.java
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
La procedura in questa sezione illustra la scrittura e la creazione di un file Jar della funzione definita dall'utente personalizzata utilizzando Apache Maven
Procedura per creare una funzione definita dall'utente personalizzata per Athena con Maven
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.
-
Dalla radice della directory
aws-athena-query-federation
creata durante la clonazione, esegui lo script prepare_dev_env.shche prepara l'ambiente di sviluppo. -
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-udf
sostituiscilo con il nome della tua applicazione Per ulteriori informazioni, vedi Come faccio a creare il mio
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
<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.
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
, dove artifactId
-version
.jarartifactId
è 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.shathena-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
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
-
Apri la console Lambda all'indirizzo https://console.aws.amazon.com/lambda/
, scegli Crea funzione, quindi scegliere Sfoglia il repository delle app serverless -
Scegliere Private applications (Applicazioni private), trovare l'applicazione nell'elenco o cercarla usando le parole chiave e selezionarla.
-
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
\ --handlercom.mycompany.athena.udfs.MyUserDefinedFunctions
\ --timeout 900 \ --zip-file fileb://./target/my-athena-udfs-1.0-SNAPSHOT.jar