Abfragen mit benutzerdefinierten Funktionen (User Defined Functions, UDFs) - Amazon Athena

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Abfragen mit benutzerdefinierten Funktionen (User Defined Functions, UDFs)

Mit benutzerdefinierten Funktionen (UDF) in Amazon Athena können Sie eigene Funktionen zum Verarbeiten von Datensätzen oder Datensatzgruppen erstellen. Eine UDF akzeptiert Parameter, führt Arbeit aus und gibt dann ein Ergebnis zurück.

Um eine UDF in Athena zu verwenden, schreiben Sie eine USING EXTERNAL FUNCTION-Klausel vor eine SELECT-Anweisung in einer SQL-Abfrage. Die SELECT-Anweisung verweist auf die UDF und definiert die Variablen, die beim Ausführen der Abfrage an die UDF übergeben werden. Die SQL-Abfrage ruft eine Lambda-Funktion mit der Java-Laufzeitumgebung auf, wenn sie die UDF aufruft. UDFs werden innerhalb der Lambda-Funktion als Methoden in einem Java-Bereitstellungspaket definiert. Mehrere UDFs können im gleichen Java-Bereitstellungspaket für eine Lambda-Funktion definiert werden. Sie geben auch den Namen der Lambda-Funktion in der USING EXTERNAL FUNCTION-Klausel an.

Sie haben zwei Optionen zum Bereitstellen einer Lambda-Funktion für Athena-UDFs. Sie können die Funktion direkt mit Lambda bereitstellen, oder Sie können die AWS Serverless Application Repository verwenden. Um vorhandene Lambda-Funktionen für UDFs zu finden, können Sie das öffentliche AWS Serverless Application Repository oder Ihr privates Repository durchsuchen und dann auf Lambda bereitstellen. Sie können auch Java-Quellcode erstellen oder ändern, ihn in eine JAR-Datei verpacken und mit Lambda oder dem AWS Serverless Application Repository bereitstellen. Beispiele für Java-Quellcode und -Pakete für den Einstieg finden Sie unter Erstellen und Bereitstellen einer UDF mit Lambda. Weitere Informationen zu Lambda finden Sie im AWS Lambda -Entwicklerhandbuch. Weitere Informationen dazu finden Sie im AWS Serverless Application Repository Entwicklerhandbuch.AWS Serverless Application Repository

Ein Beispiel, das UDFs mit Athena verwendet, um Text zu übersetzen und zu analysieren, finden Sie im Blogartikel AWS Machine Learning Translate and analyze text using SQL functions with Amazon Athena, Amazon Translate und Amazon Comprehend, oder schauen Sie sich den an. video

Ein Beispiel für die Verwendung von UDFs zur Erweiterung von Geodatenabfragen in Amazon Athena finden Sie unter Erweitern von Geodatenabfragen in Amazon Athena mit UDFs und AWS Lambda im AWS -Big-Data-Blog.

