Blog

平均负载与 CPU 使用率

Content #

既然平均负载代表的是活跃进程数,那平均负载高了,不就意味着 CPU 使用率高吗?

我们还是要回到平均负载的含义上来,平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。

而 CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。比如:

  1. CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
  2. I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
  3. 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。

Viewpoints #

From #

02 | 基础篇:到底应该怎么理解“平均负载”?

三个不同时间间隔的平均负载

Content #

三个不同时间间隔的平均值,其实给我们提供了,分析系统负载趋势的数据来源,让我们能更全面、更立体地理解目前的负载状况。

  1. 如果 1 分钟、5 分钟、15 分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳。
  2. 但如果 1 分钟的值远小于 15 分钟的值,就说明系统最近 1 分钟的负载在减少,而过去 15 分钟内却有很大的负载。
  3. 反过来,如果 1 分钟的值远大于 15 分钟的值,就说明最近 1 分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。一旦 1 分钟的平均负载接近或超过了 CPU 的个数,就意味着系统正在发生过载的问题,这时就得分析调查是哪里导致的问题,并要想办法优化了。

假设我们在一个单 CPU 系统上看到平均负载为 1.73,0.60,7.98,那么说明在过去 1 分钟内,系统有 73% 的超载,而在 15 分钟内,有 698% 的超载,从整体趋势来看,系统的负载在降低。

Viewpoints #

From #

02 | 基础篇:到底应该怎么理解“平均负载”?

查看CPU个数

Content #

grep 'model name' /proc/cpuinfo | wc -l

From #

平均负载

Content #

平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数。

所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。

不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程。

比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制。

因此,平均负载其实就是平均活跃进程数。平均活跃进程数,直观上的理解就是单位时间内的活跃进程数,但它实际上是活跃进程数的指数衰减平均值。这个“指数衰减平均”的详细含义你不用计较,这只是系统的一种更快速的计算方式,你把它直接当成活跃进程数的平均值也没问题。

既然平均的是活跃进程数,那么最理想的,就是每个 CPU 上都刚好运行着一个进程,这样每个 CPU 都得到了充分利用。比如当平均负载为 2 时,意味着什么呢?

  1. 在只有 2 个 CPU 的系统上,意味着所有的 CPU 都刚好被完全占用。
  2. 在 4 个 CPU 的系统上,意味着 CPU 有 50% 的空闲。
  3. 而在只有 1 个 CPU 的系统中,则意味着有一半的进程竞争不到 CPU。

Viewpoints #

From #

02 | 基础篇:到底应该怎么理解“平均负载”?

Latex常用数学符号

单个字符 #

\(\Theta\) Θ \(\Omega\) Ω \(\varepsilon\) ε

\(\cap\) ∩ \(\cup\) ∪ \(\partial\) ∂ 偏微分 \(\nabla\) ∇ 哈密顿算子 \(\forall\) ∀

\(\propto\) ∝ \(\pm\) ± \(\approx\) ≈ \(\doteq\) \doteq \(\nsubseteq\) \nsubseteq

组合字符 #

\(\binom{n}{k}\) \binom{n}{k} 二项系数 \(\lfloor x \rfloor\) ⌊ x ⌋ \(\lceil x \rceil\) ⌈ x ⌉

\(\widehat{\phi}\) \widehat{\phi} \(\overline{x}\) \overline{x} \(\sqrt[3]{8}\) \sqrt[3]{8}

贝叶斯定理三要素

Content #

贝叶斯定理可以准确地量化所观察到的数据改变我们信念的概率。这也就是。简单来说,我们想量化的是:在所观察到的数据下,自己对信念的坚信程度。在贝叶斯公式中,这个要素的术语是后验概率(posterior probability,简称为“后验”),也就是将通过贝叶斯定理所求出的解P(H|D)。

为了得到后验概率,还需要用到下一个要素:似然(likelihood)。它表示在给定信念的情况下,观察到某一数据的概率,也就是P(D|H)。

最后,需要量化初始信念的概率,即P(H)。这一要素在贝叶斯定理中被称为先验概率(prior probability,简称为“先验”),它表示我们在看到数据之前的信念强度。似然和先验结合在一起就会形成后验。

