2014-10-10 4 views
2

Ruby pg gem을 사용하여 트랜잭션에서 여러 개의 sql 문을 실행합니다. 내가 부딪힌 문제는 방화벽 설정으로 인해 이러한 쿼리에 연결 시간이 초과된다는 것입니다. 솔루션 제안 here jdbc 연결 문자열이 필요하며 Ruby (jRuby는 옵션이 아님)에 있기 때문에 작동하지 않습니다. 드라이버 프로그램을 AWS로 이동하여 방화벽을 제거하는 것도 옵션이 아닙니다. 나는 다음과 같은 라인을 따라입니다이Ruby에서 장기간 실행되는 Redshift 트랜잭션

코드 :

conn = RedshiftHelper.get_redshift_connection 
begin 
    conn.transaction do 
    # run my queries 
    end 
ensure 
    conn.flush 
    conn.finish 
end 

는 지금 PG 비동기 API로 찾고 있어요. is_busy를 사용하여 방화벽이 시간 초과되는 것을 막을 수 있는지 궁금 해서요. 나는 주제에 대한 좋은 문서를 찾을 수 없다. 그것에 대한 힌트를 주셔서 감사합니다.

추신 : 단일 쿼리에 대해이 문제를 해결했습니다. 시스템을 STV_INFLIGHT Redshift table.Transaction을 사용하여 비동기 적으로 트리거하고 완료를 추적 할 수 있습니다. 연결을 유지해야하므로이 방식으로 작동하지 않습니다.

답변

3

좋아, 나는 그것을 내려 놓았다. 다음은 사실입니다.

  1. Redshift는 Postgres 8.0을 기반으로합니다. 확인하려면 psql을 사용하여 Redshift 인스턴스에 연결하고 "server version 8.0"을 확인하십시오.
  2. Keepalive 요청은 TCP 소켓 (link) 수준에서 지정됩니다. 연결 문자열 (link 9.0 릴리스 변경, libpq를 섹션의 E.19.3.9.1)
  3. 루비에서
  4. PG 보석이 libpq 라이브러리에 대한 래퍼입니다 를 지정할 때
  5. 포스트 그레스 8.0 킵 얼라이브 옵션을 지원하지 않습니다

기반 위의 사실에서 Redshift는 tcp keepalive를 지원하지 않습니다. 그러나 PG를 사용하면 설정된 연결에서 사용되는 소켓을 검색 할 수 있습니다. 이것은 libpq가 keepalive 기능을 설정하지 않더라도 우리는 여전히 수동으로 사용할 수 있음을 의미합니다.따라서이 솔루션은 : 그들은 범위에서 얻을 때

class Connection 

     attr_accessor :socket, :pg_connection 

     def initialize(conn, socket) 
     @socket = socket 
     @pg_connection = conn 
     end 

     def method_missing(m, *args, &block) 
     @pg_connection.send(m, *args, &block) 
     end   

     def close 
     @socket.close 
     @pg_connection.close 
     end 

     def finish 
     @socket.close 
     @pg_connection.close 
     end 
    end  

def get_connection 
     conn = PGconn.open(...) 
     socket_descriptor = conn.socket 
     socket = Socket.for_fd(socket_descriptor) 
     # Use TCP keep-alive feature 
     socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1) 
     # Maximum keep-alive probes before asuming the connection is lost 
     socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT, 5) 
     # Interval (in seconds) between keep-alive probes 
     socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL, 2) 
     # Maximum idle time (in seconds) before start sending keep-alive probes 
     socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE, 2) 
     socket.autoclose = true 
     return Connection.new(conn, socket) 
end 

내가 Connection 클래스가 있기 때문에 루비 경향이다 프록시 소개하는 이유 (소켓 등) IO 객체 쓰레기를-수집합니다. 즉,이 프록시 클래스를 통해 구현되는 동일한 범위에 연결 및 소켓이 있어야합니다. 내 Ruby 지식은 깊지 않으므로 소켓 객체를 처리하는 더 좋은 방법이있을 수 있습니다.

이 방법이 효과적이지만 더 나은/더 나은 솔루션이 있는지 배우게되어 기쁩니다.

+0

시간을내어 함께 해 주셔서 감사합니다. –

0

The link you provided has the answer. 3 개의 다른 OS에 대한 설정이있는 맨 위의 섹션을 따르고 싶다고 생각합니다. 코드를 실행중인 클라이언트 (Amazon 서비스에 대한 클라이언트)를 선택하십시오. 이 섹션의

찾는 위치 : TCP/IP 시간 제한 설정을 변경하려면 -이 코드가 실행되고있는 OS (즉, 아마존 서비스에 대한 클라이언트는 아마 당신의 서버입니다)

리눅스 - 클라이언트 인 경우 Linux에서 실행중인 경우 root 사용자로 다음 명령을 실행하십시오.

- 자세한 내용은 생략 -

윈도우 - 클라이언트가 윈도우에서 실행되는 경우, CURRENTCONTROLSET \ HKEY_LOCAL_MACHINE을 \ 시스템에서 다음 레지스트리 설정 값을 편집 서비스 \ \은 Tcpip \ 매개 변수 :

을 - 자세한 내용은 생략 -

맥 - 고객이 맥의 경우, 작성하거나 다음과 같은 값으로 /etc/sysctl.conf에 파일을 수정 :

- 생략 세부 -

+1

나는 그것을 시험해 보았다. 그것은 불행하게도 나를 위해 작동하지 않는다. 어딘가에 그래서 나는 당신이 두 가지 (OS 설정과 keepalive)를 할 필요가 있다는 것을 알았지 만, 나는 말했듯이 나는 두 번째를 할 수 없다. – Tim

+0

psql과 Aginity 워크 벤치 모두 같은 문제가있다. 백엔드가 처리를 마친 후에 오랫동안 코드가 실행되지 않는다. JDBC, ODBC 및 Npgsql에서 작동하는 것처럼 보인다. keepalive 설정을 성공과 함께 사용했습니다 .... –

관련 문제