热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

云计算之路-阿里云上:“黑色1秒”问题与2009年Xen一个补丁的故事

在之前对“黑色1秒”问题的分析博文中,我们将最大嫌疑对象锁定在了Xen,在这篇博文我们将从Xen的角度进行分析。也许有人会问,为什么不知道天多高地多厚地去研究不属于自己范围的问题?只因我们对一个问题的

在之前对“黑色1秒”问题的分析博文中,我们将最大嫌疑对象锁定在了Xen,在这篇博文我们将从Xen的角度进行分析。也许有人会问,为什么不知道天多高地多厚地去研究不属于自己范围的问题?只因我们对一个问题的强烈好奇心——究竟是不是我们用Windows的错?

(注1:文中所说的Xen补丁问题只是提供一种分析问题的思路,我们遇到的“黑色1秒”问题与有没有打这个补丁没有关系)

(注2:关于这个Xen补丁背后的故事,推荐阅读阿里云分享的博文:云计算之路:2009年Xen一个补丁背后那不为人知的故事)

2009年3月20日,来自Intel的Yu Ke通过Xen-dev Mailing List给来自Citrix的Keir Fraser(负责的Xen开发者之一)发了一封邮件,提交了Xen的一个patch——cpuidle: suspend/resume scheduler tick timer during cpu idle entry/exit.

这个补丁的用途是什么呢?

cpuidle can collaborate with scheduler to reduce unnecessary timer interrupt. For example, credit scheduler accounting timer doesn't need to be active at
idle time, so it can be stopped at cpuidle entry and resumed at cpuidle exit. This patch implements this function by adding two ops in scheduler:
tick_suspend/tick_resume, and implement them for credit scheduler.

上面的文字是邮件中的第一段内容,大意是:Xen中的cpuidle(在物理CPU没有被给分配VCPU时,cpuidle可以让物理CPU进入C-state,好处之一是省电,详见这里)可以与CPU调度器(负责CPU的调度,关于Xen中的CPU调度,详见这里)一起协作从而减少不必要的时钟中断。比如,当CPU空闲时,credit scheduler(Xen中的一种CPU调度算法,详见这里)的accounting timer就没有继续工作的必要,所以可以让它在cpuidle时停止工作,在退出cpuidle时再唤醒它。这个patch通过添加tick_suspend/tick_resum这两个调度器操作来实现这个。

简而言之,这个补丁的用途是——在CPU空闲时,让调度器也休息;当CPU工作时,再把调度器唤醒。

应该这个补丁会带来什么好处呢?

With this patch, under idle scenario, timer interrupt frequency decreased from ~100HZ to ~10HZ, and average C state residency increase from ~10ms to larger than 100ms. Also in a two-socket machine, about 4% idle power saving is observed.

上面的文字是文字是邮件中的第二段内容,大意是:用了这个补丁,在CPU空闲场景下,时钟中断频率由~100HZ减少到~10HZ,平均的C状态(CPU的电源管理状态,详见这里)停留时间从10ms增加到100ms(看到这让我们想到“黑色0.1秒”)。在有2颗CPU的机器上,从观察情况看,可以节省4%的电量。

简单言之,这个补丁的好处是——省电。

这个补丁的临床试验情况怎么样?

However, one issue is observed with this patch, i.e. there is soft-lockup in dom0 occasionally. This issue is still under debugging. Currently we already find a >1s VCPUOP_set_singleshot_timer timeout, which imply this may be a dom0 issue. we are working hard to figure the root cause.

上面的文字是文字是邮件中的第三段内容,大意是:应用这个补丁后,观察到一个症状。在dom0(Xen中的特权虚拟机,“内部包含了真实的设备驱动,可直接访问物理硬件”)中偶尔会出现软死锁(soft-lockup),而且发现大于1秒的VCPUOP_set_singleshot_timer(详见Xen的domain.c代码)超时的情况,这暗示了dom0中可能藏着某个坑。

注意!这里的1秒!这个“1秒”与“黑色1秒”中的“1秒”,是偶然的巧合,还是本是同根生?这个地方是一个非常重要的线索,让我们看到了走出“黑色1秒”最有希望的一线光明。

继续看这封邮件中接下来的内容:

Considering the very visible effect of this patch, and the issue mentioned above only occurs when cpuidle is enabled, and has no impact to normal user, we
finally decide to send out this patch to see if it is possible for 3.4 inclusion. In the bug fix phase, we will send out bug fix for the issue.

