解决 Amazon Redshift 中的连接问题 - Amazon Redshift

解决 Amazon Redshift 中的连接问题

如果您在从 SQL 客户端工具连接到集群时遇到问题,可以从几个方面进行排查以缩小问题范围。如果您使用了 SSL 或服务器证书,请在开始排查连接问题之前将其删除以降低复杂性。然后,在找出解决方案之后再添加。有关更多信息,请参阅 配置连接的安全选项

重要

Amazon Redshift 改变了我们管理 SSL 证书的方法。如果您在使用 SSL 连接时遇到问题,您可能需要更新当前的信任根 CA 证书。有关更多信息,请参阅 将 SSL 连接过渡到 ACM 证书

以下部分提供了一些针对连接问题的示例错误消息和可能的解决方案。不同 SQL 客户端工具提供的错误消息不同,因此,虽然此非完整列表,但却是不错的问题排查切入点。

从 Amazon EC2 外部连接时遇到防火墙超时问题

在运行 COPY 命令等较长的查询时,客户端到数据库的连接会挂起或超时。此时,您可能会发现,Amazon Redshift 控制台显示查询已完成,而客户端工具仍然显示正在运行查询。查询结果可能会丢失或不完整,具体取决于连接停止的时间。

可能的解决方案

当您从 Amazon EC2 实例以外的计算机连接到 Amazon Redshift 时,会发生此问题。在此情况下,空闲连接将在处于不活动状态一段时间后被防火墙等中间网络组件终止。当您从 Virtual Private Network(VPN)或本地网络登录时,通常会出现这种行为。

为避免出现此类超时,建议您执行以下更改:

  • 提高用于处理 TCP/IP 超时的客户端系统值。在用来连接集群的计算机上进行这些更改。根据您的客户端和网络调整超时期限。有关更多信息,请参阅 更改 TCP/IP 超时设置

  • (可选)在 DSN 级别设置 Keepalive 行为。有关更多信息,请参阅 更改 DSN 超时设置

更改 TCP/IP 超时设置

要更改 TCP/IP 超时设置,请根据您用来连接集群的操作系统配置超时设置。

  • Linux — 如果您的客户端在 Linux 上运行,请以根用户身份运行以下命令来更改当前会话的超时设置:

    /sbin/sysctl -w net.ipv4.tcp_keepalive_time=200 net.ipv4.tcp_keepalive_intvl=200 net.ipv4.tcp_keepalive_probes=5

    要保存设置,请使用以下值创建或修改文件 /etc/sysctl.conf,然后重新启动您的系统。

    net.ipv4.tcp_keepalive_time=200 net.ipv4.tcp_keepalive_intvl=200 net.ipv4.tcp_keepalive_probes=5
  • Windows — 如果您的客户端在 Windows 上运行,请在 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ 下编辑以下注册表设置的值:

    • KeepAliveTime:30000

    • KeepAliveInterval:1000

    • TcpMaxDataRetransmissions:10

    这些设置使用 DWORD 数据类型。如果它们不在注册表路径下,您可以创建设置并指定这些建议值。有关编辑 Windows 注册表的更多信息,请参阅 Windows 文档。

    在设置好这些值之后,重启您的计算机以使更改生效。

  • Mac — 如果您的客户端在 Mac 上运行,请运行以下命令来更改当前会话的超时设置:

    sudo sysctl net.inet.tcp.keepintvl=200000 sudo sysctl net.inet.tcp.keepidle=200000 sudo sysctl net.inet.tcp.keepinit=200000 sudo sysctl net.inet.tcp.always_keepalive=1

    要保存设置,请使用以下值创建或修改文件 /etc/sysctl.conf

    net.inet.tcp.keepidle=200000 net.inet.tcp.keepintvl=200000 net.inet.tcp.keepinit=200000 net.inet.tcp.always_keepalive=1

    重新启动计算机,然后运行以下命令来验证值是否已设置。

    sysctl net.inet.tcp.keepidle sysctl net.inet.tcp.keepintvl sysctl net.inet.tcp.keepinit sysctl net.inet.tcp.always_keepalive

更改 DSN 超时设置

如果需要,您可以在 DSN 级别设置 Keepalive 行为。在 odbc.ini 文件中添加或修改以下参数即可实现:

KeepAlivesCount

连接被视为断开前可能丢失的 TCP keepalive 包的数量。

KeepAlivesIdle

驱动程序发送 TCP Keepalive 包前处于不活动状态的秒数。

