Redshift服务器在10分钟后关闭连接

时间:2018-05-07 11:01:25

标签: java jdbc amazon-redshift

我的声明大约需要20分钟才能运行,其形式如下:

create table new_table diststyle key distkey(column1) sortkey(column2) 
as (select ....);

当我使用SQL IDE或psql命令行客户端运行它时,语句成功执行但是当我从Java程序运行它时,服务器在10分钟后关闭连接,但出现以下异常:

    org.springframework.jdbc.UncategorizedSQLException: StatementCallback; uncategorized SQLException for SQL [create table new_table diststyle key distkey(column1) sortkey(column2) as (select ....);]; 
SQL state [HY000]; error code [600001]; [Amazon](600001) The server closed the connection.; 
nested exception is java.sql.SQLException: [Amazon](600001) The server closed the connection.
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:419) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:538) ~[spring-jdbc-4.3.4.RELEASE.jar:4.3.4.RELEASE]
    at com.abc.mypackage.MyClass.myMethod(Myclass.java:123) [classes/:?]
Caused by: java.sql.SQLException: [Amazon](600001) The server closed the connection.
    at com.amazon.support.channels.TLSSocketChannel.read(Unknown Source) ~[?:?]
Caused by: com.amazon.support.exceptions.GeneralException: [Amazon](600001) The server closed the connection.
    at com.amazon.support.channels.TLSSocketChannel.read(Unknown Source) ~[?:?]

我正在使用org.apache.commons.dbcp2.BasicDataSource来创建连接。我尝试通过defaultQueryTimeout,maxConnLifetimeMillis和socketTimeout延长超时但无济于事。服务器在相同的10分钟后继续关闭连接。

    dataSource = new BasicDataSource();
    dataSource.setUsername(dbUser);
    dataSource.setPassword(dbPassword);
    dataSource.setUrl(dbUrl);
    dataSource.setDefaultAutoCommit(true);
    dataSource.setTestOnBorrow(true);
    dataSource.setTestOnReturn(true);
    dataSource.setDriverClassName("com.amazon.redshift.jdbc41.Driver");
    dataSource.setDefaultQueryTimeout(7200);
    dataSource.setMaxConnLifetimeMillis(7200000);
    dataSource.addConnectionProperty("socketTimeout", "7200");

如何让连接保持更长时间?

P.S。建立连接和运行查询只需不到10分钟即可完成。

4 个答案:

答案 0 :(得分:0)

您可能希望延长套接字超时。

目前只有7200毫秒:

dataSource.addConnectionProperty("socketTimeout", "7200");

答案 1 :(得分:0)

检查redshift服务器是否具有工作负载管理策略,该策略在10分钟后使查询超时。 您的Java代码可能正在设置此政策

答案 2 :(得分:0)

在与Redshift集群建立连接时,需要将tcpKeepAlive时间设置为1分钟或更短时间。

               Properties props = new Properties();
               props.setProperty("user", user);
               props.setProperty("password", password);
               props.setProperty("tcpKeepAlive", "true");
               props.setProperty("TCPKeepAliveMinutes", "1");
               DriverManager.getConnection("jdbc:redshift://"+endpoint+":"
               +port+"/"+database, props);

答案 3 :(得分:0)

此处的操作-我能够通过在BasicDataSourceConnection上编写包装器来每隔几分钟({ 10分钟的作品)。事后看来,isValid(int)上大多数与超时有关的属性似乎适用于池中但未使用的连接。 BasicDataSourcesetDefaultQueryTimeout + tcpKeepAlive无效。

P.S。自解决此问题已有一段时间以来,我现在没有包装程序的代码。这是包装的简要说明。

TCPKeepAliveMinutes类在其构造函数中接受一个WrappedConnection对象(Connection)和一个conn对象(TimerTask),并实现timerTask只需从Connection调用方法即可实现接口。只要连接处于活动状态,conn每隔几分钟就会呼叫timerTaskthis.isValid(100)停止WrappedConnection.close,然后呼叫timerTask

conn.close实现WrappedBasicDataSource接口,将方法重定向到DataSource对象。 BasicDataSource从上述BasicDataSourceWrapper.getConnection获得一个连接,并使用该连接和一个新的BasicDataSource对象生成一个WrappedConnection

我可能会错过一些细节的解释,但这是要点。