我使用Ruby pg gem在事务中运行了几个sql语句。我遇到的问题是由于防火墙设置,连接超时了这些查询。建议的解决方案here不起作用,因为它需要jdbc连接字符串,而我在Ruby中(jRuby不是一个选项)。将驱动程序移动到AWS以删除防火墙也不是一种选择。
我所拥有的代码如下:
conn = RedshiftHelper.get_redshift_connection
begin
conn.transaction do
# run my queries
end
ensure
conn.flush
conn.finish
end
我现在正在研究PG异步API。我想知道我是否可以使用is_busy来防止防火墙超时,或者是那种效果。我找不到关于这个主题的好文档。感谢任何提示。
PS:我已经为单个查询解决了这个问题 - 我可以异步触发它并使用系统STV_INFLIGHT Redshift table跟踪它的完成.Transaction不能这样工作,因为我必须保持连接打开。答案 0 :(得分:5)
好的,我把它钉了下来。以下是事实:
根据以上事实,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
类,是因为Ruby在超出范围时倾向于垃圾收集IO
对象(如套接字)。这意味着我们现在需要连接和套接字在同一范围内,这是通过此代理类实现的。我的Ruby知识不深,所以可能有更好的方法来处理套接字对象。
这种方法有效,但我很乐意了解是否有更好/更清洁的解决方案。
答案 1 :(得分:0)
The link you provided has the answer。我想你只想按照顶部的部分,它有3个不同操作系统的设置,选择你正在运行代码的那个(客户端到亚马逊服务)。
查看此部分:更改TCP / IP超时设置 - 这是运行代码的操作系统(即Amazon服务的客户端可能是您的服务器)
Linux - 如果您的客户端在Linux上运行,请以root用户身份运行以下命令。
- 详情遗漏 -
Windows - 如果您的客户端在Windows上运行,请在HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters下编辑以下注册表设置的值:
- 详情遗漏 -
Mac - 如果您的客户端是Mac,请使用以下值创建或修改/etc/sysctl.conf文件:
- 省略详情 -