下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者

Linux 黄金指标

2018-04-17 Steve Mushero
大多数人对于应用程序及其底层服务的性能及稳定性非常关注,不过其中大部分服务实际上依赖于更为底层的 Linux,以及 CPU、内存、网络以及 IO 等核心资源。
因此,自行获取 Linux SRE 指标可能更为明智,特别是在上层服务对底层资源使用情况(特别是 IO)非常敏感的条件下。
即使不关注这些,此类指标也能够提供大量有价值细节,帮助你观察上层指标的变化——例如 MySQL 延迟的突然增加。毕竟这一切都有可能反映出 SQL、数据或者底层 IO 系统的变更。
对于 Linux,我们通常最关注 CPU 及磁盘,内存次之(主要关注饱和度),而后才是网络。时至今日,网络资源已经很少过载,因此大多数人会直接将其忽略——至少在 SRE 指标及警报方面是如此。
不过大家还是应该根据需求将网络 IN/OUT 作为网络级请求率指标进行监控,这是因为网络流量异常往往值得关注,而且很可能与其它请求指标存在关联(有助于进行故障排查)。

CPU

在 CPU 方面,惟二值得关注的指标就只有利用率与饱和度。虽然错误、延迟与请求等指标的重要性不高,但我们应有理由追踪其中的延迟指标。因此:
延迟:目前尚不清楚其在 Linux 当中意味着什么,可能代表着负载的执行时耗,也可能代表负载在 CPU 队列中的等待时间(不涉及交换或 IO 延迟)。
 遗憾的是,我们无法衡量 Linux 在执行各类负载时所耗费的具体时间,也无法衡量全部任务在 CPU 队列当中的等待时长。有些朋友可能认为从 /proc/schedstat 中能够得到这类指标,但经过大量实验,我们发现其实并不可以。
饱和度:我们需要 CPU Run Queue 长度,如果其大于零,则代表负载需要在 CPU 上等待处理。不过我们很难准确获取此项指标。
我们当然希望能够直接使用 Load Average,但遗憾的是在 Linux 当中,其中同时包含 CPU 与 IO,这会令数据内容质量下降。不过如果你的服务仅使用 CPU 且 IO 很少 / 为零(例如应用服务器),则此项指标将极易获取——但请注意那些被写入至磁盘的大型日志。若 Load Average 大于 CPU 计数的 1 到 2 倍,则通常意味着饱和。
如果我们需要真正的队列,即排除一切 IO,则难度将直线上升。第一问题在于,所有工具所显示的数据并无法随时间推移计算平均值,这意味着瞬时测量结果将包含大量噪声——这种情况广泛存在于 vmstat、sar-q 以及 /proc/stat 的 procs_running 当中。
 下一项挑战在于,Linux 调用的运行队列中实际包含有当前运行的条目,因此我们必须减去 CPU 数量以获得真正的队列指标。任何大于零的结果都意味着 CPU 处于饱和状态。
最后一个问题是如何从内核当中获取这些数据。最好的办法当然是使用 /proc/sat 文件。获取“procs_running”计数并减去 cpus(grep -c processor /proc/cpuinfo)即可获得队列指标。
但这仍然属于瞬时计数,因此同样包含大量噪声。似乎还没有工具选项能够实现随时间推移的汇总能力,因此我们使用 Go 语言编写了 runqstat 工具——感兴趣的朋友可以点击此处在 GitHub 中查看(目前仍处于开发当中)。
窃取:你可以追踪 CPU 窃取百分比,这意味着从虚拟机管理程序的角度来看,CPU 已经处于饱和状态。不过大家也应同时查看 CPU Run Queue 中的即时增长,除非你使用的是 Nginx、HAProxy 或者 Node.js 等单线程负载(在这种情况下,Run Queue 将难以查看)。
需要注意的是,对于单线程负载而言饱和度指标实用性不高(因为由于不存在其它需要运行的负载,因为不会出现队列)。在这种情况下,你应关注利用率,具体如下。
利用率:我们需要 CPU%,但其需要配合一些数学计算,最终得出的 CPU% 加和为:用户 + 冗余 + 系统 + 窃取(若有)。不要添加 iowait%,显然也不应添加 idle%。
 在虚拟化条件下,对系统上的 CPU 窃取百分比进行追踪将非常重要。请千万不要忘记这一点,并对一切高于 10% 至 25% 的结果保持警惕。
对于 Docker 以及其它容器,我们很难检测到最佳饱和度指标,且具体取决于系统是否设定有上限。大家必须读取每个容器中的每套 /proc 文件系统,并从 cpu.stat 文件中获取结果,提取会在每次 CPU 发生卡顿时增加的 nr_throttled 指标。在对其进行增量处理后,我们即可得到每秒卡顿数量。

