[英]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.