Überlegungen und Einschränkungen

  • Integrierte Athena Funktionen – Integrierte Funktionen in Athena sind so konzipiert, dass sie sehr leistungsfähig sind. Wir empfehlen, wenn möglich integrierte Funktionen anstelle von UDFs zu verwenden. Weitere Hinweise zu integrierten Funktionen finden Sie unter Funktionen in Amazon Athena.

  • Nur skalare UDFs – Athena unterstützt nur skalare UDFs, die jeweils eine Zeile verarbeiten und einen einzelnen Spaltenwert zurückgeben. Athena übergibt einen Batch von Zeilen, möglicherweise parallel, an die UDF, wenn Lambda aufgerufen wird. Bedenken Sie beim Entwerfen von UDFs und Abfragen die möglichen Auswirkungen dieser Verarbeitung auf den Netzwerkverkehr.

  • UDF-Handler-Funktionen verwenden ein abgekürztes Format — Verwenden Sie das abgekürzte Format (kein Vollformat) für Ihre UDF-Funktionen (z. B. package.Class anstelle vonpackage.Class::method).

  • UDF-Methoden müssen in Kleinbuchstaben sein — UDF-Methoden müssen in Kleinbuchstaben vorliegen; Kamelschreibung ist nicht zulässig.

  • UDF-Methoden benötigen Parameter – UDF-Methoden müssen mindestens einen Eingabeparameter haben. Der Versuch, eine ohne Eingabeparameter definierte UDF aufzurufen, führt zu einer Laufzeitausnahme. UDFs sollen Funktionen für Datensätze ausführen, aber eine UDF ohne Argumente nimmt keine Daten auf, sodass eine Ausnahme auftritt.

  • Java-Laufzeitunterstützung – Derzeit unterstützen Athena-UDFs die Java 8 und Java 11 Laufzeiten für Lambda. Weitere Informationen finden Sie unter entwickeln von Lambda-Funktionen mit Java im AWS Lambda -Entwicklerhandbuch.

  • IAM-Berechtigungen – Um UDF-Abfrageanweisungen in Athena auszuführen und zu erstellen, muss der IAM-Prinzipal, der die Abfrage ausführt, zusätzlich zu den Athena-Funktionen auch Aktionen ausführen dürfen. Weitere Informationen finden Sie unter Beispiel für IAM-Berechtigungsrichtlinien zum Zulassen von benutzerdefinierten Amazon-Athena-Funktionen (UDF).

  • Lambda-Kontingente – Lambda Kontingente gelten für UDFs. Weitere Informationen finden Sie unter Lambda quotas (Lambda-Kontingente) im AWS Lambda -Entwicklerhandbuch.

  • Filterung auf Zeilenebene – Die Filterung auf Zeilenebene von Lake Formation wird für UDFs nicht unterstützt.

  • Ansichten – Sie können keine Ansichten mit UDFs verwenden.

  • Bekannte Probleme — Eine vollständige up-to-date Liste der bekannten Probleme finden Sie unter Einschränkungen und Probleme im Abschnitt awslabs/ von. aws-athena-query-federation GitHub

Videos

Sehen Sie sich die folgenden Videos an, um mehr über die Verwendung von UDFs in Athena zu erfahren.

Einführung von benutzerdefinierten Funktionen (User Defined Functions, UDFs) in Amazon Athena

Das folgende Video zeigt, wie Sie UDFs in Amazon Athena verwenden können, um vertrauliche Informationen zu überarbeiten.

Anmerkung

Die Syntax in diesem Video ist Vorabversion, aber die Konzepte sind die gleichen. Verwenden Sie Athena ohne die AmazonAthenaPreviewFunctionality-Arbeitsgruppe.

Video: Übersetzen, analysieren und redigieren Sie Textfelder mithilfe von SQL-Abfragen in Amazon Athena

Das folgende Video zeigt, wie Sie UDFs in Amazon Athena zusammen mit anderen AWS -Services verwenden können, um Text zu übersetzen und zu analysieren.

Anmerkung

Die Syntax in diesem Video ist Vorabversion, aber die Konzepte sind die gleichen. Die korrekte Syntax finden Sie im zugehörigen Blogbeitrag Übersetzen, redigieren und analysieren Sie Text mithilfe von SQL-Funktionen mit Amazon Athena, Amazon Translate und Amazon Comprehend im AWS -Machine-Learning-Blog.

UDF-Abfragesyntax

Die USING EXTERNAL FUNCTION-Klausel gibt eine UDF oder mehrere UDFs an, auf die durch eine nachfolgende SELECT-Anweisung in der Abfrage verwiesen werden kann. Sie benötigen den Methodennamen für die UDF und den Namen der Lambda-Funktion, die die UDF hostet. Anstelle des Lambda-Funktionsnamens können Sie den Lambda-ARN verwenden. In kontenübergreifenden Szenarien ist der Lambda-ARN erforderlich.

Syntax

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)] [...]

Parameter

USING EXTERNAL FUNCTION UDF_name(variable1 data_type[, variable2 data_type][,...])

UDF_name gibt den Namen der UDF an, der einer Java-Methode innerhalb der referenzierten Lambda-Funktion entsprechen muss. Jede variable_data_type gibt eine benannte Variable und ihren entsprechenden Datentyp an, den UDF als Eingabe akzeptiert. Der data_type muss einer der in der folgenden Tabelle aufgeführten unterstützten Athena-Datentypen sein und dem entsprechenden Java-Datentyp zugeordnet sein.

Athena-Datentyp Java-Datentyp

TIMESTAMP (ZEITSTEMPEL)

java.time. LocalDateTime (UTC)

DATUM

java.time. LocalDate (UTC)

TINYINT