通常情况下,我们需要使用数据的概率P(D)对后验归一化,从而使其值介于0和1 之间。然而在实践中并不总是需要P(D),所以这个值没有特殊的名字。

我们将信念称为假设H,并用变量D来表示数据。 \[P(H|D)=\frac{P(H)\cdot P(D|H)}{P(D)}\]

显然,数据本身或者说数据的概率P(D)没有出现在三要素中,因为如果只关注信念的比较,通常并不需要在分析中用到它。

\[\frac{P(H_1|D)}{P(H_2|D)}=\frac{P(H_1)\cdot P(D|H_1)}{P(H_2)\cdot P(D|H_2)}\]

或者写成: \[P(H|D) \propto P(H)\cdot P(D|H)\]

From #

鼠疫的传播

Content #

鼠疫是由鼠疫杆菌引发的,主要存在于自然界一些啮齿类动物的身体中,这些小动物身上往往会有诸如跳蚤一类的寄生虫。跳蚤吸食了患病宿主的血后,鼠疫杆菌会在跳蚤的前胃棘增生,造成前胃阻塞,这一效应被称为菌栓(Blocking)。有菌栓的跳蚤由于前胃被堵住了,吸食的血液便很难进入胃里被消化,这让跳蚤始终处于饥饿之中,于是更加疯狂地吸血。当这些跳蚤吸食家鼠或者人类的血液时,血液会在跳蚤体内与鼠疫杆菌混合,之后再回到宿主血管里,造成新的宿主感染,这就是鼠疫传播的基本原理。

通常来说,各类啮齿动物和它们身上的寄生虫往往距人类生活区域较远,如中国北方一些荒漠草原地带,在这些地方,鼠疫杆菌会局限在特定范围内传播,形成“鼠疫自然疫源地”。然而,随着农耕区人口压力的增大,粮食越来越匮乏,为了填饱肚子,一些农业人口迫于匮乏的压力而被挤压到新的环境里开荒,这种行为便无意中打破了“鼠疫自然疫源地”的平衡。

鼠疫向人类社会扩散的途径主要有两种,第一种是关于家鼠的,家鼠和开荒的人类一起迁移到新地之后,会和当地啮齿类动物接触,这些家鼠也就会因此被跳蚤叮咬而感染鼠疫杆菌。家鼠和人类的关系一向密切,当它们回到自己的住所时,带回的跳蚤便可能叮咬人类,人类聚居区内的广泛传播也就开始了。

第二种传播途径是关于人类自身行为的,在一些“鼠疫自然疫源地”,会有一些啮齿类动物在巢穴里贮藏一些诸如谷物和草籽之类的食物,如果当地发生了饥荒的话,粮食的匮乏会把一些灾民逼入绝境,他们就会去挖掘啮齿类动物的贮粮以填饱肚子,在挖掘巢穴的过程中极有可能被跳蚤叮咬而感染鼠疫杆菌。此外,还有一些因病而死的啮齿类动物会被饥饿的灾民捡食,这也是重要的传染途径。如果再有四处征战的军队进入疫区,那横扫全国多个省份的鼠疫疫情就会随之而起,明朝末年正是这样。

From #

进击的智人

瘟疫肆虐与环境稳态

Content #

美国芝加哥大学荣誉退休教授威廉·H.麦克尼尔(William H.McNeil)曾经在自己的著作《瘟疫与人》中提到一个观点:某个地区之所以会有瘟疫肆虐,很可能是因为该地区之前的环境稳态被破坏了,病原体与人畜之间的关系失去了平衡,瘟疫就会爆发,感染并且杀死大量的宿主,直到环境形成新的稳态为止。这个理论在明朝末年得到了充分的验证。17世纪中叶,交通水平低下,明朝百姓长期生活在一个相对较小的范围内,对局部地区的微生物环境已经产生了适应性,而当旱灾和蝗灾接连洗礼某个地区之后,人们便不得不逃到其他地区,人口的大量流动会搅动各地微生物环境的平衡,为传染病的大规模扩散提供了绝佳的条件。

