NoOps

Ops make no ops | Ops的目标是没有Ops,嗯!

服务器的处理器核心真的越多越好?

作者: |   3,710 浏览  | 

这里我们不再赘述有关寄存器、ALC等处理器架构和原理知识。我们只从直观的数据去分析和了解我们正在使用的多核处理器的真实性能——正所谓“是骡子是马拉出来溜溜”。一切建立在实际运行的数据才是真正有价值的评判依据。

 

在开始数据分析之前,我们必须弄清楚处理器的计算能力到底是什么:是频率决定了性能?还是核数决定了性能?

首选我们必须了解处理器的一个简单的性能计算公式:

整体性能 = 单核性能 × 核心数

 

其次性能受哪些因素影响会有以下这些原则:

原则一:架构越新,单核计算性能越强!

对比同频率、同核心数的前后两代处理器的计算能力就能发现架构越新的处理器整体计算能力也越强,这也意味着处理器架构的改进确实提高了单核性能。

 

原则二:频率越高,单核计算性能越强!

对比同代同核心数不同频率的处理器就能发现频率越高的处理器计算性能也越好,但这并非完全的线性增长。原因是处理器频率上去以后由于受到内存访问速度的限制也会有一定的瓶颈,而频率越高的处理器耗费在数据等待上的时钟周期也越多。

 

原则三:核心数越多,整体计算性能越强!

对比同代同频率不同核心数的处理器不难发现核心数越多的处理器整体计算性能也越好。但是如果观察单核性能会发现其实核数越多的处理器单核性能比同频率核数较少的处理器会差一些,主要原因是核数越多对共享资源的争抢概率也越高,这些共享资源包括L3缓存、内存、QPI总线等,这也就是多核处理器总是要把L3缓存做得很大的原因,核数越多L3缓存也越大。

 

请重点区别单核性能和整体性能:

1、单核性能:它影响的是单线程或者单任务的计算能力(即计算的响应延迟),对于单个请求计算的响应延迟要求较高的应用,就要用高频处理器去满足,而不是用多核。因为应用的一个线程无论任何时候都只能运行在处理器的一个核心上,增加核心数量对于改善单个计算请求的响应延迟并没有帮助,也就是说对跑单线程、单任务的应用无法提升其性能;

2、整体性能:前面提到核数越多整体性能越好,这也意味着多线程和多任务的应用环境下,如果要提高单机的计算处理量最好的办法是增加核心数而不是靠提高频率。理由很简单,核数较少的处理器晶元面积也小。如果要一味提高性能便要提高频率,提高频率其实就是给处理器晶元加电压。晶元能够忍受的电压是有限的,电压耐受力越高的晶元成本也越高。因此从稳定性和成本去考虑的话,晶元面积更大的多核处理器才是提高整体计算能力的最好选择。

 

下面我们挑选几款主流的双路处理器来作性能分析:

主题1:核数相同、频率不同

数据说明:如下表所示从第7行(Geekbench Integer)起是各项性能指标:分别是Geekbench整数成绩、SuperPI运行百万次的时间、以及根据Geekbench整数性能分别除以“处理器数量”、“核心数量”、“核心数量和Ghz的乘积”等来分别针对整体性能,单核计算能力,单个处理器、单个核心以及单个核心下每个Ghz的性能进行分析评估。

核数相同频率不同

数据分析:

1、SuperPI体现的是单核浮点性能,通过SuperPI成绩可以发现处理器频率越高单核计算性能也越好,这一点也可以通过“性能/每个核心”项目体现,频率越高单核的计算性能也越好;

2、Geekbench Integer评估的是处理器的整体性能,规律自然也是频率越高整体性能越好;

3、“性能/每Ghz/每个核心”项目评估的是处理器的计算效率,这个项目是将Geekbench的整数成绩按照核数拆分并根据单个Ghz去计算,可以发现核数相同的处理器这个数据相互比较接近。

 

 

主题2:频率相同、核数不同

频率相同核数不同

数据分析:

1、SuperPI项目更加可以说明单核计算能力受频率的影响,虽然2640 v2有8个核心,但对SuperPI的成绩没有丝毫帮助;

2、通过“性能/每个核心”项目可以发现,同频率下核数更少的2620 v2在这项成绩略好一些,即频率相同核数较少的处理器在单核性能上总是会核数更多的处理器略好一些,这确实也验证了核心之间存在资源争抢的假设;