java.lang.Byte

SMALLINT

java.lang.Short

REAL

java.lang.Float

DOUBLE

java.lang.Double

DECIMALE (siehe RETURNS-Hinweis)

java.math. 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 gibt den SQL-Datentyp an, den die UDF als Ausgabe zurückgibt. Athena Datentypen, die in der obigen Tabelle aufgeführt sind, werden unterstützt. Verwenden Sie für den Datentyp DECIMAL die Syntax RETURNS DECIMAL(precision, scale), bei der Präzision und Skalierung Ganzzahlen sind.

LAMBDA 'lambda_funktion'

my_lambda_function gibt den Namen der Lambda-Funktion an, die bei Ausführung der UDF aufgerufen werden soll.

SELECT [...] UDF_name(expression) [...]

Die SELECT-Abfrage, die Werte an die UDF übergibt und ein Ergebnis zurückgibt. UDF_name gibt die zu verwendende UDF an, gefolgt von einem Ausdruck, der ausgewertet wird, um Werte zu übergeben. Werte, die übergeben und zurückgegeben werden, müssen mit den entsprechenden Datentypen übereinstimmen, die für die UDF in der USING EXTERNAL FUNCTION-Klausel angegeben sind.

Beispiele

Beispiele für Abfragen, die auf dem Code AthenaUDFHandler.java basieren GitHub, finden Sie auf der GitHub Amazon Athena UDF-Connector-Seite.

Erstellen und Bereitstellen einer UDF mit Lambda

Um eine eigene UDF zu erstellen, erstellen Sie eine neue Java-Klasse, indem Sie die UserDefinedFunctionHandler-Klasse erweitern. Der Quellcode für die Datei UserDefinedFunctionHandler.java im SDK ist im athena-federation-sdk Repository aws-athena-query-federation awslabs// verfügbar GitHub , zusammen mit Beispiel-UDF-Implementierungen, die Sie untersuchen und ändern können, um eine benutzerdefinierte UDF zu erstellen.

Die Schritte in diesem Abschnitt veranschaulichen das Schreiben und Erstellen einer benutzerdefinierten UDF-JAR-Datei mit Apache Maven über die Befehlszeile und eine Bereitstellung.

Klonen des SDK und Vorbereitung der Entwicklungsumgebung

Bevor Sie beginnen, stellen Sie mithilfe von sudo yum install git -y sicher, dass git auf Ihrem System installiert ist.

AWS Um das Query Federation SDK zu installieren
  • Geben Sie Folgendes in der Befehlszeile ein, um das SDK-Repository zu klonen. Dieses Repository enthält den SDK, Beispiele und eine Suite von Datenquellen-Connectors. Weitere Hinweise zu Datenquellen-Connectors finden Sie unter Nutzung von Amazon-Athena-Verbundabfrage.

    git clone https://github.com/awslabs/aws-athena-query-federation.git
So installieren Sie die Voraussetzungen für dieses Verfahren:

Wenn Sie auf einem Entwicklungscomputer arbeiten, auf dem Apache Maven AWS CLI, The und das AWS Serverless Application Model Build-Tool bereits installiert sind, können Sie diesen Schritt überspringen.

  1. Führen Sie im aws-athena-query-federation-Stammverzeichnis des Verzeichnisses, das Sie beim Klonen erstellt haben, das Skript prepare_dev_env.sh aus, das die Entwicklungsumgebung vorbereitet.

  2. Aktualisieren Sie die Shell, um neue Variablen zu erzeugen, die durch den Installationsprozess erstellt wurden, oder starten Sie die Terminalsitzung neu.

    source ~/.profile
    Wichtig

    Wenn Sie diesen Schritt überspringen, erhalten Sie später die Fehlermeldung, dass das AWS CLI oder AWS SAM Build-Tool Ihre Lambda-Funktion nicht veröffentlichen kann.

Erstellen Ihres Maven-Projekts

Führen Sie den folgenden Befehl aus, um Ihr Maven-Projekt zu erstellen. Ersetzen Sie groupId durch die eindeutige ID Ihrer Organisation und my-athena-udfersetzen Sie sie durch den Namen Ihrer Anwendung. Weitere Informationen finden Sie unter Wie erstelle ich mein erstes Maven-Projekt? in der Apache Maven-Dokumentation.

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

