我们最近安装了一台新机器,它有 8 个双核 CPU、20 GB RAM 和 3 个 1 TB 硬盘,这些硬盘被设置成某种 RAID,因此实际上可以使用 2 个 1 TB 硬盘(我不是这里的硬件专家)。它被设置为 ESXi 主机,我们在其中设置了许多测试环境。当前测试在 Windows 2003 64 位和 SQL Server 2005 Standard 64 位 SP3 上运行。从所有报告来看,该系统应该托管比我们以前的设置性能更好的环境,但某些任务的性能却差得多。我发现一个特定的 SQL 脚本在某些条件下确实运行得非常慢,我无法理解。SQL 脚本是一系列简单的 1700 多个 UPDATE 语句,开头如下:
UPDATE SrfItem SET fkSrfItem = 5 WHERE id = 4
UPDATE SrfItem SET fkSrfItem = 8 WHERE id = 7
UPDATE SrfItem SET fkSrfItem = 10 WHERE id = 9
我发现,如果我在其中一个虚拟环境中按照以下步骤操作,运行脚本需要 9-12 秒:
测试用例 #1
- 从虚拟 SQL Server 环境中的备份恢复测试数据库
- 本地连接到数据库
- 运行脚本-此步骤需要9秒
在我的桌面上执行同样的程序只需不到 1 秒就能完成第 3 步。
测试用例 #2
- 从物理 SQL Server 环境中的备份恢复测试数据库
- 本地连接到数据库
- 运行脚本-此步骤只需不到 1 秒
但在交易中运行脚本很快
测试用例 #3
- 从虚拟 SQL Server 环境中的备份恢复测试数据库
- 本地连接到数据库
- 在脚本开头添加“BEGIN TRAN”
- 在脚本末尾添加“COMMIT TRAN”
- 运行脚本-此步骤只需不到 1 秒
我发现有趣的是,即使我在事务中执行一次并将其回滚后,它仍然运行缓慢
测试用例 #4
- 从虚拟 SQL Server 环境中的备份恢复测试数据库
- 本地连接到数据库
- 在脚本开头添加“BEGIN TRAN”
- 在脚本末尾添加“ROLLBACK TRAN”
- 运行脚本-此步骤只需不到 1 秒
- 仅执行不包含交易的脚本部分 - 此步骤需要 9 秒。
我已经在装有 Windows 2003 32 位和 SQL 2005 32 位的虚拟系统以及装有 Windows 2008 64 位和 SQL 2008 64 位的虚拟系统上运行了测试。我已经在装有 Windows 2003 和 SQL 2005 的物理系统以及装有 Windows 7 64 位和 SQL 2008 R2 64 位的物理系统上运行了测试。我尝试过的所有虚拟系统都表现出这种缓慢现象,并且托管在新的 ESXi 环境中。所有物理系统都没有表现出这种缓慢现象。
有人能帮我理解一下这里发生了什么吗?我担心类似的性能问题会影响其他领域,我们应该在主机或客户机环境中重新配置一些东西。到目前为止,我们唯一能想到的就是关闭主机 BIOS 中的超线程,以匹配另一个虚拟环境及其主机的配置,在那里我们看不到缓慢的行为(我没有观察到其他虚拟环境和主机上的测试,那里的速度并不慢)。这会导致如此大的性能差异吗?
编辑:在回顾了我的问题和第一个答案后,我同意我所展示的可能是我们的物理和虚拟环境之间的 I/O 延迟性能差异。我还意识到我应该提供一些其他详细信息:这些图像使用精简配置,并且在其下有两个或三个快照。这会对该统计数据产生如此大的影响吗?现在的问题是,虚拟环境和物理环境之间的统计数据差异如此之大是否正常?我是否应该能够在环境或 SQL 配置中对其进行优化,或者是否由软件本身为具有极端 I/O 延迟的虚拟系统进行更优化的编写?
vSphere 客户端报告虚拟磁盘的写入延迟为 11 到 40 毫秒,平均为 21 毫秒。这个统计数据有用吗?这个数据是否极端?
编辑: 我们的硬件(DL380 G6)似乎存在性能问题,如下所述http://laez.nl/vmware-bad-performance-on-hp-proliant-dl380-g6-with-esxi-3-5-u4/我们只需要进行一些重新配置即可提高性能。我接受这个答案,它引导我们朝着正确的方向看,即磁盘 I/O 延迟是问题所在。
答案1
总结:
- 在你的真实服务器上,你可以在不到一秒的时间内进行 1700 次表更新 + 1700 次提交,
- 在你的虚拟服务器上,你可以在 9 秒内进行 1700 次表更新 + 1700 次提交,
- 在您的虚拟服务器上,您可以在不到一秒的时间内完成 1700 次表更新 + 1 次提交。
因此在我看来,您的问题可以重新定义为“在真实服务器上,我可以在不到一秒的时间内完成 1700 次提交,但在我的虚拟服务器上性能却下降了十倍”。
1700 次表更新和 1700 次提交之间有什么区别?表更新完全缓存,完全不依赖于磁盘 I/O。提交则完全不同。根据事务数据库的本质,数据库引擎必须非常确定犯罪已实际保存到磁盘(保存到日志文件),然后才开始提交下一个事务。因此,对于这 1700 次提交中的每一次,它都必须等待整个 I/O 往返。总而言之,在您的场景中,I/O 的延迟起着非常重要的作用,应该进行分析(不要将延迟与 I/O 速率或字节吞吐量混淆;这三个都是完全不同的动物;它们总是单独调整的)。
使用 IOMeter 测试存储是个不错的计划。它在启动时会挂起,因为它试图用测试文件填满整个磁盘。只需等到文件增长到相当大的数量并重新启动 IOMeter,它就可以正常处理“不完整”的测试文件。
答案2
您的澄清使这个问题有所明了。
3 驱动器 SATA RAID 5 组不是写入性能的最佳磁盘配置。每次写入 IO 都会产生 [最多] 4 个磁盘 IO(读取当前块、读取当前奇偶校验、写入新块、写入新奇偶校验)。实际上,这会将您的三个 7200 rpm 磁盘变成一个性能更像单个 5400rpm 驱动器的磁盘(假设您的基本驱动器为 7200 rpm)。
其次,您说 SQL VM 上有许多活动快照。VMware ESXi 快照会产生不小的开销 - 根据您正在执行的操作,当您有活动快照时,IO 开销将达到 50-100%。这会影响读取和写入。
第三,您说您正在使用精简配置 - 这会对 IO 性能产生影响,但不如其他两个影响那么显著。
最后,您没有说 ESXi 主机上是否有任何其他虚拟机在运行 - 如果有,它们显然会影响整体性能,尤其是在使用 RAID5 x 1TB SATA 磁盘设置的情况下。
答案3
我认为您的测试并不是那么可靠,无法确定虚拟化系统是否存在问题。一秒钟的测试不足以给系统施加压力以显示任何真正的瓶颈。
在虚拟化世界和 SQL Server 中,有许多活动部件。我认为磁盘 IO 是这里的主要参与者,但 RAM 也是。ESX 可以根据需要从客户机提供和获取 RAM,有时 ESX 需要几秒钟才能做出反应,从而产生短暂的暂停。如果服务器处于一定的恒定负载下,则 ESX 会稳定 RAM,但如果测试时间短且突发,则可能需要一些时间来加速。
在开始将一切推倒之前,请先运行更长时间的测试,并使用 ESX 监控 RAM 使用情况、磁盘 IO 延迟、CPU 队列长度等。一个好的测试需要在物理机上运行 30 到 60 秒,我希望虚拟机的时间在该时间的 150% 以内。