15年
网站建设经验
佳速互联
佳速观点

当前位置:首页 >> 常见问题 >> 阿里云OCS超时问题的分析与解决

阿里云OCS超时问题的分析与解决

编辑:深圳网站建设   来源:佳速互联   浏览量:正在读取   时间:2014-10-08

之前有用户联系我们阿里云,反映在使用OCS时会出现超时错误,希望我们阿里云技术团队能够帮忙解决。通常用户会将热点数据存放到OCS中,用以提高用户的业务处理响应速度,因此超时问题对于OCS来讲非常敏感,这引起了阿里云OCS团队的重视,随即开始了调查分析。

 

对于一个网络服务,通常导致超时的原因包括:网络抖动、CPU某个核心负载过高、内存不足导致的频繁swap、网卡负载过高、协议BUG导致的回包有误。通过分析,我们发现了客户端自身存在的某些问题导致OCS超时;除此之外,进一步的分析表明在某些特殊情况下OCS自身的一些问题也会导致超时。下面我们来看看阿里云OCS团队的工程师们是怎么样分析并解决这些超时问题的。

 

在进入技术细节分析之前,先简单介绍一下阿里云OCS的大致工作机制:基于Memcached协议的用户请求从阿里云ECS服务器上发出,通过阿里云SLB(负载均衡)连到阿里云OCS的前端proxy,再连接后端底层的服务器集群进行最终处理。

 

对于超时问题,我们最先考虑问题可能在于客户端到SLB,SLB到proxy之间的网络及协议问题。为了直观分析排查问题,在考虑proxy承受能力之后,我们建议用户不经过阿里云SLB直接连我们的proxy,这样可以直接在服务器抓包了解异常情况时的报文交互,同时也排除了SLB可能出问题的干扰。

在用户将自己的服务器切到我们的proxy上后,我们对每个客户端抓包,其中一台的报文如下:

{67DE13B6-1281-484F-81C1-5830469A6910}

我们看到截图片段中有两个客户端给proxy的回报,超过了200ms,这说明客户端负载有问题,经过与用户确认这一情况得到了证实。由此我们知道:某些情况下使用OCS出现超时是用户客户端负载问题导致,只要合理配置客户端就能解决此类问题。

 

接下来我们进一步调查发现,另外还有一些超时是因为阿里云OCS自身的原因导致的。阿里云OCS对于存储数据的大小是有限制的,即Value最大为1MB。若超出此限制,客户端会收到“Value too large”的错误信息。某些OCS超时错误恰恰是这个尺寸大小导致的。上文提到OCS的处理流程是proxy调用底层后端服务,我们分析OCS代码发现底层后端代码中对报文Value长度的限制是 1000 * 1000字节,而proxy层根据memcached协议是1024 * 1024字节。这种不一致导致当客户端发送的Value长度处于1000 * 1000 ~ 1024 * 1024字节的临界区间时, set eplaceadd操作没有任何信息返回,即没有response;而客户端会一直等待这个response,直到抛出超时异常。虽然是个看起来很初级的BUG,但由于它仅在某些特殊情况下出现,所以定位它还是花了一点时间。找到了这个问题,解决起来就容易了。

 

解决了上述客户端负载和尺寸检测BUG的问题,仍有另外的用户给我们报告OCS超时问题。莫非还有其他的原因?

对于新出现的这些超时情况,我们还是采取在客户端抓包的办法,看到的数据如下:

{CDDE6712-1043-4F8D-9892-0E57F60A924C}

从图中可以得知,客户端10.162.108.239到OCS服务器端10.160.124.220的连接在18:06分开始休眠到18:41被唤醒,发起一次Get请求;之后客户端经历多次重试后,TCP才知道连接已断。这期间客户端未从服务器端收到任何报文。

上文提到过,用户的请求要通过阿里云SLB(负载均衡)连到阿里云OCS的多台proxy,再连接后端底层的服务器集群。所以我们考虑是否存在SLB导致超时问题的可能性。

 

经过与阿里云SLB部门的同学沟通得知,SLB会断开15分钟未活跃的连接,且不会给客户端和服务器发任何FIN或RST报文。这样就可能出现一个问题,即客户端和服务器都认为连接正常。然而当客户端应用层发起一个请求时,该请求被交至TCP层,而TCP层不知道此时链接已经断开,于是重发该请求数次,直到应用层的超时时间到,就返回Timeout。在某些极端情况下,如果应用层没有设过期或者过期时间非常长,就会一直等到TCP层超时才会返回。

 

在得知了SLB的这个情况后,为了绕开这个问题,我们在OCS服务器上设置了TCP层的keepAlive包。将/proc/sys/net/ipv4/tcp_keepalive_time由默认的7200s改为450s一次。接着我们做测试,客户端连接到OCS服务器上,然后抓包如下:

{91D82219-9995-4403-8E09-27E7017B2668}

 

图中显示在20:58分时,服务端TCP层触发keepalive包,但始终不能发出去。即客户端依然收不到任何信息。在客户端同时抓包,抓不到任何来自服务器11211端口的KeepAlive报文。接下来我们查看客户端的netstat状态如下:

{E5068D42-AE70-4B45-9D52-C821B526828E}

即客户端依然认为自己还处于连接状态,因为没有收到服务器的任何消息。如果此时用户发起请求,仍然会得到最初用户反馈的现象,即继续重传直至超时。

 

看来这个问题还没有解决。我们继续分析,考虑到一个可能性:我们阿里云OCS的客户端都是跑在阿里云ECS上,会不会这里有什么情况?

 

于是我们与阿里云ECS团队的同学沟通了解到:ECS上开启了netfilter,其中一条过滤规则是对于空闲时间大于180s的连接,netfilter会将它从established表中剔除,且不会通知客户端服务器,当客户端或者服务端还在该链接上面发送报文时,NODE将不再转发。

 

至此情况大致明朗了:因为是通过ECS和SLB建立的连接,而ECS和SLB对于连接空闲时间都有各自不同的限制,所以可能出现OCS服务器与客户端之间的KeepAlive包丢失,从而导致超时情况的发生。于是我们把OCS服务器的KeepAlive改为90s,绕过SLB、ECS,启动应用再重新测试,问题解决。

 

 

表面上看起来同样都是OCS超时的问题,其真正的原因却是各不相同。我们在这里描述起来看似很轻松,但是在实际工作中能够迅速及时的解决这些问题却绝非易事。有的很容易就被发现解决,有的原因找起来却是破费脑筋。通过我们阿里云工程师们的努力,能够让用户更好的使用阿里云服务,这是我们工作最大的乐趣和价值所在。



友情链接: 阿里云小店 找商网 阿里云金牌合作伙伴 深圳阿里云服务器 长沙网站建设 深圳百度爱采购推广 深圳万网空间 深圳做网站 响应式网站建设 宝安做网站 深圳设计网站 阿里云ICP备案 宝安网站建设 南山网站建设 深圳营销型网站建设 深圳品牌网站建设 深圳微信网站建设 西乡网站建设 外贸网站建设
深圳网站建设
13723486509