如果说2013年云计算之路的主题是“踩坑”,那么2014年我们希望云计算之路的主题变成“填坑”——当然填坑是阿里云来完成的,我们只是见证曾经的坑坑洼洼变成平坦大道。
15号(周四)晚上我们发现了SLB会话保持的坑,16号晚上阿里云成功定位并进行修复,这两天正式发布后会填平这个坑。这次从踩坑到填坑的过程是最痛快的一次。
接下来我们的目标锁定在“黑色n秒”(刚发现一个英文说法:stuck for x seconds)这个坑我们最多、最神秘、最诡异的坑。
受“云计算之路:2009年Xen一个补丁背后那不为人知的故事”一文的启发,在这篇博文中,我们要对“黑色n秒”的原因做出一个最大胆的猜想,也希望是最终猜想!我们的猜想是——我们遇到的“黑色n秒”问题,不管是黑色10秒、30秒、1秒、5秒还是这两天刚刚发现的0.5秒,都是背后同一个原因在不同触发条件下的不同表现。
那这个背后的原因是什么呢?如果用最简单的话来表达,就是CPU睡过头了。如果哆嗦一点,就是CPU的某个核因为空闲进入睡眠状态(C-states),后来需要它工作时,Xen想借助另一个CPU核来唤醒它,结果由于某种未知因素造成睡眠中的CPU核没被唤醒或者负责唤醒的CPU核偷懒了。此时此刻,黑色n秒就开始了,只至睡眠中的CPU核被外部中断唤醒。
从这个猜想中可以看出,如果所有的CPU核都在忙碌,就不会触发这个问题。是的,当我们得到这个猜想时,有点哭笑不得——之前由于遭遇CPU跑高、CPU波动问题,本来4核就够了。我们特地买了8核,通常有4个核都闲着,从而更容易触发这个问题。
那换成4个核是不是会解决问题呢?不会,只是发生的频率会低一些,因为网站访问有高低峰,在低峰时也会有CPU核闲下来。
那有没有办法从根本上避开这个问题?有!目前为止我们发现一个唯一的解决方法,就是——坚决不让CPU进入睡眠状态,即使没活干,也要呆着随时待命。要实现这个,需要进入物理机的BIOS关闭CPU的C-states。而为此要付出的代价是支持电力事业的发展。
你也许会问这个最终猜想及解决方法究竟靠不靠谱呢?请看下面3个在网上发现的案例。
第一个案例:Citrix论坛上的一个帖子——Xenserver 6.2 intermittent ping response delays
用的是DELL R820+XenServer 6.2,遇到的问题是:ping虚拟机有时会出现响应时间高达500ms左右的异常情况(在时间点上与我们遇到的“黑色0.5秒”对应)。
Intermittently we see a large response time and followed by the normal response time <1ms, this gradually decreases from 500ms back to 1ms then jumps to 500ms and starts decreasing again.
后来是通过进入这台机器的BIOS禁用C1E和C States解决的:
Manged to resolve this by making the following changes on the R820 BIOS:
System BIOS Settings -> System Profile Settings
Changed C1E to Disabled
Change C States to Disabled.
这个案例中最值得关注的地方是所用的物理服务器是DELL R820,CPU是Xeon E5-4600;而我们用的阿里云云服务器的物理机的CPU是Xeon E5-2630。虽然型号有差异,但都是Ivy Bridge架构,更关键的是电源管理功能是一样的,用的都是Intel Turbo 2.0(详见这里)。所以我们推测,如果E5-4600在电源管理上存在缺陷,那么E5-2630也同样存在,该案例中所用的禁用C1E和C States的方法也可能也适用于我们的场景。
第二案例:Citrix支持中心的一篇文章——Hosts Become Unresponsive with XenServer 5.6 and above on Nehalem and Westmere CPUs
用的是Nehalem与Westmere架构CPU+Xen Server 5.6,遇到的问题是虚拟机随机死锁,问题通常发生在CPU长时间处于空闲状态(空闲的结果自然是进入睡眠状态)之后:
Hosts that are experiencing this issue will often have been largely idle for a period leading prior to the lockup.
也是通过在BIOS中禁用C-states(同时也禁用了Turbo Mode/Turbo Boost option)解决的。
To resolve the issue, complete the following procedure:
- In the BIOS menu, set the value for the C-states option to Disabled.
- In the BIOS menu, set the value for the Turbo Mode/Turbo Boost option to Disabled.
- If the server BIOS has power management options that leave power management to the BIOS rather than the operating system, such as Dell's Active Power Controller or HP’s Power Regulator, also disable this by setting the power management option to OS Control.
这个案例中,最值得关注的是文章中的Problem Cause部分,文中说Nehalem与Westmere CPU架构引入了新C-states特性,但存在缺陷,文中所遇到的问题就是这个缺陷引起的。
但我们所用的Xeon E5-2630不是这两个CPU架构,不受这个缺陷影响。但从中可以知道物理CPU在电源管理上的缺陷是会引起虚拟机死锁问题(黑色n秒也可以说成是死锁)。
第三个案例:stackexchange上的一个问答——BUG: soft lockup - CPU# stuck for x seconds
用的是亚马逊AWS EC2(也是Xen)+CentOS,遇到的问题是某个进程会卡住10秒或者更长时间,与我们遇到的黑色10秒很相似。
这位提问者最终没有说是如何解决这个问题的,但回复中有人说
Disabling c-states worked for me. – Andrew
我们猜测这位回复者遇到了类似问题,并通过禁用C-States解决了。
从这个案例,我们进行了这样一个推测: stackexchange上的这个问题是在2013年5月27日提出的,亚马逊AWS EC2的虚拟机环境与阿里云ECS的虚拟机环境很接近,EC2上出现的这个问题在ECS上重演的可能性很大,而我们遇到的黑色n秒问题可能就是一种重演。既然有人通过禁用C-states解决了问题,我们为什么不尝试一下呢?
【我们的尝试】
我们的尝试是在虚拟机中在Windows层面禁用CPU C-states,但前提条件是物理机在BIOS中设置了将CPU电源管理控制权交给操作系统。想想这个可能性太小了,因为一台物理机中跑着多台虚拟机,如果控制权交给了操作系统,假如这台虚拟机禁用了C-states,那台虚拟机没有禁用,CPU该听谁的。
虽然可能性微乎其微,我们还是要试试。我们通过在Windows注册表中添加一个针对CPU的Capabilities项禁用了C-states(来自superuser):
reg add HKLM\System\CurrentControlSet\Control\Processor /v Capabilities /t REG_DWORD /d 0x0007e066
但测试结果显示,黑色n秒问题依旧。于是,只剩下唯一的希望。
【唯一的希望】
现在唯一能验证我们的最终猜想、唯一能解决“黑色n秒”问题的希望就是——进入物理机的BIOS,禁用CPU C-states。
【更新】
从阿里云得到的最新消息,物理机的BIOS是关闭C-states的,我们的最终猜想失败。
接下来唯一的希望就寄托于阿里云对这个问题的继续研究。