大意是:考虑到这个补丁诱人的省电效果(省电就是省钱啊),而且上面提到的问题(疑似黑色1秒)只在启用cpuidle的情况下发生,不会影响到正常普通用户(这地方有点疑惑,什么才是普通用户?),最终决定发出这个补丁(似乎缺少了一点不放过任何一个问题的偏执)。

接下来我们看看负责向Xen提交代码的Keir Fraser的回复:

I don't really want to take the patch while it is soft locking up. I would expect linux-2.6.18-xen.hg:22 to avoid lockup warnings due to too long
singleshot timeouts (I assume you are testing with the 2.6.18 tree?).

Personally I would rather have cpuidle be enabled by default (or even always with no disable option) and get existing Cx benefits for everyone, rather
than have a slightly broken cpuidle option.

Is there a reason not to turn on cpuidle by default now? Or even enable and
then remove the boot option?

还好Keir Fraser不愿放过这个小问题,他希望解决软死锁问题之后再发布这个补丁,而且他希望默认开启cpuidle。这里可以看出Keir Fraser坚持的原因,如果默认开启cpuidle,这个问题的影响就会很大。

再看一下Yu Ke紧接着的回复:

Right, I am testing it with 2.6.18 tree. I am also looking into the dom0 code, to see if should change dom0.

There is no obvious obstacle to turn on cpuidle by default. According to our testing and measurement, cpuidle is pretty stable now, maybe it is time to enable it by default.

Keir Fraser的坚持打动了Yu Ke,决定寻找并填掉这个坑,并且他也希望默认开启cpuidle。

那Yu Ke究竟有没有找到这个坑,有没有填平这个坑?

去哪里寻找答案?我们想到了Xen的git日志:

xen git日志

2009年3月31日,Keir Fraser向Xen代码库提交了Yu Ke完成的补丁代码。在这个提交中,只字未提坑的事。

这个坑究竟有没有被填平呢?照之前Keir Fraser的性格,应该不会有让有坑的代码提交上去。所以,我们更关注的是这个坑究竟是怎么被填平的?

于是,我们又回到Xen-devel mailing list中寻找。。。

终于找到了:[Xen-devel] [PATCH] cpuidle: suspend/resume scheduler tick timer during cpu idle entry/exit V2 - msg#01762!

2009年3月26日Yu Ke向Keir Fraser发了一封邮件并提交了填好坑的代码:

Hi Keir,

This attached is the version 2 of the patch. The major update is fixing the soft-lockup issue.

The root cause is: sched_tick_suspend will call __stop_timer and may raise TIMER_SOFTIRQ if the timer deadline is changed. In this case, the assumption of
no softirq pending in acpi_processor_idle is broken, and later the hpet broadcast wakeup IPI will not be delivered to this CPU, since its softirq pending bit is set. Then the CPU will be sleeping until random external interrupt happen. To fix this issue, the sched_tick_suspend is moved before the softirq pending bit checking, to keep the assumption correct.

I also measure the performance by SPECJbb in dom0, no performance degradation observed.


Best Regards
Ke

原来Yu Ke遇到的“黑色1秒”问题的原因是这样的:

前面我们说过这个补丁的用途是在CPU空闲时,让调度器也休息;当CPU工作时,再把调度器唤醒。让调度器休息调用的是sched_tick_suspend(),而sched_tick_suspend则会调用_stop_timer(),如果这时时钟(Timer)的时间戳被改变,会触发TIMER_SOFTIRQ(时钟软中断,欲了解软中断的知识,详见这里),而坑就是这个软中断造成的。

开始的补丁代码是这样的:

if ( softirq_pending(smp_processor_id()) )
    do_softirq();

sched_tick_suspend();
//...

开始的softirq_pending代码就是为了处理软中断,之后的代码就认为不会再出现软中断,可是在执行sched_tick_suspend()时在某种条件下(比如时钟时间戳被改变)会触发软中断,造成softirq pending bit被设置了值;当CPU由空闲状态进入工作状态时(比如某个线程被调度到该CPU执行),系统会发出hpet(High Precision Event Timer)广播唤醒IPI(Inter-processor interrupt)从而唤醒CPU,但由于当时处于softirq pending状态,hpet到达不了这个CPU,于是CPU没有被唤醒,继续悠闲着。而那个需要被执行的线程只能傻傻地等着,直到CPU被外部的中断唤醒。

