web-dev-qa-db-ja.com

LambdaでAmazonS3Clientを作成するときのOutOfMemoryError

128 MBのメモリのみで構成されたAWS Lambda関数があり、SNS(それ自体はS3によってトリガーされます)によってトリガーされ、S3からファイルをダウンロードします。

私の機能では、次のとおりです。

public class LambdaHandler {

    private final AmazonS3Client s3Client = new AmazonS3Client();

    public void gdeltHandler(SNSEvent event, Context context) {
        System.out.println("Starting");
        System.out.println("Found " + eventFiles.size() + " event files");
    }

AmazonS3Clientオブジェクトの作成に分離したOutOfMemoryErrorを取得しているため、コメントアウトしてこの投稿からすべてのロジックを除外しました。そのオブジェクトを取り出しても、エラーは発生しません。上記のコードとまったく同じ結果がOutOfMemoryErrorになります。

128MBのメモリを関数に割り当てましたが、認証情報を取得してAmazonS3Clientオブジェクトをインスタンス化するだけでは十分ではありませんか?

私はAmazonS3Clientコンストラクタを与えてみました

new EnvironmentVariableCredentialsProvider()

と同様

new InstanceProfileCredentialsProvider()

同様の結果で。

AmazonS3Clientオブジェクトの作成には、より多くのメモリが必要ですか?

以下はスタックトレースです。

メタスペース:Java.lang.OutOfMemoryError Java.lang.OutOfMemoryError:com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder.build(BeanDeserializerBuilder.Java:347)at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer( BeanDeserializerFactory.Java:242)at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.Java:143)at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.Java:409)at com.fasterxml.jackson.databind.deserのcom.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.Java:265)の.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.Java:358) .DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.Java:245)at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.Java:143)at com.fasterxml.jackson.databind.De com.fasterxml.jackson.databind.ObjectReader._prefetchRootDeserializer(ObjectReader.Java:1588)at com.fasterxml.jackson.databind.ObjectReader。(ObjectReader.Java:185)at com。のserializationContext.findRootValueDeserializer(DeserializationContext.Java:439) fastxml.jackson.databind.ObjectMapper._newReader(ObjectMapper.Java:558)at com.fasterxml.jackson.databind.ObjectMapper.reader(ObjectMapper.Java:3108)

InstanceProfileCredentialsProviderまたはEnvironmentVariableCredentialsProviderを提供しようとすると、次のスタックトレースが表示されます。

スレッド「メイン」の例外Java.lang.Error:Java.lang.OutOfMemoryError:Metaspace at lambdainternal.AWSLambda。(AWSLambda.Java:62)at Java.lang.Class.forName0(Native Method)at Java.lang.Class。 forName(Class.Java:348)at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.Java:94)原因:Java.lang.OutOfMemoryError:Metaspace at Java.lang.ClassLoader.defineClass1(Native Method)at Java.lang.ClassLoader。 defineClass(ClassLoader.Java:763)at Java.security.SecureClassLoader.defineClass(SecureClassLoader.Java:142)at Java.net.URLClassLoader.defineClass(URLClassLoader.Java:467)at Java.net.URLClassLoader.access $ 100(URLClassLoader。 Java:73)Java.net.URLClassLoader $ 1.run(URLClassLoader.Java:368)at Java.net.URLClassLoader $ 1.run(URLClassLoader.Java:362)at Java.security.AccessController.doPrivileged(Native Method)at Java .net.URLClassLoader.findClass(URLClassLoader.Java:361)at Java.lang.ClassLoader.loadClass(ClassLoader.Java:424)at Java.lang.ClassLoader.loadClass(ClassLoader.Java:357)at lambd ainternal.EventHandlerLoader $ PojoMethodRequestHandler.makeRequestHandler(EventHandlerLoader.Java:421)at lambdainternal.EventHandlerLoader.getTwoLengthHandler(EventHandlerLoader.Java:777)at lambdainternal.EventHandlerLoader.getHandlerFromOverload(EventHandlerLoader.Java:802)at lambdainternal.EventHandlerLoader.loadEventPojoHandler(Event :888)at lambdainternal.EventHandlerLoader.loadEventHandler(EventHandlerLoader.Java:740)at lambdainternal.AWSLambda.findUserMethodsImmediate(AWSLambda.Java:126)at lambdainternal.AWSLambda.findUserMethods(AWSLambda.Java:71)at lambdainternal.AWSLambdadada .Java:219)at lambdainternal.AWSLambda。(AWSLambda.Java:60)... 3つ以上のSTART RequestId:58837136-483e-11e6-9ed3-39246839616aバージョン:$ LATEST END RequestId:58837136-483e-11e6-9ed3-39246839616a REPORT RequestId:58837136-483e-11e6-9ed3-39246839616a期間:15002.92 ms課金期間:15000 msメモリサイズ:128 MB最大メモリ使用量:50 MB
2016-07-12T14:40:28.048Z 58837136-483e-11e6-9ed3-39246839616aタスクが15.00秒後にタイムアウトした