3、Geekbench Integer成绩也体现出多核的性能优势,同频率下核数较多的处理器整体性能也更好;

4、再来看看用以评估计算效率的“性能/每Ghz/每个核心”项目,可以发现核数较多的处理器在计算效率上处于劣势:八核处理器的单核Ghz性能明显要比六核处理器的低不少,这样也进一步验证了核心之间存在资源争抢的假设,并且核数越多资源争抢的现象也越显著。

 

 

主题3:整体性能相同

最后一组选取整体性能接近而频率和核数均不同的处理器

整体计算能力相同

数据分析:

1、SuperPI的成绩依旧验证了单核性能只受频率影响的假设;

2、Geekbench Integer成绩说明2630 v2的性能整体略好于2640 v2;

3、通过“性能/每个核心”项依旧验证了频率决定了单核性能的假设;

 

根据以上数据我们可以进一步将计算公式细化为:

多核处理器的整体计算能力 = 单核Ghz计算能力 × 频率数 × 核数

 

结论:

1、处理器整体性能和频率、核数有关,但并非核数越多性能就一定越好,高频少核和低频多核整体性能很可能接近;

2、核数决定了计算承载能力,核数越多能够承载的计算量也越大;

3、频率决定了单核计算能力,频率越高单个计算请求的响应延迟也越低;

4、频率相同的情况下,核数越多单核计算效率也越低;

使用共享网口方式访问管理控制器

作者: |   10,168 浏览  | 

发现没有你的服务器会额外多出一个以太网口来,那个网口是专门用来访问管理控制器(BMC)的,当然也可以通过普通网口的共享模式访问BMC。

 

什么是共享网口方式?

这里要简单地提到NC-SI(Network Controller – Sideband Interface)技术,即网络控制器边带接口技术。这一技术是用来实现BMC芯片和以太网控制器之间信息传递的,它使得BMC芯片能够像使用独立管理网口那样使用主板上的网络接口。以下是共享访问模式的实现结构图:

NCSI

简单理解:BMC其实是一个单片机,它有自己独立的IO设备,而独立网口就是其中之一。将BMC芯片和网络控制器互联,通过NC-SI技术使得BMC芯片能够使用网络控制器上的接口。

 

为何要使用共享网口访问管理控制器?

1、减少物料成本:共享访问模式能够为单机节省一根网线;

2、减少人力成本:如果业务网只需要接一根网线,共享方案可以减少一半的布线人力支出;

3、减少交换机投入:独立网口会多占用一个交换机端口,增加交换机采购数量,使用共享模式减少了这部分的支出和额外的交换机运维成本;

 

如何实现共享网口模式?

1、BIOS或者WEB bmc界面中将IPMI访问方式修改为share(共享模式);

2、为共享网口独立分配一个VLAN号和IP地址,以便和业务网剥离;

3、在交换机端开启802.1q协议,并分配相同的VLAN号。

 

服务器到底用双电源还是单电源?

作者: |   5,659 浏览  | 

服务器通常会有两个电源插槽,两个电源意味着更高的可靠性,UPS的介入使得服务器供电的可靠性又上了一个台阶。随着电源可靠性的不断提高,也有越来越多用户开始使用单电源方案以节省成本。那到底用双电源还是单电源呢?

 

电源故障引发的业务风险有哪些?

单点类业务(开发、测试和办公平台等):

1、业务中断:业务无法继续向用户提供服务,影响用户体验;

2、数据恢复:掉电引发数据丢失,需要数据恢复,产生运维成本;

集群类业务(WEB前端、缓存、数据库等):

掉电引发数据丢失,根据业务的不同分类可能需要数据恢复(比如缓存型业务就不需要数据恢复),有一定的运维成本发生;

分布式存储(hadoop、分布式文件系统等):

存储类业务遇到单机断电掉线都将被作为一个节点的故障处理,因此数据恢复可能会占去大量的时间(自动化数据恢复除外);

 

通过数据评估两种方案的价值:

假设服务器总数为W万台,单电源服务器年故障率为x%,电源仅占到所有故障总数的y%,那么电源的年故障率应该在xy/10000,一年内电源故障次数为:Wxy。可以根据这个公式去评估一个集群一年内的断电次数:假设一年内允许的断电次数为Z,那么只要让Wxy < Z就可以达到期望目标。

当Wxy值远大于Z时,在x、y不变的情况下,通常是因为W基数较大引起的。这个时候要满足Wxy < Z就只能通过双电去实现:

双电方案下服务器年断电概率为:xxyy/10^8,断电次数为:Wxxyy/10000,它是单电方案故障次数的xy/10000,足够满足小于Z的条件了。

总结:在使用单电方案的前提下,如果要满足Z>Wxy,就要尽量控制整个集群的服务器规模;服务器基数较大时,为了避免基数问题带来过多的服务器断电,建议使用双电方案。

 

如何强化单电方案的可用性:

1、插头绑线规范化提高电源插头稳固性,防止服务器电源因误碰而掉线。

2、保持良好的机房散热条件,防止电源因为过热而导致故障;

3、尽量选用标号更高的电源(比如白金电源、黄金电源),提高转换效率减少谐波干扰;

 

注意:电源接入方案和供电故障不在本文讨论范围内,请同学们不要钻牛角尖。

服务器BIOS主要设置项目解说

作者: |   4,344 浏览  | 

每次操作BIOS的时候是否都有一种抓狂的感觉:面对玲琅满目的设置页和设置项几近崩溃?

何从下手设置BIOS项目呢?本文围绕和处理器、内存性能相关的设置项目进行解说,将关键设置项目进行细化和解释,同时给出设置建议。

 

有关BIOS主要设置项的说明:

1、处理器节电相关:C1E、C-State、电源模式、EIST等;

2、内存NUMA模式和访问速率等;

3、处理器超线程、虚拟化和直接IO访问等;

4、处理器指令优化:MLC、DCU等;

 

下表给出了详细设置项目的解说(以超微服务器BIOS设置项目为例):

BIOS设置项目说明

 

阵列卡缓存电池充放电问题详解

作者: |   5,168 浏览  | 

磁盘阵列是服务器上历史悠久的一项技术,它能够通过不同的阵列模式合理利用空间和性能配比出性价比极高的磁盘阵列,被大部分服务器OEM厂商所广泛采用。其中以LSI公司的MegaRAID SAS产品为主,广泛用于各品牌(除惠普外)x86服务器。

 

为何有缓存?

阵列卡核心技术包含三部分内容:1、数据条带化;2、数据冗余;3、高速缓存。其中高速缓存即所谓的阵列卡内存(以下简称缓存):阵列卡控制器通过一系列算法将上层应用下发的写请求进行优化并存储在阵列卡的高速缓存内以此提高应用的写性能(上层应用不必等待数据实际Flush到磁盘上即可完成写操作)。由于阵列卡缓存也属于RAM(易失性存储)的一种,因此也存在掉电丢数据的风险。一旦服务器断电,阵列卡缓存中的数据就会丢失,这会给应用造成数据一致性的风险。

电池的诞生

为了保障断电后数据的一致性,于是一种可循环充电式的电池被应用到阵列卡缓存单元上。如今大部分阵列卡缓存单元都会外接一个可充电式的电池包,以此来为断电后的缓存提供电源支持,同时保障数据在一定时间内不丢失(这个时间通常为48小时)。待到下一次服务器再次恢复电源后,阵列卡控制器会将缓存中的数据Flush到磁盘,以避免脏数据的产生。

缓存的供电方式

1、一般情况下服务器通电时阵列卡缓存使用的是主板供电;
2、服务器断电后阵列卡板卡电路自动将缓存的供电方式由主板切换到电池;

电池为何要进行充放电操作?

LSI阵列卡用的是锂电池方案,我们知道锂电池有较强的惰性,它在非充电状态下会缓慢地自放电(电池特性),一段时间后电量就会下降。为了能够及时校准电量避免电池因为自放电而导致电量不明确,于是阵列卡控制器会对电池进行周期性地充放电操作(Relearn),以此保证电量的准确性,同时还可以判断电池是否故障或者老化。

电池充放电会有哪些操作?

1、控制器首先对电池进行完全放电直至零电量;

2、控制器重新对电池进行充电操作直至充满;

3、控制器对电池的电量重新进行计算校准;

4、等待下一个充放电时间点;

为何充放电会引发性能问题?

充放电操作时由于电池电量无法提供足够的数据保障时间,为了避免风险发生阵列卡控制器默认会将缓存关闭,正是由于缓存被关闭而引发了写性能急剧下降的问题。

 

惠普服务器为何没有同类问题?

