5

当尝试在 Amazon 的 64 位 linux AMI 上运行的 Jgroups 3.1.0-FINAL 上在 EC2(大型实例)上设置 Infinispan 时,我们一直看到不一致的网络故障。一个空的缓存开始正常并且似乎可以工作一段时间,但是一旦缓存已满,一个新的服务器正在同步导致缓存锁定。

我们决定推出自己的缓存,但看到的行为大致相同。在同步期间交换了 10 兆字节,但它们没有被淹没。在应用程序级别有一个来回数据 - > ack 对话,但看起来有些消息永远不会到达远程。

在查看 UNCAST 跟踪记录时,我看到以下内容:

# my application starts a cache refresh operation 
01:02:12.003 [Incoming-1,mprewCache,i-f6a9d986] DEBUG c.m.e.q.c.l.DistributedMapManager - i-f6a9d986: from i-d2e29fa2: search:REFRESH 
01:02:12.003 [Incoming-1,mprewCache,i-f6a9d986] INFO  c.m.e.q.c.l.DistributedMapRequest - starting REFRESH from i-d2e29fa2 for map search, map-size 62373 
01:02:12.003 [Incoming-1,mprewCache,i-f6a9d986] DEBUG c.m.e.q.c.l.DistributedMapManager - i-f6a9d986: to i-d2e29fa2: search:PUT_MANY, 50 keyValues 
# transmits a block of 50 values to the remote but this never seems to get there 
01:02:12.004 [Incoming-1,mprewCache,i-f6a9d986] TRACE o.j.p.UNICAST - i-f6a9d986 --> DATA(i-d2e29fa2: #11, conn_id=10) 
# acks another window 
01:02:12.004 [Incoming-1,mprewCache,i-f6a9d986] TRACE o.j.p.UNICAST - i-f6a9d986 --> ACK(i-d2e29fa2: #4) 
# these XMITs happen for over and over until 01:30:40 
01:02:12.208 [Timer-2,mprewCache,i-f6a9d986] TRACE o.j.p.UNICAST - i-f6a9d986 --> XMIT(i-d2e29fa2: #6) 
01:02:12.209 [Timer-2,mprewCache,i-f6a9d986] TRACE o.j.p.UNICAST - i-f6a9d986 --> XMIT(i-d2e29fa2: #7) 
01:02:12.209 [Timer-2,mprewCache,i-f6a9d986] TRACE o.j.p.UNICAST - i-f6a9d986 --> XMIT(i-d2e29fa2: #8) 
...

这是我们的Jgroups 堆栈。我们PING在运行时将协议替换为我们自己的EC2_PING版本,该版本使用 AWS 调用来查找其他集群成员候选者。这不是连接问题。

任何想法为什么某些数据包没有到达目的地?

4

2 回答 2

5

任何想法为什么某些数据包没有到达目的地?

这是一个有趣的问题。它似乎对某些 EC2 实例的影响比其他实例要大得多。问题在于通过 UDP 在 EC2 实例之间发送大数据包。

缓存同步代码向远程服务器发送约 300k 的大消息,该消息被分段(使用 FRAG2)分成 4 个 60k(默认大小)的数据包和 1 个 43k 的数据包,发送到远程盒子。由于某些网络限制,远程盒子仅接收最后(第 5 个)43k 消息。60k 条消息永远不会到达。这似乎只发生在某些主机对之间——其他对可以在大数据包大小的情况下正常通信。它不是普遍的,是我花了这么长时间才隔离诊断问题的原因。

我最初认为这是一个 UDP 接收器窗口大小问题,并试图调整它(sysctl -w net.core.rmem_max=10240000)但这没有帮助。查看 tcpdump 显示 60k 数据包没有到达远程主机。只有 43k 数据包是。

解决方案是将片段大小减小到 16k(32k 可能很好,但我们比较保守)。数据包大小在 AWS 内部存在一些限制,因为它们在 Amazon 的虚拟网络中传输,该网络正在过滤可能超过 50k 的大型 UDP 数据包。默认的 Jgroups 片段大小(60k)是大 IMO,可能应该减少到 32k 或其他东西。

我们向亚马逊提交了一张票,他们承认了这个问题,但普遍的反应是他们很难解决。我们已经调整了片段大小并且正在工作,因此票已关闭。从票中引用:

来自:亚马逊网络服务

这是案例 XXXXXXXXX 的更新。我们目前在 Amazon EC2 上限制为 32k 及以下的数据包大小,并且可以确认您面临的更大数据包大小的问题。我们正在研究解决此限制的方法。请让我们知道您是否可以将数据包大小保持在此水平以下,或者这是否是阻碍您操作能力的严重问题。

我们正在积极考虑增加数据包大小以及其他平台改进,并对由此带来的不便深表歉意。

关于 EC2 的其他一些评论。首先,我们看到同一可用区中的主机需要大于 8 的 TTL。如果您使用多播,请确保您的 TTL 设置为 128 或其他值。我们最初认为这是问题所在,但最终不是。

希望这对其他人有帮助。

于 2014-01-07T21:40:17.887 回答
1

在不向答案添加任何元素的情况下,我想添加另一种检测相同问题的方法。

我不是 tcpdump 专家,然后我分析了调试和日志记录的问题。

在我们的例子中,一条消息被分成许多较小的数据包(给定 FRAG2 的 frag_size 参数)。其中一些(不一定是最后一个)随机未传输:通常,数据包 1 到 19 被正确传输,21 个被传输但 20 个丢失。

随后是两个实例之间的大量往返:

客户端会丢失 #20 包,它再次确认 #19 并请求 20;服务器将发送明确请求的 #20 和尚未确认的 #21

缺少#20 的客户端将收到#21(但不是#20)、重新确认#19、重新询问#20 等等,持续时间从 1 秒到 50 秒。

最后,缺少#20 的客户端通常会完成(即使从未收到#20)而无需说什么。

于 2014-04-24T12:18:55.243 回答