Redshift сервер закрывает соединение через 10 минут - PullRequest
0 голосов
/ 07 мая 2018

У меня есть оператор, который занимает около 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 голосов
/ 14 октября 2018

OP здесь - я смог заставить его работать, написав оболочки через BasicDataSource и Connection для опроса активного соединения с isValid(int) каждые несколько минут (работает любая частота больше, чем раз в 10 минут). Оглядываясь назад, кажется, что большинство связанных с тайм-аутом свойств в BasicDataSource применяются к соединениям, которые находятся в пуле, но не используются. setDefaultQueryTimeout и tcpKeepAlive + TCPKeepAliveMinutes не работали.

P.S. Прошло много времени с тех пор, как я решил эту проблему, и у меня сейчас нет кода для упаковщиков. Вот краткое описание упаковщиков.

WrappedConnection класс принимает в своем конструкторе объект Connection (conn) и объект TimerTask (timerTask) и реализует интерфейс Connection, просто вызывая методы из conn. timerTask звонит this.isValid(100) каждые несколько минут, пока соединение активно. WrappedConnection.close останавливается timerTask и затем звонит conn.close.

WrappedBasicDataSource реализует интерфейс DataSource, перенаправляющий методы на объект BasicDataSource. BasicDataSourceWrapper.getConnection получает соединение от вышеупомянутого BasicDataSource и генерирует WrappedConnection, используя соединение и новый объект TimerTask.

Возможно, я пропустил объяснение некоторых деталей, но это суть этого.

0 голосов
/ 24 сентября 2018

проверьте, есть ли на сервере redshift политика управления рабочей нагрузкой, которая блокирует запросы по истечении 10 минут. возможно, ваш java-код устанавливает эту политику

0 голосов
/ 12 октября 2018

Вам нужно установить время 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);
0 голосов
/ 07 мая 2018

Возможно, вы захотите увеличить время ожидания сокета.

Ток это только 7200мс:

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