Tim*_*Tim 3 ruby pg amazon-redshift
我使用Ruby pg gem在事务中运行了几个sql语句.我遇到的问题是由于防火墙设置,连接超时了这些查询.这里提出的解决方案不起作用,因为它需要jdbc连接字符串,而我在Ruby中(jRuby不是一个选项).将驱动程序移动到AWS以删除防火墙也不是一种选择.
我的代码如下:
conn = RedshiftHelper.get_redshift_connection
begin
conn.transaction do
# run my queries
end
ensure
conn.flush
conn.finish
end
Run Code Online (Sandbox Code Playgroud)
我现在正在研究PG异步API.我想知道我是否可以使用is_busy来防止防火墙超时,或者是那种效果.我找不到关于这个主题的好文档.感谢任何提示.
PS:我已经为单个查询解决了这个问题 - 我可以异步触发它并使用系统STV_INFLIGHT Redshift table来跟踪它的完成.事务不会以这种方式工作,因为我必须保持连接打开.
好的,我把它钉了下来.以下是事实:
根据上述事实,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
Run Code Online (Sandbox Code Playgroud)
我之所以引入代理Connection类,是因为Ruby IO在超出范围时倾向于垃圾收集对象(如套接字).这意味着我们现在需要连接和套接字在同一范围内,这是通过此代理类实现的.我的Ruby知识不深,所以可能有更好的方法来处理套接字对象.
这种方法有效,但我很乐意了解是否有更好/更清洁的解决方案.