java.lang.RuntimeException: An error occurred in ElasticsearchSink
Caused by: java.net.SocketTimeoutException: 240,000 milliseconds timeout on connection http-outgoing-3 [ACTIVE]
问题分析一:
1、Caused by: java.net.SocketTimeoutException
查看elasticsearch集群是正常的,而且负载没很高
2、Caused by: java.lang.RuntimeException: An error occurred in ElasticsearchSink.
说明在Sink时有问题
解决方法一:设置刷新配置参数
esSinkBuilder.setBulkFlushMaxActions(2000);
esSinkBuilder.setBulkFlushMaxSizeMb(5);
esSinkBuilder.setBulkFlushInterval(2000L);
问题分析二:
基本上可以确定,数据没有问题,ES集群也没有压力(有短时间的oldGC),所以就把排查重点放在了sink这一块,由于Flink写ES采用的Http方式,所以排查HttpAsyncClientBuilder类的参数发现:
private ConnectionKeepAliveStrategy keepAliveStrategy;
而ES sink使用的默认连接时间是-1。即永不过期
怀疑ES集群在OldGC时造成 http 长连接dead,而且不会创建新的连接,导致数据刷ES超时。
添加自定义的KeepAliveStrategy,这里维持时间设置为 5min
esSinkBuilder.setRestClientFactory(new RestClientFactory() {
@Override
public void configureRestClientBuilder(RestClientBuilder restClientBuilder) {
//设置ES用户名和密码
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(Configurations.getString("es.sensors.untreated.name"),
Configurations.getString("es.sensors.untreated.passwd")));
restClientBuilder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
httpClientBuilder.disableAuthCaching();
httpClientBuilder.setDefaultCredentialsProvider( credentialsProvider);
httpClientBuilder.setKeepAliveStrategy((response, context) -> Duration.ofMinutes(5).toMillis());
return httpClientBuilder;
}
});
restClientBuilder.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
@Override
public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder requestConfigBuilder) {
return requestConfigBuilder
.setConnectionRequestTimeout(1000 * 60 * 2)
.setSocketTimeout(1000 * 60 * 2);
}
});
}
});