我认为我们运行的 Solaris 版本太旧,无法在 top 中报告窃取时间。有没有办法获取此旧版 Solaris 的此信息。以下是基本版本信息:
-bash-3.2$ uname -aX
SunOS sekritname 5.10 Generic_150400-59 sun4v sparc sun4vSystem = SunOS
Node = sekritname
Release = 5.10
KernelID = Generic_150400-59
Machine = sun4v
BusType = <unknown>
Serial = <unknown>
Users = <unknown>
OEM# = 0
Origin# = 1
NumCPU = 32
我对这些 Sun VM 系统没有任何真正的专业知识,所以我可能会误解一些事情,在这种情况下可能有更好的方法来完成我需要做的事情。应用我的英特尔思维模型,我怀疑我们的 CPU 被挤占了,但我该如何衡量呢?
更新
请原谅我使用英特尔术语。我们基本上在单个刀片上运行两个虚拟机,其中一个是应用服务器,另一个为该应用提供 SSO 支持。有时,应用服务器会显著变慢,有时,第三方 SSO 应用也会陷入困境。
其中还涉及孤岛和政治,因此我无法了解 SSO 主机或实际硬件层。
我目前的假设是,当 SSO 应用程序出现故障时,它会占用过多的 CPU,以至于应用程序服务器无法获得足够的实际计算时间来跟上负载。我分析了应用程序的 GC 日志,其中有一条引人注目的条目如下:
[Times: user=0.71 sys=1.36, real=1.47 secs]
通常情况下,使用 10 个并行 GC 工作线程,user >> real >> sys
而导致奇怪时间模式的一个原因是虚拟机无法获得足够的 CPU。(我们没有进行交换,而且系统都是基于 SSD 的,因此 IO 等待不是问题。)
此时我需要获取数据来帮助证明这一理论,在我的 Linux 思维中,我只需检查 top 中的 st%。谷歌搜索还显示,在现代版本的 Solaris 中我可以做同样的事情。我的问题是我们没有运行现代版本的 Solaris。
答案1
您真正的问题似乎是性能下降。而且在 Solaris 10 T1000/T2000 服务器上,偷取时间可能毫无意义。
要查明您是否在区域中运行,请使用命令/usr/bin/zonename
(不同版本的 Solaris 上的位置可能不同 - 还请检查/bin
、/sbin/
和/usr/sbin
。)如果zonename
返回除之外的任何内容global
,则表示您正在区域中运行。
如果由于某种原因您无法访问该zonename
命令,则可以使用几个ps
命令来查看您是否处于区域中。首先,查找init
:
ps -ef | grep init
如果上述操作未找到init
PID 为 的进程1
,则表明您处于区域中。您还可以查找zsched
(如果我没记错的话):
ps -ef | grep zsched
如果返回一个进程,该进程是它自己的父进程(PID 和 PPID 都相同且大于1
),那么您就在区域中运行。
如果您处于某个区域,您可能会遇到资源限制,从而减慢您的速度。不过,这种情况不太可能发生。
什么别的服务器上正在运行什么?包括其他区域。我曾在 Sun T 系列服务器上看到过与您描述的类似的严重性能问题,这是由 ZFS ARC 与使用大内存页面的应用程序(例如 Oracle 数据库)之间的交互引起的。
ZFS ARC 使用 4k 内存页,因此会产生内存碎片 - 而且它会全部服务器上的内存。如果您的服务器进入该状态,并且某个进程需要大量大内存页面,则内核必须将一堆小页面合并为大页面,这涉及移动大量内存。而且这一切都是在单线程中完成的。早期 T 系列服务器上的任何单个线程都是慢的因为服务器被设计用于处理大量具有较大延迟的线程 - 例如处理网络上大量连接的 Web 服务器或数据库服务器。
因此,内核会在很长一段时间内完成将小页内存合并成大页的任务。
然后,在大页面使用过程完成后,ZFS ARC 会取回这些页面,并且这些页面会变得碎片化。
我怀疑您可能也遇到了同样的问题。
要查找答案,请运行
echo ::memstat | mdb -k
如果您正在运行区域,请以 root 身份在全局区域中执行此操作。如果您的可用内存真的很低,您可能会遇到此问题。
为了找到答案,请再次以 root 身份从全局区域运行以下 dTrace 脚本,以确定内核将其所有时间花在何处:
#!/usr/sbin/dtrace -s
profile:::profile-1001hz
/arg0/
{
@[ stack() ] = count();
}
将其复制到一个文件,hot.d
将其设置为可执行文件(chmod 755 hot.d
)并从全局区域以 root 身份运行它:
./hot.d
在遇到速度变慢时运行它。让它运行 10-20 秒(如果不是更长时间的话)matched 1 probe
,然后使用 中断它CTRL-C
。然后它将发出很多的输出,其中大部分您不必关心。但是,最后几个堆栈跟踪输出将是最常见的采样输出,它们将告诉您内核将其时间全部花在何处。
这将明确地告诉你问题出在哪里。它可能不够精确,无法完全解决问题,你可能需要做更多调查,但你会知道该去哪里找。
如果您看到很多带有idle
或wait
的堆栈跟踪,则表明存在用户空间问题。您可能能够通过将stack()
上面的 dTrace 脚本替换为ustack()
来获取用户堆栈,从而识别该问题。
如果你在函数名称中看到很多堆栈跟踪coalesce
,则内核正在花费所有时间来创建大内存页面。解决此问题的方法是释放内存,最有可能通过限制 ZFS ARC 大小,甚至可能非常严格。我不得不髌骨将一些服务器上的 ZFS ARC 降至 1 GB 以下,以防止其影响性能。