最近几天,笔者所在的单位中的一台WEB服务器由于负载过大出现了问题,当同时在线的用户达到一定规模(2000-3000)时,频繁出现页面响应迟缓、超时等问题。服务器采用的操作系统是Windows Server 2003企业版,数据库系统是SQL Server 2005企业版。正当大家考虑升级服务器时,笔者对服务器状态进行了分析,并最终在未增加服务器硬件条件下找到了瓶颈、解决了问题。现将分析、解决问题的过程与大家分享,希望能帮助大家解决类似的问题。
分析问题:
通过对服务器检查发现,不仅服务器的HTTP请求响应迟缓,就连在服务器本机操作和远程桌面的操作中都有明显“卡”的感觉。检查任务管理器,发现此时的CPU占用率和内存使用率并不高,没有发现制约性能的地方,可是为什么系统这么慢呢?这时,我发现了服务器的硬盘灯狂闪不止,这下发现了病因,服务器在频繁的访问硬盘,而硬盘IO响应时间和内存相比是非常高的。
利用SQL Server自带的性能工具:SQL Server Profiler,打开其性能监视器,我发现了Avg.Disk Queue Length(平均磁盘队列)和Pages/Sec(每秒读取的磁盘页面数)都很高,如图1所示,尤其是Avg.Disk Queue Length,已经达到了万级,而Pages/Sec也达到了60。正常的Avg Disk Queue Length值应该是盘阵中磁盘数量的2倍,Pages/Sec也应该维持在10以下(除了偶尔的峰值外)。
图1 SQL Server性能监视
解决问题:
看来要想完全解决问题,就要分析数据库频繁访问硬盘的原因。一般来讲,SQL Server会充分利用内存进行缓存,不会太过频繁的访问硬盘。而我们的问题是虽然负载较高,但内存使用率并不高(仅仅使用了1.8G内存)。服务器的内存总数为12G,虽然IIS与其它应用占用了一些内存,但剩余的可用内存仍然有8G左右,为什么SQL Server不充分利用内存而频繁读取硬盘呢?
这里有一个很有意思的现象,微软和我们开了个小玩笑,当通过右键点击“我的电脑”的属性时,可以发现服务器正确识别了12G内存,可这并不意味着它就能使用这么多内存。Windows Server 2003企业版和Windows XP一样都是32位操作系统,受到32位内存地址的制约,它们能使用的内存通常不会超过4G,单个进程能使用的内存甚至不能超过2G。但Windows XP的计算机属性中会老老实实地告诉我们系统只识别到3G多内存,而Windows Server 20003会识别所有内存,但实际上它默认情况下无法使用那么多内存。
通过上网查询,发现可以通过开启Windows 2003 Server的PAE功能以启用大内存支持。首先,找到C:的boot.ini文件。在资源管理器中点击“工具”-“文件夹选项”-“查看”,在高级设置中取消“隐藏受保护的操作系统文件”,并选择“显示所有文件和文件夹”。这样我们就可以看到boot.ini文件了。用记事本打开它,找到类似于如下的行:
multi(0)disk(0)rdisk(0)partition(1)WINDOWS="Windows Server 2003, Enterprise" /noexecute=optout /fastdetect /pae
如上面一样,在其末尾加上“/pae”选项,然后重新启动服务器,这样便启用了windows 2003 Server的大内存支持。
为了让单进程使用内存突破2G,我们还需要修改SQL Server的设置。首先应该在系统中创建一个隶属于管理员身份的用户,然后在“开始”-“运行”中输入“gpedit.msc”启动组策略编辑器。找到“计算机设置”-“windows设置”-“安全设置”-“本地策略”-“用户权限分配”,单击该节点后在右边找到“内存中锁定页面”,双击后添加刚才建立的用户。
换用刚建立的用户登录系统,点击“开始”-“程序”-“管理工具”-“服务”,找到SQL Server服务。右击“属性”,点击“登录”选项卡,选择“登录身份”为“此账户”,确定下面文本框中的用户为当前新建立的用户并输入正确的用户密码(如图2),然后重新启动SQL Server服务。这样设置的目的是让有“内存中锁定页”权限的用户来启动SQL Server进程,这是使用大内存支持的必要手段。
图2 用新账户启动SQL Server服务
重启SQL Server后,使用SQL Server Management Studio连接到数据库服务器,右键点击服务器节点,选择“属性”,在对话框中找到“内存”面板,勾选其中的“使用AWE分配内存”(如图3所示),然后按照服务器内存情况正确设置最小和最大的内存使用,单位为MB,本例中的内存设置为最小4G最大6G,设置完成后再次重新启动SQL Server,即可生效。
图3 开启AWE,设置内存使用
经过这样的设置后,单位的服务器同时在线5000人也没有再发生超时或迟缓的现象,查看SQL Server Profiler的性能监视器,其Avg Disk Queue Length和Pages/Sec也降低到0左右(除了峰值),服务器运转恢复正常。
注意事项:
1.问题的根源在于32位系统访问内存的限制,导致应用程序不能充分使用内存,如果系统是64位的话,则没有这样的问题,而在微软的32位系统中,使用大内存支持可以通过PAE来实现,但也不是说内存多大都可以用PAE访问,现在的Windows Server 2003企业版通过PAE最多可以使用32G内存,其实这对于大多数应用足够了。
2.使用PAE仅仅解决了操作系统可使用的内存问题,应用程序要想突破单进程的内存限制还必须要拥有权限“在内存中锁定页”,这也是我们为什么要建立一个账户,并对其赋权后用该账户启动SQL Server的原因,所以这一步不能省略。
3.启动PAE和AWE后,资源管理器中对于SQL Server进程的内存使用情况就不再准确了,如果想查看SQL Server究竟用了多少内存,可在SQL Server Management Studio中建立一个查询,利用如下命令“DBCC MemoryStatus”查看内存使用情况,其中“AWE Allocated”项目如果不为0的话,则说明AWE启动成功,你的SQL Server现在已经运行在大内存状态下了(如图4所示)。
图4 查看内存使用情况