1、惠普服务器使用的是自家设计的基于PMC控制器的阵列卡,它采用的是镍氢电池。镍氢电池没有太强的惰性,并且特性和锂电池不同,它并不需要通过完全放电来校准电量。
2、当镍氢电池由于自放电而导致电量降低时到一定程度时(比如80%),阵列卡控制器会检测到电量下降并对电池进行娟流充电以补充失去的电量。整个过程对用户是透明的,也不需要关闭缓存,因此并不会影响IO性能。

 

是否存在可充电式电池的替代方案?

有!闪存式电容方案不但可以替代电池提供几乎无限的数据保护时间,并且控制器也不会因为充放电操作而关闭缓存。闪存式电容能够在服务器断电时,由高容量电容向阵列卡短暂地供电(大约几分钟),随后阵列卡控制器会将缓存中的数据全部复制到同等容量的闪存介质上。因为闪存是非易失性存储器,因此可以认为数据保护时间是无限的。待下一次服务器正常通电开机,阵列卡控制器在初始化阶段会将闪存中的脏数据重新Flush到磁盘上。

当然闪存式电容方案也不是绝对完美的,缺点也显而易见,就是成本太高!

 

为何采用可充电式电池?

1、基于可充电式电池的缓存单元价格低廉,比起基于闪存式电容的缓存单元要便宜许多;
2、可充电式电池通过循环充电已经能够满足一定的数据保护时间。

说到底还是因为成本!

 

阵列卡自动充放电带来的运维问题?
1、电池寿命有限,更换周期通常是2-3年,更换需要停机操作,增加运维工作量;
2、电池自动充放电时会强制关闭缓存影响写性能,给业务性能造成很大影响,给运维带来压力;
3、由于电池问题引发的问题和故障数不胜数,增加运维团队的工作量。

 

为何放弃阵列卡自动充放电功能?
1、通常服务器都是双电方案,单电源故障的更换操作可在线完成;
2、绑线规范使得电源和插头之间不会出现松动脱离的情况,更加减少了掉电的风险;
3、单个电源的月故障率远远低于磁盘、内存、阵列卡,双电同时故障概率极其低;

 

充放电问题的解决方案:

1、缓存单元的供电方案更换成闪存式电容;

2、缓存设置为WT(写缓存开启)和CachedBadBBU(强制写缓存开启),AutoLearn仍旧周期性进行只是该过程进行阶段缓存不会被关闭;(推荐)

3、担心AutoLearn期间电池的数据保护时间不够的话,也可以选择不强制打开写缓存,仅在业务低峰期时通过MegaCli工具人为地进行电池Relearn操作。

 

Juniper防火墙,LVS DR mode 与 HTTP keepalive 丢包问题追查

作者: |   6,181 浏览  | 

最近业务上新上了 Juniper 的防火墙。在防火墙上线后发现,原先业务上的调用同网段内 LVS VIP 的 HTTP 长连接在使用一段时间后频繁出现丢包重传现象,而其它网段连接此 LVS IP 则没有丢包。

 

概要

Juniper SRX 防火墙默认规则关于 TCP 连接建立的判定方法以及相关配置。

同网段中向DR模式 LVS 发出的TCP包,其回包不通过网关而是直接返回到发起机器。

使用python3 + urllib3 模拟 HTTP keepalive 长时间保持连接情况

 

症状

应用服务器上向 LVS IP 发的 HTTPS 请求丢包非常之惨烈。

first cap2

网络拓扑

先上一张网络拓扑,方便说明问题。

网络拓扑图

LVS IP 是公网IP

Juniper 防火墙设备同时充当默认网关。

 

复现、调查与分析过程

复现

为了能够在不影响业务的情况下方便调查,稳定复现问题是关键。

在复现的方法上想了很多办法,耗费了最多时间。

第一种方法,也是直接想到的方法,尝试用 curl。

但是连接丢包是在长连接建立一段时间后才发生的,所以使用 curl 需要 1) 模拟长连接 2) 长连接需要保持一段时间。

查阅手册,发现使用 curl 保持长连接不难,但是由于内网请求速度非常快,因此要保持长连接一段时间难以做到。

第二种方法,使用 python 的urllib3。

查了下urllib3的手册,写出下面代码。

运行该代码约20秒后,输出卡住了。重复多次稳定复现。

调查

先在业务机器上和 Real Server 上抓包,发现连接建立一段时间后一定会出现丢包,然后整个连接被关闭。

后尝试在 LVS 机器上和业务机器上抓包分析。

LVS 上抓包图:

LVS上抓包

业务机器上抓包图:

业务机器上抓包

蓝色的行为同一个包在 LVS 和业务机器上的同一个包。