KeepAlivesInterval

两次传输 TCP keepalive 间隔的秒数。

如果这些参数不存在,或者其值为 0,则系统将使用为 TCP/IP 指定的 Keepalive 参数来确定 DSN Keepalive 行为。在 Windows 上,您可以在注册表中的 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\ 中查找 TCP/IP 参数。在 Linux 和 macOS 上,可以在 sysctl.conf 文件中查找 TCP/IP 参数。

连接被拒绝或失败

当连接被拒绝或失败时,您可能会收到类似于以下其中一种的错误。

  • “无法建立到 <endpoint> 的连接。”

  • “无法连接到服务器:连接超时。服务器是否在主机 '<endpoint>' 上运行,是否接受端口 '<port>' 上的 TCP/IP 连接?”

  • “连接被拒。请检查主机名和端口是否正确无误,以及邮件管理员是否接受 TCP/IP 连接。”

可能的解决方案

通常,当您收到指示连接建立失败的错误消息时,是因为访问集群的权限或到达集群的网络流量存在问题。

要从集群所在的网络外部的客户端工具连接到集群,请将入站规则添加到集群的安全组中。规则配置取决于是否在 Virtual Private Cloud (VPC) 中创建了 Amazon Redshift 集群:

  • 如果您已在基于 Amazon VPC 的虚拟私有云 (VPC) 中创建 Amazon Redshift 集群,请在 Amazon VPC 中向指定客户端 CIDR/IP 地址的 VPC 安全组添加一条入站规则。有关为集群配置 VPC 安全组和可公开访问的选项的更多信息,请参阅VPC 中的 Redshift 资源

  • 如果您已在 VPC 外部创建 Amazon VPC 集群,则需要将您的客户端 CIDR/IP 地址添加到 Amazon Redshift 中的集群安全组。有关配置集群安全组的更多信息,请参阅Amazon Redshift 安全组

如果您尝试从在 Amazon EC2 实例上运行的客户端工具连接到集群,也需要添加入站规则。在这种情况下,请向集群安全组添加规则。该规则必须指定与客户端工具的 Amazon EC2 实例关联的 Amazon EC2 安全组。

在某些情况下,客户端和服务器之间可能有一个层,例如防火墙。在这些情况下,请确保防火墙接受通过为集群配置的端口的入站连接。

客户端和驱动程序不兼容

如果客户端和驱动程序不兼容,可能会收到“指定的 DSN 包含驱动程序和应用程序之间的架构不匹配”的错误信息。

可能的解决方案

如果您在尝试连接时收到架构不匹配的错误,则说明客户端工具与驱动程序不兼容。此情况是由于其系统架构不匹配导致的。例如,如果您在 32 位客户端工具上安装 64 位驱动程序版本,便会发生这种情况。有时,64 位客户端工具可以使用 32 位驱动程序,但无法在 32 位应用程序上使用 64 位驱动程序。请确保驱动程序和客户端工具使用的是相同版本的系统架构。

查询似乎挂起,有时无法连接到集群

您在完成查询时遇到问题,即在 SQL 客户端工具中,查询显示为正在进行,但实则处于挂起状态。有时,查询无法显示在集群中,如系统表或 Amazon Redshift 控制台中。

可能的解决方案

此问题可能是由于数据包丢失导致的。在此情况下,两个 Internet 协议 (IP) 主机在网络路径中的最大传输单位 (MTU) 大小不同。MTU 大小用于确定可通过网络连接在单个以太网帧中传输的数据包的最大大小(以字节为单位)。在 AWS 中,一些 Amazon EC2 实例类型支持 1500 MTU(以太网 v2 帧),其他实例类型支持 9001 MTU(TCP/IP 巨型帧)。

为避免因 MTU 大小不同可能导致的各种问题,建议您执行以下操作之一:

  • 如果集群使用 EC2-VPC 平台,则使用将返回 Destination Unreachable 的入站自定义 互联网 控制消息协议 (ICMP) 规则配置 Amazon VPC 安全组。因此,该规则指示原始主机沿网络路径使用最小的 MTU 大小。有关此方法的详细信息,请参阅配置安全组以允许 ICMP“无法到达目标”

  • 如果您的集群使用 EC2-Classic 平台,或者您无法允许 ICMP 入站规则,请禁用 TCP/IP 巨型帧以便使用以太网 v2 帧。有关此方法的详细信息,请参阅配置实例的 MTU

配置安全组以允许 ICMP“无法到达目标”