打个比方来说明一下CPU的这种状态。你中午吃过饭闲着没事想睡会觉,于是在iPad定了一下闹钟就开始睡觉;但是一个同事在你睡觉的时候把iPad设置为了静音,结果闹钟准时工作了,你却听不到,继续做着美梦直到有人叫你或打你手机,你才开始干活。

由此,我们联想到,我们遭遇“黑色1秒”问题时,CPU很可能处于同一种状况。HTTP.SYS的一个线程被调度到一颗空闲的CPU核,系统给美梦中的CPU发了一个通知——“快起床,开始快活啦!”,结果某种原因造成CPU没收到,继续美梦。而HTTP.SYS的线程只能傻等着,直到1秒后,有人直接去敲CPU的门把CPU叫醒,于是CPU开始忙活起来。

这时你也许会问,如果真是这样的话,那只会造成当时线程卡住。为什么“黑色1秒”期间,所有的HTTP.SYS线程都会卡住?那是因为HTTP.SYS不是一般人,它运行于Windows的内核模式,我们猜测HTTP.SYS很有可能用到spinlock,所以只要一个线程卡住,所有线程都无法干活(猜测依据的是我们在曾经遭遇的“黑色10秒”期间写的一篇博文,其中有一句话:“SpinLock是在Windows内核级别使用了”)。而如果是用户模式的线程(比如ASP.NET线程),就不会这样。从昨天进一步的监测数据看,在“黑色1秒”期间有时有些ASP.NET线程会卡住,但不会全部卡住。

在之前的分析中,我们有这样的猜想:

黑色10秒,黑色30秒,黑色1秒,黑色5秒。。。就叫黑色n秒吧。不管黑色多少秒,这些都只是问题的表象,而真正的黑色在虚拟机层面,更准确地说就是Xen。

而这一次,我们要作出更更准确的猜想——黑色n秒的问题很可能出在Xen的CPU调度环节。

2009年Xen那个的补丁引发的“黑色1秒”问题的解决方法出人意料地简单——只要把softirq_pending与sched_tick_suspend()的代码调换一下位置,让sched_tick_suspend()先执行。

xen sched_tick_suspend

而对于我们遇到的“黑色1秒”问题,只要阿里云从内心承认是Xen的问题,我们就觉得出人意料了!

不管怎么样,这次是黑色n秒问题最重要的一次突破,同时也让我们遇到了千载难逢的学习Xen的好机会!


推荐阅读
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • 【shell】网络处理:判断IP是否在网段、两个ip是否同网段、IP地址范围、网段包含关系
    本文介绍了使用shell脚本判断IP是否在同一网段、判断IP地址是否在某个范围内、计算IP地址范围、判断网段之间的包含关系的方法和原理。通过对IP和掩码进行与计算,可以判断两个IP是否在同一网段。同时,还提供了一段用于验证IP地址的正则表达式和判断特殊IP地址的方法。 ... [详细]
  • 本文是一篇翻译文章,介绍了async/await的用法和特点。async关键字被放置在函数前面,意味着该函数总是返回一个promise。文章还提到了可以显式返回一个promise的方法。该特性使得async/await更易于理解和使用。本文还提到了一些可能的错误,并希望读者能够指正。 ... [详细]
  • 前段时间做一个项目,需求是对每个视频添加预览图,这个问题最终选择方案是:用canvas.toDataYRL();来做转换获取视频的一个截图,添加到页面中,达到自动添加预览图的目的。 ... [详细]
  • 本文整理了Java中org.gwtbootstrap3.client.ui.Icon.addDomHandler()方法的一些代码示例,展示了Icon.ad ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 本文讨论了在iOS平台中的Metal框架中,对于if语句中的判断条件的限制和处理方式。作者提到了在Metal shader中,判断条件不能写得太长太复杂,否则可能导致程序停留或没有响应。作者还分享了自己的经验,建议在CPU端进行处理,以避免出现问题。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • Python中的PyInputPlus模块原文:https ... [详细]
  • 【爬虫】关于企业信用信息公示系统加速乐最新反爬虫机制
    ( ̄▽ ̄)~又得半夜修仙了,作为一个爬虫小白,花了3天时间写好的程序,才跑了一个月目标网站就更新了,是有点悲催,还是要只有一天的时间重构。升级后网站的层次结构并没有太多变化,表面上 ... [详细]
author-avatar
手机用户2702939047
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有