我们使用pecl的memcached(注意D,有2个,memcache和memcached)扩展名连接到memcached 1.4.13盒子集群。
我们注意到发生了大量的 tcpip 重置:
[root@box ~]# netstat -s | grep unexpected
2078913548 connections reset due to unexpected data
[root@box ~]# tcpdump -n -v 'tcp[tcpflags] & (tcp-rst) != 0' -nn
13:30:45.786577 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
LANSUBNET.1.19093 > LANSUBNET.4.999: Flags [R], cksum 0xfad9 (correct), seq 1996582451, win 0, length 0
13:30:45.786697 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
LANSUBNET.1.11540 > LANSUBNET.100.999: Flags [R], cksum 0x904c (correct), seq 2003170685, win 0, length 0
13:30:45.793199 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
LANSUBNET.1.55125 > LANSUBNET.3.999: Flags [R], cksum 0x42c3 (correct), seq 1998297456, win 0, length 0
13:30:45.793389 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
LANSUBNET.1.19112 > LANSUBNET.4.999: Flags [R], cksum 0xa2b5 (correct), seq 1993131641, win 0, length 0
13:30:45.793547 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
LANSUBNET.1.11564 > LANSUBNET.100.999: Flags [R], cksum 0x447c (correct), seq 2003255604, win 0, length 0
13:30:45.817874 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
LANSUBNET.1.55135 > LANSUBNET.3.999: Flags [R], cksum 0x841c (correct), seq 1995200572, win 0, length 0
13:30:45.818549 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
LANSUBNET.1.55141 > LANSUBNET.3.999: Flags [R], cksum 0x385d (correct), seq 1997841357, win 0, length 0
Memcached 绑定在我们所有的 memcached 盒子上的端口 999 上。
我们是否诊断错误?
可能是什么原因造成的?
我们确定的是:
A) 这与 mecached pecl 扩展无关(注意 d,有 2 个扩展...内存缓存和内存缓存)。我们尝试切换到另一个,memcache 扩展,但发生了同样的问题。
B)这实际上是100%由内存缓存连接引起的。我们禁用了 php -> memcached 会话,并且由于 netstat 中的意外数据而重置的连接立即停止增长。
C) 我们在 2 个盒子上出现了这个问题,所以我认为这不是特定于服务器的问题。当我说 2 个盒子时,我的意思是 2 个不同的服务器,与我们的 memcached 集群建立出站连接。它们都位于同一个 LAN 上。
注意:为了安全起见,我们将上面的 LAN 子网更改为"局域网子网"...这是在在此处发布消息之前完成的;)
任何帮助将不胜感激!
谢谢。
更多数据:
[root@box ~]# netstat -s | grep unexpected ; sleep 1 ; netstat -s | grep unexpected ;
2089258664 connections reset due to unexpected data
2089258858 connections reset due to unexpected data
因此,在"不那么忙"的时间,重置似乎以大约 200/秒的速度发生。哎哟!
另外,非常值得一提的是:
我们已执行以下操作:
tcpdump -nn -v 'tcp[tcpflags] & (tcp-rst) != 0' and tcp port not 999
从而过滤端口 999(我们的 memcached 守护程序所在的位置)...并且 tcp 重置缓慢到微小的涓涓细流......一分钟很少,我认为这在相当繁忙的服务中是可以接受的。
我们已经找到了这个问题的完整解决方案。
它是由 memcached pecl 扩展 "Memcached::OPT_BUFFER_WRITES" 常量设置为 true 引起的。
我找到了解决方案。
我怀疑Twitter上的任何人都会读到这篇文章,但如果你是,谢谢你:
Twitter最近(我相信是2012年2月)开源了他们的Memcached Proxy。
https://dev.twitter.com/blog/twemproxy
从本质上讲,所有这些都是memcached协议的基于ip:port或套接字的代理。
您可以将其绑定到 IP:端口或套接字。我们选择了套接字路由。
因此,我们剩下的是一个本地托管的套接字,我们可以从中访问我们的 Memcached 服务器池。
PECL 扩展 memcached 2.0.0b1+ 支持基于套接字的连接。
所以现在一步一步如下:
PHP -> memcached 2.0.2 PECL 扩展 -[本地托管套接字]-> TWITTERS 真棒 MEMCACHED 代理 -[真正持久的连接]-> 内存缓存服务器池
TCP 重置已停止。
值得一提的是:
我们最初尝试绑定 Twitter memcached 代理 127.0.0.1... 即使我们让 Pecl Memcached 与 Twitter 代理通信,我们也看到了 TCP 重置。奇怪!
我想这不是一个"修复"说...但它解决了我们这边的问题。
享受!