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.
Leistungsoptimierung
Beachten Sie die folgenden Empfehlungen zur Codeoptimierung für Ihre Runtime SnapStart, um die Vorteile von zu maximieren.
Anmerkung
SnapStart funktioniert am besten, wenn es mit Funktionsaufrufen in großem Maßstab verwendet wird. Funktionen, die selten aufgerufen werden, weisen möglicherweise nicht dieselben Leistungsverbesserungen auf.
Um die Vorteile von zu maximieren SnapStart, empfehlen wir, Abhängigkeiten vorab zu laden und Ressourcen, die zur Startlatenz beitragen, in Ihrem Initialisierungscode statt im Funktionshandler zu initialisieren. Dadurch wird die Latenz, die mit dem Laden schwerer Klassen verbunden ist, aus dem Aufrufpfad entfernt, wodurch die Startleistung mit optimiert wird. SnapStart
Wenn Sie Abhängigkeiten oder Ressourcen nicht während der Initialisierung vorladen können, empfehlen wir Ihnen, sie mit Dummy-Aufrufen vorzuladen. Aktualisieren Sie dazu den Code des Funktionshandlers, wie im folgenden Beispiel aus der Funktion pet store im
private static SpringLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
static {
try {
handler = SpringLambdaContainerHandler.getAwsProxyHandler(PetStoreSpringAppConfig.class);
// Use the onStartup method of the handler to register the custom filter
handler.onStartup(servletContext -> {
FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class);
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
});
// Send a fake Amazon API Gateway request to the handler to load classes ahead of time
ApiGatewayRequestIdentity identity = new ApiGatewayRequestIdentity();
identity.setApiKey("foo");
identity.setAccountId("foo");
identity.setAccessKey("foo");
AwsProxyRequestContext reqCtx = new AwsProxyRequestContext();
reqCtx.setPath("/pets");
reqCtx.setStage("default");
reqCtx.setAuthorizer(null);
reqCtx.setIdentity(identity);
AwsProxyRequest req = new AwsProxyRequest();
req.setHttpMethod("GET");
req.setPath("/pets");
req.setBody("");
req.setRequestContext(reqCtx);
Context ctx = new TestContext();
handler.proxy(req, ctx);
} catch (ContainerInitializationException e) {
// if we fail here. We re-throw the exception to force another cold start
e.printStackTrace();
throw new RuntimeException("Could not initialize Spring framework", e);
}
}
Um die Vorteile von zu maximieren SnapStart, konzentrieren Sie sich auf eine effiziente Codeorganisation und Ressourcenverwaltung innerhalb Ihrer Python-Funktionen. Als allgemeine Richtlinie gilt, dass Sie während der Initialisierungsphase umfangreiche Rechenaufgaben ausführen sollten. Mit diesem Ansatz werden zeitaufwändige Operationen aus dem Aufrufpfad herausgenommen, was die Gesamtleistung der Funktion verbessert. Um diese Strategie wirksam umzusetzen, empfehlen wir die folgenden bewährten Verfahren:
-
Import von Abhängigkeiten außerhalb des Funktionshandlers.
-
Erstellen Sie
boto3
-Instances außerhalb des Handlers. -
Initialisieren Sie statische Ressourcen oder Konfigurationen, bevor der Handler aufgerufen wird.
-
Erwägen Sie die Verwendung eines Laufzeit-Hooks vor dem Snapshot für ressourcenintensive Aufgaben wie das Herunterladen externer Dateien, das Vorladen von Frameworks wie Django oder das Laden von Machine-Learning-Modellen.
Beispiel — Optimiere die Python-Funktion für SnapStart
# Import all dependencies outside of Lambda handler
from snapshot_restore_py import register_before_snapshot
import boto3
import pandas
import pydantic
# Create S3 and SSM clients outside of Lambda handler
s3_client = boto3.client("s3")
# Register the function to be called before snapshot
@register_before_snapshot
def download_llm_models():
# Download an object from S3 and save to tmp
# This files will persist in this snapshot
with open('/tmp/FILE_NAME', 'wb') as f:
s3_client.download_fileobj('amzn-s3-demo-bucket', 'OBJECT_NAME', f)
...
def lambda_handler(event, context):
...
Um die just-in-time (JIT-) Kompilierung und das Laden von Assemblys zu reduzieren, sollten Sie erwägen, Ihren Funktionshandler von einem RegisterBeforeCheckpoint
Runtime-Hook aus aufzurufen. Aufgrund der Funktionsweise von .NET Tiered Compilation erhalten Sie optimale Ergebnisse, wenn Sie den Handler mehrfach aufrufen, wie im folgenden Beispiel gezeigt.
Wichtig
Vergewissern Sie sich, dass Ihr Dummy-Funktionsaufruf keine unbeabsichtigten Nebeneffekte hervorruft, wie z. B. das Auslösen von Geschäftstransaktionen.
public class Function
{
public Function()
{
Amazon.Lambda.Core.SnapshotRestore.RegisterBeforeSnapshot(FunctionWarmup);
}
// Warmup method that calls the function handler before snapshot to warm up the .NET code and runtime.
// This speeds up future cold starts after restoring from a snapshot.
private async ValueTask FunctionWarmup()
{
var request = new APIGatewayProxyRequest
{
Path = "/heathcheck",
HttpMethod = "GET"
};
for (var i = 0; i < 10; i++)
{
await FunctionHandler(request, null);
}
}
public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
{
//
// Process HTTP request
//
var response = new APIGatewayProxyResponse
{
StatusCode = 200
};
return await Task.FromResult(response);
}
}
Bewährte Praktiken für das Netzwerk
Der Zustand der Verbindungen, die Ihre Funktion während der Initialisierungsphase erstellt, wird nicht garantiert, wenn Lambda Ihre Funktion aus einem Snapshot wieder aufnimmt. In den meisten Fällen werden Netzwerkverbindungen, die ein AWS SDK herstellt, automatisch wieder aufgenommen. Für andere Verbindungen empfehlen wir die folgenden bewährten Methoden.
Wiederherstellen von Netzwerkverbindungen
Stellen Sie Ihre Netzwerkverbindungen immer wieder her, wenn Ihre Funktion von einem Snapshot fortgesetzt wird. Wir empfehlen, dass Sie die Netzwerkverbindungen im Funktionshandler wiederherstellen. Alternativ können Sie ein After-Restore-Laufzeit-Hook verwenden.
Verwenden Sie den Hostnamen nicht als eindeutige ID der Ausführungsumgebung
Wir raten davon ab, hostname
zu verwenden, um Ihre Ausführungsumgebung als eindeutigen Knoten oder Container in Ihren Anwendungen zu identifizieren. Bei SnapStart wird ein einzelner Snapshot als Ausgangszustand für mehrere Ausführungsumgebungen verwendet. Alle Ausführungsumgebungen geben denselben hostname
-Wert für InetAddress.getLocalHost()
(Java), socket.gethostname()
(Python) und Dns.GetHostName()
(.NET) zurück. Für Anwendungen, die eine eindeutige Identität oder einen eindeutigen hostname
-Wert der Ausführungsumgebung erfordern, empfehlen wir, im Funktionshandler eine eindeutige ID zu generieren. Oder verwenden Sie einen After-Restore-Laufzeit-Hook, um eine eindeutige ID zu generieren und verwenden Sie dann die eindeutige ID für die Ausführungsumgebung.
Vermeiden der Bindung von Verbindungen an feste Quellports
Wir empfehlen, Netzwerkverbindungen nicht an feste Quellports zu binden. Wenn eine Funktion nach einem Snapshot wieder aufgenommen wird, werden die Verbindungen neu aufgebaut, und Netzwerkverbindungen, die an einen festen Quellport gebunden sind, können fehlschlagen.
Vermeiden der Verwendung von Java-DNS-Cache
Lambda-Funktionen speichern DNS-Antworten bereits im Cache. Wenn Sie einen anderen DNS-Cache mit verwenden SnapStart, kann es zu Verbindungstimeouts kommen, wenn die Funktion von einem Snapshot aus wieder aufgenommen wird.
Die java.util.logging.Logger
-Klasse kann indirekt den JVM-DNS-Cache aktivieren. Um die Standardeinstellungen zu überschreiben, setzen Sie networkaddress.cache.ttllogger
initialisieren. Beispiel:
public class MyHandler {
// first set TTL property
static{
java.security.Security.setProperty("networkaddress.cache.ttl" , "0");
}
// then instantiate logger
var logger = org.apache.logging.log4j.LogManager.getLogger(MyHandler.class);
}
Um UnknownHostException
-Ausfälle in der Java 11-Laufzeit zu vermeiden, empfehlen wir, networkaddress.cache.negative.ttl
auf 0 zu setzen. In Java 17 und späteren Laufzeiten ist dieser Schritt nicht erforderlich. Sie können diese Eigenschaft für eine Lambda-Funktion mit der Umgebungsvariablen AWS_LAMBDA_JAVA_NETWORKADDRESS_CACHE_NEGATIVE_TTL=0
festlegen.
Das Deaktivieren des JVM-DNS-Cache deaktiviert nicht das verwaltete DNS-Caching von Lambda.