通过在 LVS 机器和业务机器上抓包,确定是防火墙硬件将包丢弃。

至此,将调查重点放在防火墙配置上。

可疑的防火墙配置

现在问题已经明确为:

因为某个原因或者配置,防火墙将超过20秒的长连接的包丢弃了。

检查防火墙的配置,找找与 “20″ 相关的项目,在其默认配置中有所发现

其中

set security screen ids-option untrust-screen tcp syn-flood timeout 20

这一条其意义是:TCP 连接的建立必须在20秒内完成,否则该连接请求将被丢弃。链接

至此,已大致可以确定问题所在了:防火墙将超过20秒的连接强行关闭了。

LVS DR模式

在 LVS DR 模式下,请求方向 LVS 发起 TCP 请求,但是 TCP 请求的回包并不从 LVS 返回,而是由 Real Server 直接返回给请求方。

如果请求方与 LVS 不在同网段,则返回的 TCP 包需要通过网关转发给请求方。但是如果请求方与 LVS 是同网段且网关是防火墙设备,那情况要稍微复杂些。

如图:

TCP包流向图

TCP包流向图

注意到经过防火墙的 TCP 包是单方向的。防火墙一直认为 TCP 连接没有建立。

 

解决方法

根据之前的分析,想到的解决方法有两个:

  1. 调整防火墙配置和应用程序的配置,让 HTTP 长连接保持一个合适的时间。
  2. 在该网段搭建内网 LVS,流量不经由防火墙。

数据库优化案例(一)

作者: |   2,148 浏览  | 

现象:

  1. 程序大量SQL运行超时;
  2. 数据库中大量SQL长时间处于Updating阶段;

初步检查:

  1. 查看系统状态,CPU有24个核,只有一个核user利用率100%,其余核的idle基本上100%;
  2. 内存、IO.util都正常;
  3. 查看processlist,所有UPDATE语句长时间处于Updating阶段,其它类型的SQL没有Block或者运行缓慢现象;

进一步排查:

  1. 分析运行缓慢的SQL,发现运行缓慢的Update语句操作的都是同一张表;
  2. 执行缓慢的Update语句总共有两类:一类是通过主键更新一行数据;另一类是根据状态字段批量更新数据;Schema和SQL示例如下:

基本可以推测是根据状态字段更新数据的SQL导致的问题。进一步查看INNODB STATUS,发现如下记录:

这下可以解释为什么只有一个CPU核在运行了。第二条SQL通过索引加扫表的方式,寻找符合条件的数据,这条SQL消耗了一个CPU核。查找数据的同时,此SQL加了gap锁,导致其它更新同一张表的SQL一直在等待锁的释放,因此其它CPU核基本处于空闲状态。

解决

找到问题的根源,解决起来就比较简单了,分析一下数据,发现索引(user_id, status)的区分度还不错,新增索引(user_id, status)后,问题解决。

一种开源的部署解决方案-fleet

作者: |   3,685 浏览  | 

fleet是coreos的子项目之一, 是一个分布式的container发布工具,用于进行cluster中任务的提交和管理;

那通过fleet来进行部署发布有何优势? 需要具备什么样的条件? 有什么需要考虑的问题 ?

一、fleet的整体架构

Schedule-Diagram

 

二、fleet的运行机制

1、定义systemd的unit描述文件, 描述文件中指定要执行的命令(如启动的docker image或其它命令等),运行该job需要满足的一些依赖条件等;
2、将该描述文件commit到registry中, Engine检测到新任务创建一个joboffer;
3、所有线上机器通过fleet agent watch joboffer, 发现自身满足require描述, 则要求执行该任务;
4、engine将该任务分配给某一agent;
5、agent启动任务,并把JOB状态反馈到registry中;

三、fleet的特色
从fleet的架构中可以看出,它采用了一个与中心化发布完全相反的思路,采用这种方法有什么优势或者哪些值得借鉴呢?
1、agent主动请求任务,而非控制端发布任务, 弱化了部署前对主机和任务的对应关系的依赖,比较容易就可以进行job copies的控制;
2、天生具备针对任务的调度功能,在Engine上可以设置各种条件来进行任务的分配;
2、通过实现中心化的控制端进程远程管理(虽然暂时也用的ssh+信任关系), 但这个功能对动态调度系统来讲可以说是非常必要的一个功能,即便不能提前知道任务实际会运行在哪里仍然要以轻松进行访问和管理;

Read More →