簡體   English   中英

AWS / Lambda / Java上的Elasticsearch客戶端 - 2.5秒客戶端啟動時間

[英]Elasticsearch client on AWS / Lambda / Java - 2.5 seconds client startup time

我們使用AWS Lambda(Java)和elasticsearch客戶端連接到AWS上的托管彈性搜索實例。 我在第一次請求時遇到了漫長的等待,大約2.5秒(在冷啟動之上)。 之后很快。 我無法弄清楚這種延遲的來源,我正在努力優化它。

private void testPerformanceElasticSearch() throws Exception {
        log.info("1. Before testing elasticsearch client");
        AWS4Signer signer = new AWS4Signer();
        signer.setServiceName("es");
        signer.setRegionName("eu-west-1");
        HttpRequestInterceptor interceptor = new AWSRequestSigningApacheInterceptor("es", signer, new DefaultAWSCredentialsProviderChain());
        String endpoint = "https://" + Utils.getEnvironmentVariable("ELASTIC_SEARCH_ENDPOINT");
        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(HttpHost.create(endpoint)).setHttpClientConfigCallback(hacb -> hacb.addInterceptorLast(interceptor)));
        log.info("2. After getting elasticsearch client");
        log.info("3. Before doing a elasticsearch query");
        log.info("4");
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        log.info("5");
        TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("userId", "abc");
        log.info("6");
        boolQueryBuilder.must(termsQueryBuilder);
        log.info("7");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        log.info("8");
        searchSourceBuilder.query(boolQueryBuilder);
        log.info("9");
        SearchRequest searchRequest = new SearchRequest("users");
        log.info("10");
        searchRequest.source(searchSourceBuilder);
        log.info("11");
        restHighLevelClient.search(searchRequest);
        log.info("12");
        log.info("13. After testing elasticsearch");
}

然后我像這樣記錄; 你可以看到'5'和'6'之間有超過2秒的延遲,我無法真正放置:

17:16:06.871INFO[PlacesPerformance] 1. Before testing elasticsearch client
17:16:06.932INFO[PlacesPerformance] 2. After getting elasticsearch client
17:16:06.933INFO[PlacesPerformance] 3. Before doing a elasticsearch query
17:16:06.935INFO[PlacesPerformance] 4
17:16:06.942INFO[PlacesPerformance] 5
17:16:09.179INFO[PlacesPerformance] 6
17:16:09.179INFO[PlacesPerformance] 7
17:16:09.181INFO[PlacesPerformance] 8
17:16:09.181INFO[PlacesPerformance] 9
17:16:09.183INFO[PlacesPerformance] 10
17:16:09.183INFO[PlacesPerformance] 11
17:16:09.362INFO[PlacesPerformance] 12
17:16:09.362INFO[PlacesPerformance] 13. After testing elasticsearch

關於如何改進這個的任何建議?

更新:

奇怪。 每當我在lambda中運行代碼時,我在構造請求時經歷了2.5秒的延遲(甚至沒有執行它)。 在本地,它工作正常。 我嘗試了以下方法:

1.  Local against local elasticsearch. No delay.
2.  Local against AWS elasticsearch. No delay.
3.  Lambda with signing request. DELAY.
4.  Lambda without signing request. DELAY.
5.  Lambda with a 'match all' query. DELAY
6.  Lambda with a http address. DELAY.
7.  Lambda with a custom runtime. DELAY.
8.  Lambda with a custom runtime. DELAY.
9.  Lambda with standard Java 8 runtime. DELAY.

問題是,在第一個請求時(實際請求,不是預熱請求,因為預熱請求不通過您的應用程序代碼,它不會觸發在實際請求路徑中使用的加載類)JVM加載(讀取,解析,驗證等等...)相關類,初始化安全組件(密碼等...)和TLS握手完成(需要多個RTT,Java 9和TLS 1.3應該減少)。

第一次AWS服務調用(DynamoDB,SQS等)也會出現類似的長持續時間行為。

由於我是作者Thundra warmup插件,我正在考慮為預熱消息引入掛鈎點,因為自定義操作將能夠像初始化安全組件,加載類等一樣執行...

VPC內部的Lambda函數對啟動時間有很大影響。 你說你的ES是托管實例,所以我認為它是由VPC支持的。

即使它不在VPC中,Java冷啟動本質上通常比Node或Python等運行時更長,因為JVM需要首先啟動。 這主要是你的2.5秒來自的地方。

好。 如何解決這個問題?

這取決於ElasticSearch需要多少並發連接。 如果一個函數能夠處理所有傳入的請求,則可以將Lambda函數的並發執行限制為1,這樣您就可以確保始終使用相同的容器(只要這些請求在±5分鍾內完成)大體時間)。

現在,如果你不知道將要執行多少並發Lambda函數,那么你就沒有辦法了。 您可以嘗試預先升溫您的Lambda函數,但是您需要同時觸發100個請求來預熱100個不同的容器。

當我瀏覽Lambda函數的並發模型以及冷/暖開始工作時,請檢查這個答案

如果您有更多信息要分享或者我不夠清楚,我很樂意編輯我的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM