2016-02-09 10 views
10

Ich habe eine Lambda-Funktion, die eine Datei von S3 jedes Mal lesen muss, wenn es ausgeführt wird.
Die Datei ist sehr klein, etwa 200 Bytes, der S3-Bucket befindet sich in der US-Standardregion, die Lambda-Funktion befindet sich in der us-east-1-Region (also der gleichen Region). Es dauert zwischen 10 und 15 Sekunden, um die Datei zu lesen. Wie kommt es, dass das so langsam ist?AWS Lambda-Funktion extrem langsam S3-Datei abrufen

Danke.

EDIT: einige Code

long start = System.nanoTime(); 
AmazonS3Client s3Client = new AmazonS3Client(); 
S3Object propertyFile = null; 
try { 
    propertyFile = s3Client.getObject(S3_BUCKET_NAME, S3_PROPERTY_FILE); 
} catch (Exception e) {...} 
try (InputStream in = propertyFile.getObjectContent()) { 
    PROPERTIES.load(in); 
} catch (Exception e) {...} 
LOGGER.debug("S3 access " + (System.nanoTime() - start)); 

EDIT # 2: Nach Brooks' Vorschlag habe ich

AmazonS3Client s3Client = new AmazonS3Client(new InstanceProfileCredentialsProvider()); 

Und ich bekomme diese Fehlermeldung:

Unable to load credentials from Amazon EC2 metadata service 

EDIT # 3:
Der Speicher für die Lambda-Funktion war 256 MB, wenn ich 1024MB zuweisen, ta kes 3-4 Sekunden, das ist immer noch zu langsam (es dauert etwa 1-2 Sekunden, wenn ich lokal von meinem Computer aus teste).

+0

Die Person, die unten abgestimmt hat, könnte vielleicht den Grund erklären. –

+0

Versuchen Sie, den InstanceProfileCredentialsProvider anzugeben, wenn Sie den AmazonS3Client instanziieren. Der Standardkonstruktor muss die Autorisierung über (in dieser Reihenfolge) Umgebungsvariablen, Systemeigenschaften, Berechtigungsnachweisdatei und dann Instanzprofil versuchen. Ihre bevorzugte Autorisierungsmethode ist also die letzte. Ich würde nicht denken, dass es so lange dauern würde, aber probier es aus und lass es mich wissen. – Brooks

+0

Sorry, ich habe mich geirrt. Ich hatte gedacht, dass Lambda-Container mit InstanceProfiles ausgeliefert werden (ich kann nicht herausfinden, warum das nicht der Fall war). Es scheint, dass es mit Anmeldeinformationen geliefert wird, die in Umgebungsvariablen angegeben sind (http://stackoverflow.com/questions/32275169/aws-lambda-custom-triggers). Versuchen Sie, beim Instanziieren des AmazonS3-Clients (new EnvironmentVariableCredentialsProvider()) anzugeben. Obwohl es das erste Element in der Liste der Anmeldeinformationen ist, die bei Verwendung des Standardkonstruktors überprüft wurden, kann es nicht schaden, es zu versuchen. Lass uns wissen. – Brooks

Antwort

1

Was würde ich vorschlagen, ist ProfileCredentialsProvider zu verwenden und S3 Client-Instanz zwischen Lambda-Funktion Ausführungen cachen:

public class MyLambda { // No matter you implement standard AWS SDK interfaces or not 

    private final AmazonS3Client s3Client = new AmazonS3Client(new ProfileCredentialsProvider()); 

    public String sayHello(Request request, Context context) { 
     S3Object s3Obj = s3Client.getObject(request.getBucket(), request.getKey()); 
     return S3Utils.getContent(s3Object); // Some util which retrieves object content 
    } 
} 

Die Sache ist, dass es einige Zeit dauert, das S3-Client einzurichten, die Verbindungen Pool und andere verwaltet Ressourcen.

+0

'ProfileCredentialsProvider' arbeitet mit den Rollenberechtigungen, die Sie Ihrer Funktion zugewiesen haben. – Nazar