除此之外,当粮食出现歉收或者绝收时,人们不得不拓宽自己的食谱以求活命,将一些平时不会食用的东西变成食物,比如一些啮齿类动物,其中染了病的动物更容易被捕捉和捡食。原本已经因为饥饿而免疫力低下的人再接触这些病菌的载体,便很容易被感染,其根本原因在于食物的匮乏,因此,相当大的一部分疫情是伴随着旱灾和蝗灾出现的。1640—1641年,常有灾害与瘟疫伴生的现象出现。明末的山东、安徽等地,除了深陷饥荒,还有过半的民众死于恐怖的瘟疫,如枣一般大的绿苍蝇漫天飞舞,遮天蔽日。

From #

进击的智人

缺锌与收继婚

Content #

复旦大学历史地理学博士高凯曾经对北方游牧民族生活的一些地区进行了详细的调研,他发现,这些民族生活的地区由于受到纬度、降雨、成土母质等因素的影响,人体常会缺乏一种微量元素——锌。

人体内含有40多种元素,其中常量元素占身体的99.9%以上,而微量元素所占比例微乎其微,虽然微量元素的比例很小,而且锌元素仅是14种微量元素中的一种,但是它所起到的作用却是极其重要的,几乎参与身体运行和发育的方方面面。在人体内,有200多种酶、核酸和蛋白质的合成与锌有关,妇女怀孕后,其对锌元素的需求量比非孕期妇女的需求量高出将近一倍,这是因为胎儿的发育、生长有赖于细胞的不断增殖,在这个过程中,DNA复制时所需要的酶以及RNA转录时所需要的酶都是含锌的,如果缺乏锌元素,胎儿几乎无法正常生长。胎儿的脑部是含锌量最高的一个器官,每1克脑组织中含锌量约为10微克,远远高于其他微量元素的含量,如果孕妇在孕期未能摄入足量的锌,那么胎儿就可能出现神经系统发育畸形的症状,甚至一出生就成为无脑儿。

锌元素的缺乏不仅对婴儿有着致命的影响,对孕妇也是如此,缺锌的孕妇很可能会出现羊水早破、分娩并发症、染色体畸形、免疫力下降等问题。可以说,锌元素的摄入水平直接决定了女性是否能够正常生育,如果锌元素摄入不足,孕妇的死亡率就会随之暴增。

那么锌元素从何而来呢?其实是从环境中来的,土壤中的锌元素会通过饮食进入人体循环,但是如果土壤中原本就缺乏锌元素,就会很麻烦。匈奴和鲜卑等北方游牧民族长期生活在高纬度内陆地区,其绝大部分土壤是缺乏锌元素的,再加上北方游牧民族的饮食中通常含有大量的肉食,而肉食中的铜元素在被人体吸收时会和锌元素相互拮抗,也就是说,摄入大量肉食会在一定程度上阻碍锌元素的吸收,使得匈奴和鲜卑族的妇女长期处于严重缺乏微量元素锌的状态。考古学者通过分析这一时期出土的一些骨骸,并进行化验,证实了这一结论。

上文提到,锌元素的缺乏会大大提高孕妇在分娩时的死亡率,这使得历史上北方游牧民族社会中孕龄妇女大量死亡,进而出现严重的男女比例失衡。所以在当时北方游牧民族的观念中,可以顺利生育的妇女对于一个家庭来说是非常宝贵的财富,是不可以轻易流散到家族以外的。

高凯博士推测,正是为了防止人口崩溃和民族灭绝,同时也为了家族血脉的延续,收继婚的习俗出现了。曾经有学者总结了收继婚的三个主要原则。

第一,被收娶者必须是寡妇,也就是说,如果自己父亲或者哥哥还活着,就不能娶自己的后妈或者嫂子。

第二,收娶者必须是死者社会习俗上的婚姻继承人。

第三,收继婚是公开的结合,是光明正大的关系,而不是偷偷摸摸的私通。

这三条原则确保了在北方游牧民族的社会中,收继婚既不会有近亲结婚带来的弊端,又可以保证健康的孕龄妇女留在家族内为家族延续血脉。

From #

进击的智人