編集1関数に割り当てられたメモリを192MBまで増やした場合、それは正常に機能しますが、奇妙なことに、CloudWatchのログで59MBのメモリのみを使用すると報告します。残りのメモリを失うだけですか?

27
Brooks

AWS Java SDKを使用しているときにこれを観察しています。AWSクライアント(同期または非同期)を作成すると、メタスペースから取得される可能性があります。

これは、AmazonHttpClientの作成やリクエストハンドラチェーンの動的な読み込み(AmazonEc2Client#init() privateメソッドの一部)など、インスタンス化時にAmazonクライアントが実行していることが原因であると思います。

報告されたメモリ使用量はヒープ自体に関するものである可能性がありますが、メタスペースが含まれていない場合があります。 AWSフォーラムにはいくつかのスレッドがありますが、問題に関するAWSからの応答はありません。

18
AlexejK

ラムダに割り当てられたメモリを128 MBから256 MBに増やしてみてください

4
user1095501

コールドスタートを減らす1つの方法は、メモリを1536 MBに設定し、タイムアウトを15分に設定することです。これにより、新しいインスタンスを開始する必要があるときに、共有ホストでラムダを実行するのではなく、専用ホストがラムダのみを実行するようになります。S3からコピーするのではなく、ホストのキャッシュからコードをコピーします。

ただし、これはよりコストがかかります。これを実行したくない場合は、以下をお読みください。

コールドスタート時間を短縮するにはどうすればよいですか?

1)Lambdaのベストプラクティスに従います: https://docs.aws.Amazon.com/lambda/latest/dg/best-practices.html

2)関数に対してより大きなメモリ設定を選択することで、メモリが「電力」設定と考えてください。これは、関数が受け取るCPUの量も決定するためです。

3)関数Zipのサイズを小さくすることこれは、関数Zipに含める依存関係の数を減らすことを意味します。 Java ProGuardを使用してJARのサイズをさらに縮小できます

4)[Javaのみ] POJOインターフェースの代わりにバイトストリームインターフェースを使用します。 Lambdaが内部で使用するJSONシリアル化ライブラリは、開始するまでに時間がかかる場合があります。あなたの側で開発作業が必要になりますが、軽量のJSONライブラリと一緒にバイトストリームインターフェイスを使用することで、これを改善できる可能性があります。役立つリンクがいくつかあります: http://docs.aws.Amazon.com/lambda/latest/dg/Java-handler-io-type-stream.htmlhttps: //github.com/FasterXML/jackson-jr

5)[Javaのみ]匿名クラス(ラムダ、メソッド参照、コンストラクタ参照など)を置き換えるJava 8機能を使用しないでくださいJava 8 Lambda関連のバイトコードは、最適な起動パフォーマンスをもたらさないようです。コードが匿名クラス(ラムダ、メソッド参照、コンストラクター参照など)を置き換えるJava 8機能を使用している場合は、匿名クラスに戻ることで起動時間を短縮できます。

6)異なるランタイムを使用することにより、ランタイムごとにコールドスタート時間が異なり、ランタイムパフォーマンスも異なります。 NodeJSは重いIO作業に適しているかもしれませんが、Goは多くの同時作業を行うコードに適しているかもしれません。お客様は、Lambdaでの言語パフォーマンスを比較するためにいくつかの基本的なベンチマークを実行しました。ここでは、さまざまなプログラミング言語のパフォーマンスのより一般的な比較を示します。万能の答えはありません。要件に適したものを使用してください。

基本的なベンチマーク: https://read.acloud.guru/comparing-aws-lambda-performance-of-node-js-python-Java-c-and-go-29c1163c2581

一般的な比較: https://benchmarksgame-team.pages.debian.net/benchmarksgame/which-programs-are-fast.html

1
user3311298