我在 AWS 上有一个 Redshift 实例。 我的应用程序在与 Redshift 集群位于同一区域的 EC2 上作为 Windows 服务运行。我有一个查询平均需要大约 45 秒,而 redshift 显然有 30 秒的默认超时。因此,在该查询运行约 30 秒后,我得到:
错误:查询 (SOME_NUMBER) 应用户请求而取消; 执行查询时出错
相同的查询在 SQL Workbench/J 中运行并完成良好,因此集群配置正确。我尝试过但没有运气:
有人知道如何删除或更改默认超时吗?
这种连接字符串格式对我来说非常有效:
Host={Host};Port={Port};Username={Username};Password={Password};SSL Mode=Require;Server Compatibility Mode=Redshift;Timeout=45;Command Timeout={TimeoutSeconds};Tcp Keepalive=true;
“Timeout”是连接超时 “命令超时”是默认命令超时
您还可以在命令本身上设置命令超时:
await using var cmd = new NpgsqlCommand(commandSql, con) { CommandTimeout = 300 };
需要设置保活参数。对于 JDBC 驱动程序来说是
tcpKeepAlive
。不确定它是否与 ODBC 具有相同的名称。
另一个可能影响您的问题是 MTU 大小。 Redshift 支持最大 MTU 为 1500(这是网络上的最大数据包大小),并且大多数互联网连接也被“分块”这么多,以支持路径中的所有各种交换机。 但是,EC2 实例和 AWS 网络没有此限制,可以支持更大的 MTU,并且默认设置为这样做。 因此,可能发生的情况是,EC2 发送一个长查询,而 Redshift 只能看到其中的前 1500 个字节,并正在等待其余部分。双方都在等待对方。
要解决此问题,您需要将 EC2 实例的网络配置更改为 MTU 1500。我在 Linux EC2 上这样做的次数不多,但在 Windows 上从未这样做过。 因此,这里有一个指向描述 Windows 流程的页面的链接 - https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/network_mtu.html#set_mtu_windows
以编程方式针对
CommandTimeout
设置 OdbcCommand
为我解决了这个问题。在连接字符串中设置它不起作用。
并且设置
ConnectionTimeout
不起作用,我认为这是因为这只是建立初始连接的超时。