在Windows 2008 R2高端机器上运行SQL Server 2008时,CPU个数的考量

在Windows 2008 R2高端机器上运行SQL Server 2008时,CPU个数的考量

本文来自:
http://blogs.msdn.com/b/apgcdsd/archive/2011/09/05/windows-2008-r2-sql-server-2008-cpu.aspx

背景介绍

通常SQL Server在运行时,我们在错误日志里,会发现有多少个CPU被检测到。如下面的例子,SQL Server检测到了总共有4个CPU.

 

在Windows 2008 R2高端机器上运行SQL Server 2008时,CPU个数的考量_第1张图片

 

我们知道SQL Server所能检测到的CPU是逻辑CPU个数。而不是物理CPU个数。双核CPU对于SQL Server来讲,是两个逻辑CPU,如果有超线程的话,CPU个数还要翻一倍。逻辑CPU个数,通常能在Windows 的Task Manager里显示出来, 在CPU Usage History里,有多少个框,就有多少个逻辑CPU

 

在Windows 2008 R2高端机器上运行SQL Server 2008时,CPU个数的考量_第2张图片

 

【问题】

但是在有一些很高端的机器上,我们会发现一些比较有趣的现象。SQL Server所能检测到的CPU个数,竟然和逻辑CPU个数不符合。

 

如下面的机器配置,有4个物理CPU, 每个CPU上有10个Cores, 而且也enable了超线程。所以这台机器上,总共有80个逻辑CPU,按道理,SQL Server应该能检测到80个CPU才对。

 

但我们查看SQL Server的错误日志,SQL Server 竟然只能检测到40个CPU.

 

在Windows 2008 R2高端机器上运行SQL Server 2008时,CPU个数的考量_第3张图片

 

在另外一台相同配置的机器上,SQL Server 重启后,有时候能检测到20个CPU, 有时候能检测到60个CPU。

 

SQL Server能检测到的CPU个数竟然会随着SQL Server重启,而有所变化。本来SQL Server性能很好,重启后,SQL Server能使用的CPU变成20了,性能就会变得很差。这对于很高端的应用来讲,是不能接受的。

 

【调查】

 

对于这个非常奇怪的现象,我们似乎是无从下手,难道是SQL Server的版本限制?但是我们的SQL Server版本已经是Enterprise了, 好像是SQL Server的一个Bug, 但是又不能确定。

 

调查一

我们做了进一步的研究。我们知道,SQL Server所检测到的CPU个数,是通过调用下面的函数所得到的:

 

SYSTEM_INFO siSysInfo;

GetSystemInfo(&siSysInfo);

printf("  Number of processors: %u\n", siSysInfo.dwNumberOfProcessors);

 

我们写了一个repro程序,完整的代码如下:

 

// SystemInfo.cpp : Defines the entry point for the console application.

#include "stdafx.h"

#include <windows.h>

#include <stdio.h>

#pragma comment(lib"user32.lib")

int _tmain(int argc, _TCHAR* argv[])

{

 

   SYSTEM_INFO siSysInfo;

   // Copy the hardware information to the SYSTEM_INFO structure.

 

   GetSystemInfo(&siSysInfo);

   // Display the contents of the SYSTEM_INFO structure.

 

   printf("Hardware information: \n"); 

   printf("  OEM ID: %u\n", siSysInfo.dwOemId);

   printf("  Number of processors: %u\n", siSysInfo.dwNumberOfProcessors);

 

       return 0;

}

 

编译执行上述代码,问题能够重现:

D:\TEMP>systeminfo_x64.exe

Hardware information:

  OEM ID: 9

  Number of processors: 60

 

D:\TEMP>systeminfo_x64.exe

Hardware information:

  OEM ID: 9

  Number of processors: 20

 

D:\TEMP>systeminfo_x64.exe

Hardware information:

  OEM ID: 9

  Number of processors: 20

 

D:\TEMP>systeminfo_x64.exe

Hardware information:

  OEM ID: 9

  Number of processors: 60

 

所以,到了这一步,我们可以判定,问题跟SQL Server无关。但是为什么GetSystemInfo() 得到的CPU个数会变来变去呢?难道是GetSystemInfo() 这个API的Bug?

 

调查二

我们仔细研究了GetSystemInfo这个API, 其中,_SYSTEM_INFO 这个结构描述在:

http://msdn.microsoft.com/en-us/library/ms724958(v=vs.85).aspx  对dwNumberOfProcessors的描述如下:

dwNumberOfProcessorsThe number of logical processors in the current group

 

这里,”current group” 这个词引起了我们的注意。

 

调查三

我们做了进一步研究,发现在Windows 7和Windows Server 2008 R2 里,我们引入了Processor Group 这个概念, 具体描述在http://msdn.microsoft.com/en-us/library/dd405503(v=vs.85).aspx  简单的讲,64位的Windows7和Windows Server 2008 R2为了能够在一台机器上,支持超过64个逻辑CPU, 引入了Processor Group这个概念。Processor Group会把一些逻辑CPU编成一个组,但是一个组内的逻辑CPU总数不能超过64个。超过64个的话,要编入另外一个组。

 

所以,对于我们的系统,有80个逻辑CPU, 那么就会编成两个组。是不是每个组均匀的分配CPU呢,不是的。操作系统会在重启的时候,根据逻辑CPU之间的物理远近,自动进行编组。所以,在有的系统上,我们会看到40-40分配,在另外系统上,我们会看到20-60分配。

 

那么,每当一个进程运行的时候,它会在哪个Processor Group上运行呢? 操作系统会按照Round-robin方式,给每个进程分派Processor Group, 一旦一个进行分配到了一个Processor Group, 就会一直在这个Processor Group里运行,直到该进程结束为止。

 

【解释】

所以,这就解释了,为什么SQL Server 2008 有时候能检查到20个CPU, 有时候能检查到60个CPU, 这完全是因为Processor Group在起作用。每次SQL Server 重新启动后,有可能被分配到另外一个Processor Group, 而导致能检查到的CPU个数出现变化。

 

我们可能会问,为什么SQL Server 2008 会通过调用GetSystemInfo(&siSysInfo); 的办法来获取逻辑CPU个数呢?难道不能用其他API么?这是因为,Processor  Group这个概念是在Windows Server 2008 才引入的。当开发SQL Server 2008的时候,并没有做相应的变化。当然,这个问题在SQL Server 2008 R2得以解决。SQL Server 2008 R2能最多同时检测到256个逻辑CPU.

 

【解决方案】

 

最好的解决方案是把SQL Server 2008 升级到SQL Server 2008 R2. 如果短期内不可行的话,我们可以把超线程禁用。这样系统上逻辑CPU的个数会变成40个。小于64个,所有的CPU会被编入一个组。虽然SQL Server能检测到的CPU只有40个,但至少系统是稳定的。

 

我们可能还会问,是否有办法,能否人工干预Processor Group的编组,一个组有64个CPU, 另外一个组有16个CPU?  对于NUMA架构的话,我们可以做一些适当的调整,具体可参考: http://support.microsoft.com/kb/2506384

 

另外,如果我们碰到Processor Group按20-60分配的情况,对系统整体性能是有影响的。建议打一个操作系统的补丁:

 

Performance issues when more than 64 logical processors are used in Windows Server 2008 R2

http://support.microsoft.com/default.aspx?scid=kb;EN-US;2510206

 


你可能感兴趣的:(cpu,sqlserver)