当两个主机在网络中的 MTU 大小存在差异时,请先确保您的网络设置不会阻止路径 MTU 发现 (PMTUD)。PMTUD 使接收主机能够使用以下 ICMP 消息响应原始主机:Destination Unreachable: fragmentation needed and DF set (ICMP Type 3, Code 4)。此消息将指示原始主机在网络路径中使用最低 MTU 大小重新发送请求。若无此协商,当请求过大,导致接收主机无法接收时,数据包可能会丢失。有关此 ICMP 消息的更多信息,请转至 国际互联网工程任务组 (IETF) 网站上的 RFC792

如果您没有为 Amazon VPC 安全组明确配置此 ICMP 入站规则,PMTUD 则将被阻止。在 AWS 中,安全组是虚拟防火墙,用于为到实例的入站和出站流量指定规则。有关 Amazon Redshift 集群安全组的信息,请参阅 Amazon Redshift 安全组。对于使用 EC2-VPC 平台的集群,Amazon Redshift 将使用 VPC 安全组来允许或拒绝到集群的流量。默认情况下,安全组处于锁定状态,会拒绝所有入站流量。有关如何为 EC2-Classic 或 EC2-VPC 实例设置入站和出站规则的信息,请参阅《Amazon EC2 用户指南》中的 EC2-Classic 与 VPC 中的实例间的差异

有关如何向 VPC 安全组添加规则的更多信息,请参阅VPC 安全组。有关此规则中需要的特定 PMTUD 设置的更多信息,请参阅《Amazon EC2 用户指南》中的路径 MTU 发现

配置实例的 MTU

在某些情况下,您的集群可能会使用 EC2-Classic 平台,或者您不能允许对入站流量使用自定义 ICMP 规则。在这些情况下,建议您在从中连接到 Amazon Redshift 集群的 EC2 实例的网络接口 (NIC) 上将 MTU 调整为 1500。此调整将禁用 TCP/IP 巨型帧,以确保连接始终使用同一数据包大小。但是,此选项将从整体上降低实例的最大网络吞吐量,而不仅仅是到 Amazon Redshift 的连接。有关更多信息,请参阅以下流程。

在 Microsoft Windows 操作系统上设置 MTU

如果客户端在 Microsoft Windows 操作系统上运行,则可使用 netsh 命令查看和设置以太网适配器的 MTU 值。

  1. 运行以下命令可确定当前 MTU 值:

    netsh interface ipv4 show subinterfaces
  2. 在输出中查看 MTU 适配器的 Ethernet 值。

  3. 如果值不是 1500,则运行以下命令设置它:

    netsh interface ipv4 set subinterface "Ethernet" mtu=1500 store=persistent

    设置好此值后,重启您的计算机以使更改生效。

在 Linux 操作系统上设置 MTU

如果客户端在 Linux 操作系统上运行,则可使用 ip 命令查看和设置 MTU 值。

  1. 运行以下命令可确定当前 MTU 值:

    $ ip link show eth0
  2. 查看输出中 mtu 后面的值。

  3. 如果值不是 1500,则运行以下命令设置它:

    $ sudo ip link set dev eth0 mtu 1500
在 Mac 操作系统上设置 MTU
  • 请按照 MacOS 支持网站上关于 How to change the MTU for troubleshooting purposes 的说明。有关详细信息,请搜索 支持网站。

设置 JDBC 提取大小参数

预设情况下,JDBC 驱动程序一次收集查询的所有结果。因此,尝试通过 JDBC 连接检索大型结果集时,可能遇到客户端内存不足错误。为使您的客户端按批检索结果集,而不是在单个“要么全部检索,要么失败”提取中检索结果集,请在客户端应用程序中设置 JDBC 提取大小参数。

注意

ODBC 不支持提取大小。

为获得最佳性能,请将提取大小设置为不会导致内存不足错误的最大值。较小的提取大小值会导致更多的服务器通信,从而延长执行时间。服务器会预留资源,包括 WLM 查询槽和关联内存,直到客户端检索到整个结果集或查询取消为止。如果适当优化提取大小,则可以更快释放这些资源,使其能够供其他查询使用。

注意

如果需要提取大型数据集,建议使用 UNLOAD 语句将数据传输到 Amazon S3。使用 UNLOAD 时,计算节点并行工作,以加快数据的传输。

有关设置 JDBC 提取大小参数的更多信息,请参阅 PostgreSQL 文档中的基于光标获取结果