Hinzufügen von Abhängigkeiten und Plugins zu Ihrem Maven-Projekt

Fügen Sie die folgenden Konfigurationen zu Ihrer Maven-pom.xml-Projektdatei hinzu. Ein Beispiel finden Sie in GitHub der Datei pom.xml unter.

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

Schreiben von Java-Code für die UDFs

Erstellen Sie eine neue Klasse, indem Sie UserDefinedFunctionHandler.java erweitern. Schreiben Sie Ihre UDFs in der Klasse.

Im folgenden Beispiel werden zwei Java-Methoden für UDFs, compress() und decompress(), innerhalb der Klasse MyUserDefinedFunctions erstellt.

*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); } }

Erstellen der JAR-Datei

Führen Sie mvn clean install aus um Ihr Projekt zu erstellen. Nachdem es erfolgreich erstellt wurde, wird eine JAR-Datei im target-Ordner Ihres Projekts mit dem Namen artifactId-version.jar erstellt, wobei artifactId der Name ist, den Sie im Maven-Projekt angegeben haben, z. B. my-athena-udfs.

Stellen Sie das JAR bereit für AWS Lambda

Sie haben zwei Möglichkeiten, Ihren Code in Lambda bereitzustellen:

  • Bereitstellen mit AWS Serverless Application Repository (empfohlen)

  • Erstellen einer Lambda-Funktion aus der JAR-Datei

Option 1: Bereitstellung auf AWS Serverless Application Repository

Wenn Sie Ihre JAR-Datei auf dem bereitstellen AWS Serverless Application Repository, erstellen Sie eine AWS SAM YAML-Vorlagendatei, die die Architektur Ihrer Anwendung darstellt. Anschließend geben Sie diese YAML-Datei und einen Amazon-S3-Bucket an, in den Artefakte für Ihre Anwendung hochgeladen und für AWS Serverless Application Repository verfügbar gemacht werden. Im folgenden Verfahren wird das Skript publish.sh verwendet, das sich im athena-query-federation/tools-Verzeichnis des Athena-Query-Federation-SDKs befindet, das Sie zuvor geklont haben.

Weitere Informationen und Anforderungen finden Sie unter Veröffentlichen von Anwendungen im AWS Serverless Application Repository Entwicklerhandbuch, AWS SAM Vorlagenkonzepte im AWS Serverless Application Model Entwicklerhandbuch und Veröffentlichen serverloser Anwendungen mit der AWS SAM CLI.

Das folgende Beispiel veranschaulicht Parameter in einer YAML-Datei. Fügen Sie Ihrer YAML-Datei ähnliche Parameter hinzu und speichern Sie diese in Ihrem Projektverzeichnis. Ein vollständiges Beispiel finden Sie unter athena-udf.yaml. 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

Kopieren Sie das publish.sh-Skript in das Projektverzeichnis, in dem Sie Ihre YAML-Datei gespeichert haben, und führen Sie den folgenden Befehl aus:

./publish.sh MyS3Location MyYamlFile

Zum Beispiel, wenn Ihr Bucket-Speicherort s3://DOC-EXAMPLE-BUCKET/mysarapps/athenaudf ist und Ihre YAML-Datei unter my-athena-udfs.yaml gespeichert wurde:

./publish.sh DOC-EXAMPLE-BUCKET/mysarapps/athenaudf my-athena-udfs
Eine Lambda-Funktion erstellen
  1. Öffnen Sie die Lambda-Konsole unter https://console.aws.amazon.com/lambda/, wählen Sie Funktion erstellen und danach Serverless-App-Repository durchsuchen aus

  2. Wählen Sie Private applications (Private Anwendungen) aus, suchen Sie Ihre Anwendung in der Liste oder mit Schlüsselwörtern und wählen Sie sie aus.

  3. Überprüfen und geben Sie Anwendungsdetails an, und wählen Sie dann Deploy (Bereitstellen).

    Sie können nun die Methodennamen verwenden, die in Ihrer Lambda-Funktion-JAR-Datei als UDFs in Athena definiert sind.

Option 2: Direktes Erstellen einer Lambda-Funktion

Sie können eine Lambda-Funktion auch direkt über die Konsole oder AWS CLI erstellen. Das folgende Beispiel veranschaulicht die Verwendung des Lambda-CLI-Befehls create-function.

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