EC2上jgroups通道丢失数据包的问题

时间:2014-01-07 21:38:00

标签: java amazon-ec2 udp infinispan jgroups

在尝试在亚马逊的64位Linux AMI上运行的Jgroups 3.1.0-FINAL上设置EC2(大型实例)上的Infinispan时,我们一直看到不一致的网络故障。空缓存启动正常并且似乎工作了一段时间,但是一旦缓存已满,新服务器获得同步会导致缓存锁定。

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

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

# 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 stack。我们在运行时将PING协议替换为我们自己的EC2_PING版本,该版本使用AWS调用来查找其他集群成员候选者。这是一个连接问题。

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

2 个答案:

答案 0 :(得分:5)

  

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

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

缓存同步代码向远程服务器发送大约300k消息,该消息被分段(使用FRAG2)分成4个60k(默认大小)和1个43k数据包,这些数据包被发送到远程盒。由于某些网络限制,远程控制台仅接收 last (5th)43k消息。只有永远的60k消息才会到达。这似乎只发生在某些主机对之间 - 其他对可以与大数据包大小进行良好通信。这不是普遍的是我花了这么长时间来隔离诊断问题。

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

解决方案是将碎片尺寸减小到16k(32k可能没问题,但我们保守了)。对于数据包大小存在一些内部AWS限制,因为它们围绕亚马逊的虚拟网络传输,该网络正在过滤大于5万的大型UDP数据包。默认的Jgroups片段大小(60k)是大IMO,可能应该减少到32k或者其他东西。

我们向亚马逊提交了这张票,他们承认了这个问题,但一般的回答是他们很难修复。我们调整了片段大小并且正在工作,因此票据已关闭。从机票上引用:

  

来自:亚马逊网络服务

     

这是案例XXXXXXXXX的更新。我们目前仅限于Amazon EC2上32k及以下的数据包大小,并且可以确认您遇到的更大数据包大小的问题。我们正在研究这种限制的解决方案。如果您的数据包大小低于此级别,或者这是严重阻碍您操作的问题,请告知我们。

     

我们正在积极寻求增加数据包大小以及其他平台改进,并对此造成的不便表示道歉。

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

希望这有助于其他人。

答案 1 :(得分:1)

如果不在答案中添加任何元素,我想添加另一种检测相同问题的方法。

我不是tcpdump专家,然后我通过调试和记录分析了这个问题。

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

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

  

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

     

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

最后,缺少#20的客户端通常完成(即使从未收到#20),也没有说什么。