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.
Empfehlungen Amazon QLDB Amazon-Fahrer
Wichtig
Hinweis zum Ende des Supports: Bestandskunden können Amazon QLDB bis zum Ende des Supports am 31.07.2025 nutzen. Weitere Informationen finden Sie unter Migrieren eines Amazon QLDB Ledgers zu Amazon Aurora SQL Postgre
In diesem Abschnitt werden bewährte Methoden für die Konfiguration und Verwendung des QLDB Amazon-Treibers für jede unterstützte Sprache beschrieben. Bei den Codebeispielen handelt es sich um Java-Beispiele.
Diese Empfehlungen gelten für die meisten typischen Anwendungsfälle, aber nicht für alle. Verwenden Sie die folgenden Empfehlungen, wenn Sie glauben, dass sie für Ihre Anwendung geeignet sind.
Themen
Das QldbDriver Objekt konfigurieren
Das QldbDriver
Objekt verwaltet Verbindungen zu Ihrem Ledger, indem es einen Pool von Sitzungen verwaltet, die transaktionsübergreifend wiederverwendet werden. Eine Sitzung stellt eine einzelne Verbindung zum Ledger dar. QLDBunterstützt eine aktiv laufende Transaktion pro Sitzung.
Wichtig
Bei älteren Treiberversionen befindet sich die Session-Pooling-Funktionalität immer noch im PooledQldbDriver
Objekt stattQldbDriver
. Wenn Sie eine der folgenden Versionen verwenden, ersetzen Sie alle Erwähnungen von QldbDriver
durch PooledQldbDriver
für den Rest dieses Themas.
Treiber | Version |
---|---|
Java | 1.1.0 oder früher |
.NET | 0.1.0-beta |
Node.js | 1.0.0-rc.1 oder früher |
Python | 2.0.2 oder früher |
Das PooledQldbDriver
Objekt ist in der neuesten Version der Treiber veraltet. Wir empfehlen, auf die neueste Version zu aktualisieren und alle Instanzen von PooledQldbDriver
to zu zu zu konvertieren. QldbDriver
QldbDriver Als globales Objekt konfigurieren
Um die Verwendung von Treibern und Sitzungen zu optimieren, stellen Sie sicher, dass in Ihrer Anwendungsinstanz nur eine globale Instanz des Treibers vorhanden ist. In Java können Sie beispielsweise Abhängigkeits-Injection-Frameworks wie SpringQldbDriver
als Singleton konfigurieren.
@Singleton public QldbDriver qldbDriver (AWSCredentialsProvider credentialsProvider, @Named(LEDGER_NAME_CONFIG_PARAM) String ledgerName) { QldbSessionClientBuilder builder = QldbSessionClient.builder(); if (null != credentialsProvider) { builder.credentialsProvider(credentialsProvider); } return QldbDriver.builder() .ledger(ledgerName) .transactionRetryPolicy(RetryPolicy .builder() .maxRetries(3) .build()) .sessionClientBuilder(builder) .build(); }
Konfigurieren der Wiederholungsversuche
Der Treiber versucht automatisch, Transaktionen zu wiederholen, wenn häufig auftretende vorübergehende Ausnahmen (wie SocketTimeoutException
oderNoHttpResponseException
) auftreten. Um die maximale Anzahl von Wiederholungsversuchen festzulegen, können Sie den maxRetries
Parameter des transactionRetryPolicy
Konfigurationsobjekts verwenden, wenn Sie eine Instanz von erstellen. QldbDriver
(Verwenden Sie für ältere Treiberversionen, wie im vorherigen Abschnitt aufgeführt, den retryLimit
Parameter vonPooledQldbDriver
.)
Der Standardwert von maxRetries
ist 4
.
Bei clientseitigen Fehlern wie InvalidParameterException
sind keine wiederholten Versuche möglich. Wenn sie auftreten, wird die Transaktion abgebrochen, die Sitzung wird an den Pool zurückgegeben, und eine Ausnahme wird für den Client des Treibers ausgelöst.
Konfigurieren Sie die maximale Anzahl gleichzeitiger Sitzungen und Transaktionen
Die maximale Anzahl von Ledger-Sitzungen, die von einer Instanz von QldbDriver
zur Ausführung von Transaktionen verwendet werden, wird durch ihren maxConcurrentTransactions
Parameter definiert. (Für ältere Treiberversionen, wie im vorherigen Abschnitt aufgeführt, wird dies durch den poolLimit
Parameter von definiertPooledQldbDriver
.)
Dieser Grenzwert muss größer als Null und kleiner oder gleich der maximalen Anzahl offener HTTP Verbindungen sein, die der Sitzungsclient gemäß der spezifischen Definition zulässt AWS SDK. In Java ist beispielsweise die maximale Anzahl von Verbindungen im ClientConfigurationObjekt festgelegt.
Der Standardwert von maxConcurrentTransactions
ist die maximale Verbindungseinstellung Ihres AWS SDK.
Wenn Sie QldbDriver
in der Anwendung konfigurieren, beachten Sie die folgenden Aspekte hinsichtlich der Skalierung:
-
Ihr Pool sollte immer mindestens so viele Sitzungen haben wie die Anzahl der gleichzeitig laufenden Transaktionen, die Sie planen.
-
In einem Multithread-Modell, bei dem ein Supervisor-Thread an Worker-Threads delegiert, sollte der Treiber mindestens so viele Sitzungen haben wie die Anzahl der Worker-Threads. Andernfalls warten Threads bei Spitzenlast nacheinander auf eine verfügbare Sitzung.
-
Das Service-Limit für gleichzeitige aktive Sitzungen pro Ledger ist in Kontingente und Limits bei Amazon QLDB definiert. Stellen Sie sicher, dass Sie nicht mehr als dieses Limit an gleichzeitigen Sitzungen für einen einzelnen Ledger über alle Clients konfigurieren.
Wiederholter Versuch bei Ausnahmen
Beachten Sie beim erneuten Versuch mit Ausnahmen, die in auftretenQLDB, die folgenden Empfehlungen.
Versuchen Sie es erneut mit OccConflictException
Konfliktausnahmen bei Optimistic Concurrency Control (OCC) treten auf, wenn sich die Daten, auf die die Transaktion zugreift, seit Beginn der Transaktion geändert haben. QLDBlöst diese Ausnahme aus, während versucht wird, die Transaktion zu bestätigen. Der Treiber wiederholt die Transaktion bis zu so oft, wie konfiguriert maxRetries
ist.
Weitere Informationen OCC und bewährte Methoden zur Verwendung von Indizes zur Begrenzung von OCC Konflikten finden Sie unter. QLDBAmazon-Parallelitätsmodell
Wiederholter Versuch bei anderen Ausnahmen außerhalb von QldbDriver
Um eine Transaktion außerhalb des Treibers erneut zu versuchen, wenn während der Laufzeit benutzerdefinierte, anwendungsdefinierte Ausnahmen ausgelöst werden, müssen Sie die Transaktion umschließen. In Java zeigt der folgende Code beispielsweise, wie Sie die Reslience4J-Bibliothek
private final RetryConfig retryConfig = RetryConfig.custom() .maxAttempts(MAX_RETRIES) .intervalFunction(IntervalFunction.ofExponentialRandomBackoff()) // Retry this exception .retryExceptions(InvalidSessionException.class, MyRetryableException.class) // But fail for any other type of exception extended from RuntimeException .ignoreExceptions(RuntimeException.class) .build(); // Method callable by a client public void myTransactionWithRetries(Params params) { Retry retry = Retry.of("registerDriver", retryConfig); Function<Params, Void> transactionFunction = Retry.decorateFunction( retry, parameters -> transactionNoReturn(params)); transactionFunction.apply(params); } private Void transactionNoReturn(Params params) { try (driver.execute(txn -> { // Transaction code }); } return null; }
Anmerkung
Der Wiederholungsversuch einer Transaktion außerhalb des Treibers hat einen MultiplikatoreffektQLDB. Wenn beispielsweise die Konfiguration so konfiguriert QldbDriver
ist, dass sie dreimal wiederholt wird, und die benutzerdefinierte Wiederholungslogik ebenfalls dreimal versucht, kann dieselbe Transaktion bis zu neun Mal wiederholt werden.
Dadurch werden Transaktionen idempotent
Als bewährte Methode sollten Sie Ihre Schreibtransaktionen idempotent machen, um unerwartete Nebenwirkungen im Falle von Wiederholungen zu vermeiden. Eine Transaktion ist idempotent, wenn sie mehrfach ausgeführt werden kann und jedes Mal zu identischen Ergebnissen führt.
Weitere Informationen hierzu finden Sie unter QLDBAmazon-Parallelitätsmodell.
Optimierung der Leistung
Um die Leistung zu optimieren, wenn Sie Transaktionen mit dem Treiber ausführen, sollten Sie die folgenden Überlegungen berücksichtigen:
-
Der
execute
Vorgang führt immer mindestens dreiSendCommand
API Aufrufe durchQLDB, einschließlich der folgenden Befehle:-
StartTransaction
-
ExecuteStatement
Dieser Befehl wird für jede PartiQL-Anweisung aufgerufen, die Sie in dem
execute
Block ausführen. -
CommitTransaction
Berücksichtigen Sie bei der Berechnung der Gesamtauslastung Ihrer Anwendung die Gesamtzahl der API Aufrufe.
-
-
Grundsätzlich empfehlen wir, mit einem Single-Thread-Writer zu beginnen und Transaktionen zu optimieren, indem mehrere Anweisungen in einer Transaktion zusammengefasst werden. Maximieren Sie die Kontingente für Transaktionsgröße, Dokumentgröße und Anzahl der Dokumente pro Transaktion gemäß der Definition in Kontingente und Limits bei Amazon QLDB.
-
Wenn Batching für große Transaktionslasten nicht ausreicht, können Sie Multithreading ausprobieren, indem Sie zusätzliche Writer hinzufügen. Sie sollten jedoch sorgfältig die Anwendungsanforderungen an die Dokument- und Transaktionssequenzierung im Hinblick auf die damit einhergehende Komplexität abwägen.
Mehrere Anweisungen pro Transaktion ausführen
Wie im vorherigen Abschnitt beschrieben, können Sie mehrere Anweisungen pro Transaktion ausführen, um die Leistung Ihrer Anwendung zu optimieren. Im folgenden Codebeispiel fragen Sie eine Tabelle ab und aktualisieren dann ein Dokument in dieser Tabelle innerhalb einer Transaktion. Dazu übergeben Sie der execute
Operation einen Lambda-Ausdruck.
Die execute
Operation des Treibers startet implizit eine Sitzung und eine Transaktion in dieser Sitzung. Jede Anweisung, die Sie im Lambda-Ausdruck ausführen, ist in die Transaktion eingeschlossen. Nachdem alle Anweisungen ausgeführt wurden, schreibt der Treiber die Transaktion automatisch fest. Wenn eine Anweisung fehlschlägt, nachdem das automatische Wiederholungslimit erschöpft ist, wird die Transaktion abgebrochen.
Verbreiten von Ausnahmeregelungen in einer Transaktion
Wenn Sie mehrere Anweisungen pro Transaktion ausführen, empfehlen wir generell nicht, Ausnahmen innerhalb der Transaktion abzufangen und zu schlucken.
Beispielsweise fängt das folgende Programm in Java jede Instance von RuntimeException
ab, protokolliert den Fehler und fährt fort. Dieses Codebeispiel wird als schlechte Praxis angesehen, da die Transaktion sogar dann erfolgreich ist, wenn die UPDATE
-Anweisung fehlschlägt. Daher geht der Client möglicherweise davon aus, dass das Update erfolgreich war, auch dies nicht der Fall war.
Warnung
Verwenden Sie dieses Codebeispiel nicht. Er wird bereitgestellt, um ein Anti-Pattern-Beispiel zu zeigen, das als schlechte Praxis gilt.
// DO NOT USE this code example because it is considered bad practice
public static void main(final String... args) {
ConnectToLedger.getDriver().execute(txn -> {
final Result selectTableResult = txn.execute("SELECT * FROM Vehicle WHERE VIN ='123456789'");
// Catching an error inside the transaction is an anti-pattern because the operation might
// not succeed.
// In this example, the transaction succeeds even when the update statement fails.
// So, the client might assume that the update succeeded when it didn't.
try {
processResults(selectTableResult);
String model = // some code that extracts the model
final Result updateResult = txn.execute("UPDATE Vehicle SET model = ? WHERE VIN = '123456789'",
Constants.MAPPER.writeValueAsIonValue(model));
} catch (RuntimeException e) {
log.error("Exception when updating the Vehicle table {}", e.getMessage());
}
});
log.info("Vehicle table updated successfully.");
}
Propagieren Sie stattdessen die Ausnahme (lassen Sie sie auftauchen). Wenn ein Teil der Transaktion fehlschlägt, lassen Sie den execute
Vorgang die Transaktion abbrechen, damit der Client die Ausnahme entsprechend behandeln kann.