磁盘

在磁盘方面,我们应将 SRE 指标映射至以下指标,其全部来自 iostat 实用程序。不过你的监控系统可能会直接从 /proc/diskstats 中提取这些条目(大多数探针都支持这项功能)。
你可以面向全部磁盘、最繁忙磁盘或者服务数据所在磁盘获取上述数据,最后一种作法一般最为简单,因为大家肯定都了解服务的所在位置并可将注意力集中顺对应的警报及仪表权身上——而不致因其它信息量较少的磁盘而分神。
请求率:磁盘系统的 IOPS(合并之后),在 iostat 中表示为 r/s 与 w/s。
错误率:对磁盘进行测量无法得出任何有意义的错误率——除非你希望对高延迟状况进行计数。大多数真正的错误——例如 ext4 或 NFS——会带来致命的后果,你应尽快发布警报。而且由于需要对内核日志进行解析,因此我们实际上很难发现这些错误。
延迟:读取与写入时间,其在 iostat 中表示为平均等待时间(await),其中包含查询时间并会在磁盘饱和时急剧上升。
如果可以,最好分别监控读取与写入响应时间(即 r_await 与 w_await),因为二者在动态表现上往往区别很大,能够帮助你为敏感地把握实际变化,且不受“其它”IO 方向(特别是数据库)噪声的影响。
你也可以测量 iostat 服务时间,并借此查看各磁盘子系统的运行状况,具体包括 AWS EBS 以及 RAID 等等。其上升可能会给负载及 IO 敏感型服务带来实际影响。
饱和度:最好利用每设备 IO 队列长度进行测量,iostat 以 aqu-sz 变量的形式提供。需要注意的是,其中包含有服务 IO 请求,因此并不算是真正的队列指标(相关数学计算比较复杂)。
需要强调的是,iostat util % 并不适合用于测量真正的饱和度,特别是在使用 SSD 与 RAID 阵列的情况下——二者可以同时执行多个 IO 请求,因此其实际表示的是处于进行过程中的至少一项请求的时间百分比。然而,如果你只需要获取 util %,也可利用其简单查看当前运行状态与基准情况是否存在差别。
利用率:大多数人会使用 iostat util %,但如上所述,这项指标在衡量单轴磁盘之外的实际利用率时并不适合。

内存

在内存方面,我们需要关注的只有饱和度与利用率。
饱和度:任何交换行为都意味着内存已经发生饱和,不过目前大多数云虚拟机已经不再使用任何交换文件,因此这项指标的实用性正快速下降。这意味着目前最理想的衡量指标应该是接下来要提到的利用率。
大家应尽可能追踪 OOM(内存不足)错误,其主要由内核本身引发,即出现内存空间用尽或者进程交换。遗憾的是,我们只能在内核日志当中查看这些情况,因此在理想状态下,你可以将这些信息发送至一套集中式 ELK 或者基于 SaaS 的日志分析系统当中,并据此发布警报。
任何内存不足错误都意味着内存资源已经严重饱和,而且也代表着一种紧急事态——在 MySQL 等系统中,这可能导致内存使用量最大的用户被关闭。
需要注意的是,如果存在交换或者内核交换未被设置为 1,那么内存在被用尽之前会发生大量交换操作。这是因为内核不会在开始交换之前尽可能下调文件缓存,如此一来即可保证内存资源被生产进程全部占用之前即进入内存饱和状态。
利用率 — 计算内存使用量的公式为(总内存 - 自由缓冲区 - 缓存),这也是最经典的内存用量衡量方法。除以总内存容量,即可得出当前利用率百分比。

网络

在网络方面,我们最关注的是吞吐量,也就是我们在带宽层面所说的“每秒请求数量”。
速率:读取与写入带宽,以每秒 bit 为单位。大多数监控系统能够轻松获取这项指标。
利用率:将读取 / 写入带宽除以网络最大带宽。需要注意的是,在混合虚拟机 / 容器环境下,最大带宽数值可能很难确定,这是因为此类情况下流量可能同时使用主机的本地主机网络与主有线网络。这时,可能最好直接追踪读取与写入带宽。

作者简介

Steve Mushero:云络科技创始人,上海云敞网络科技有限公司全球技术顾问。Steve Mushero 具有 25 年以上的 IT 运维经验,曾任职土豆网第一任 CTO,OaaS 开创者以及多项专利持有人。
 写留言

精选留言

由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。