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à.
Massimizzare le prestazioni di Lambda SnapStart
Ottimizzazione prestazioni
Per massimizzare i vantaggi di SnapStart, prendi in considerazione i seguenti consigli di ottimizzazione del codice per il tuo runtime.
Nota
SnapStart funziona al meglio se utilizzato con richiami di funzioni su larga scala. Le funzioni richiamate di rado potrebbero non presentare gli stessi miglioramenti delle prestazioni.
Per aumentare al massimo i vantaggi di SnapStart, consigliamo di precaricare le dipendenze e inizializzare le risorse che contribuiscono alla latenza di avvio nel codice di inizializzazione anziché nell'handler della funzione. Ciò sposta la latenza associata al caricamento intensivo delle classi dal percorso di chiamata, ottimizzando le prestazioni di avvio con SnapStart.
Se non riesci a precaricare le dipendenze o le risorse durante l'inizializzazione, ti consigliamo di precaricarle con invocazioni fittizie. Per far ciò, aggiorna il codice del gestore delle funzioni come mostrato nell'esempio seguente dalla funzione pet store
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); } }
Per massimizzare i vantaggi di SnapStart, concentrati sull'organizzazione efficiente del codice e sulla gestione delle risorse all'interno delle tue funzioni Python. Come linea guida generale, esegui attività di calcolo complesse durante la fase di inizializzazione. Questo approccio elimina dal percorso di invocazione le operazioni che richiedono molto tempo, migliorando le prestazioni complessive delle funzioni. Per implementare questa strategia in modo efficace, consigliamo le seguenti best practice:
-
Importa le dipendenze al di fuori dell'handler della funzione.
-
Crea istanze
boto3al di fuori dell'handler. -
Inizializza le risorse o le configurazioni statiche prima che l'handler venga richiamato.
-
Prendi in considerazione l'utilizzo di un hook di runtime prima dello snapshot per attività che richiedono molte risorse come il download di file esterni, il precaricamento di framework come Django o il caricamento di modelli di machine learning.
Esempio : ottimizzazione della funzione Python per 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): ...
Per ridurre i tempi di compilazione just-in-time (JIT) e di caricamento degli assembly, considera la possibilità di richiamare l'handler della funzione da un hook di runtime RegisterBeforeCheckpoint. Grazie al funzionamento della compilazione su più livelli .NET, otterrai risultati ottimali richiamando l'handler più volte, come illustrato nell'esempio seguente.
Importante
Assicurati che l'invocazione della funzione fittizia non produca effetti collaterali indesiderati, come l'avvio di transazioni commerciali.
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); } }
Best practice per la rete
Lo stato delle connessioni che la funzione stabilisce durante la fase di inizializzazione non è garantito quando Lambda riprende la funzione da uno snapshot. Nella maggior parte dei casi, le connessioni di rete stabilite da un SDK AWS riprendono automaticamente. Per altre connessioni, consigliamo le seguenti best practice.
Ristabilire le connessioni di rete
Ristabilisci sempre le connessioni di rete quando la funzione riprende da uno snapshot. Si consiglia di ristabilire le connessioni di rete nel gestore delle funzioni. In alternativa, puoi usare un hook di runtime dopo il ripristino.
Non utilizzare hostname come identificatore univoco dell'ambiente di esecuzione
Si consiglia di non utilizzare hostname per identificare l'ambiente di esecuzione come nodo o container univoco nelle applicazioni. Con SnapStart, viene utilizzato un singolo snapshot come stato iniziale per più ambienti di esecuzione. Tutti gli ambienti di esecuzione restituiscono lo stesso valore hostname per InetAddress.getLocalHost() (Java), socket.gethostname() (Python) e Dns.GetHostName() (.NET). Per le applicazioni che richiedono un'identità dell'ambiente di esecuzione o un valore hostname univoco, si consiglia di generare un ID univoco nel gestore della funzione. Oppure, utilizza un hook di runtime dopo il ripristino per generare un ID univoco, quindi utilizza l'ID univoco come identificatore per l'ambiente di esecuzione.
Evitare di collegare connessioni a porte di origine fisse
Si consiglia di evitare di associare le connessioni di rete a porte di origine fisse. Le connessioni vengono ristabilite quando una funzione riprende da uno snapshot e le connessioni di rete legate a una porta di origine fissa potrebbero non riuscire.
Evitare di usare la cache DNS Java
Le funzioni Lambda memorizzano già nella cache le risposte DNS. Se con SnapStart si utilizza un'altra cache DNS, è possibile che si verifichino dei timeout di connessione quando la funzione riprende da uno snapshot.
La classe java.util.logging.Logger può abilitare indirettamente la cache DNS JVM. Per sovrascrivere le impostazioni predefinite, imposta networkaddress.cache.ttllogger. Esempio:
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); }
Per evitare errori UnknownHostException nel runtime di Java 11, si consiglia di impostare networkaddress.cache.negative.ttl su 0. Nei runtime di Java 17 e successivi, questa operazione non è necessaria. È possibile impostare questa proprietà per una funzione Lambda con la variabile di ambiente AWS_LAMBDA_JAVA_NETWORKADDRESS_CACHE_NEGATIVE_TTL=0.
La disabilitazione della cache DNS JVM non disabilita la cache DNS gestita da Lambda.