在与朋友们聊到怎么让SQL Server的性能更好时,发现一些问题。对于SQL Server,除了遵循OS和应用程序的最佳实践外,还有哪些优化方法?
硬件级别的优化同样也很重要,特别是存储的优化。聊完这些,我们开始从DBA的角度去解释SAN的问题。
有许多的因素影响着磁盘的IO性能,比如共用或专用磁盘,RAID级别,总线速度,HBA的配置等。还有一个重要的但经常被忽略的因素:磁盘分区对齐(alignment in disk partitions).
还有一些非磁盘因素,也可能出现瓶颈:
-HBA和网卡
-FC的处理能力和iSCSI端口
-服务器和存储的路径数
-交换机
了解和考虑架构中相关组件的限制是非常重要的。下面是目前市场止一些组件的限制:
但是这些是怎么跟SQL Server联系起来的呢?
SQL Server中数据存储的基本单元是页(Page 8kb).分配给数据库中数据文件(无论mdf或ldf)的空间,逻辑上被分为连续的,从0到N编号的页。磁盘IO操作以页的方式实现。
硬盘由一些薄片(Platter)组成。在薄片表面的的圆型磁盘(Disk)是存储信息的电子媒体。薄片的每一面上有数以千计的磁道(Tracks)。薄片具有相同直径的磁道组成了磁柱(Cylinder)。
对于新出的设备,磁柱没有什么意义,因为他们并不以同心圆排列。但是这对于理解术语的来龙去脉还是有帮助的。
每个磁盘表面有一个专门的头(Head)用于IO。磁道被分为扇区(Sector).扇区是磁盘读写的最小片段。新出的设备能够提供1kb,3kb或4kb的扇区。
使用RAID技术,数据通过一组物理磁盘被条带化。这种数据分布的方与操作系统请求数据的方式是相辅相成的。
在后续数据存储在阵列中下一个磁盘前,数据存储在阵列中当前磁盘的粒度,叫做条带化单元大小(stripe-unit size)。(译者:这比较绕口,简单来说就是数据经过条带化后,分成多个小块存储在阵列的磁盘上。这个“块”就叫条带单元,它大小就叫条带单元大小。)从阵列中第一个磁盘到最后一个磁盘的条带单元的集合称为一个条带(Stripe)。
这就是分区对齐吗?这影响SQL Server的性能吗?下面的图示将会解释这些。
覆盖着红色梯度线的黑色虚线代表一组阵列中单个磁盘的边界。Windows Server2008之前的Windows版本,保留63个扇区用于记录磁盘硬件的信息,接下来分区中其它的可供用户使用。
如图所示,一般的扇区大小为512 bytes,图中的条带单元大小为64kb,NTFS的默认簇(Cluster)大小为4kb。(译者:簇就是一组扇区的集合,也是磁盘上分配存储空间的最小单位)
缺少磁盘对齐将迫使第八个用户数据的簇跨越两个条带单元。从第一个条带单元的最后的一个空白扇区直到第二条带单元。这种情况会延续整个分区的余下部分。因为每第N个跨越两个条带单元的簇执行一次读或写将会导致两次IO。
建议用于SQL Server的文件分配单元大小(即簇大小)为64kb。SQL Server首选的64kb的簇大小造成了默认分区错位,迫使用户数据簇跨越两个条带单元。从第一个条带单元的第一个可用扇区开始,直到第二个条带单元。这种情会延续整个分区的余下部分。这种配置注定了后续每一个用户数据簇的读写,会跨越两个磁道或者条带单元。
下面是我们的一个测试磁盘性能的实验数据,基于Windows Server2003&SQL Server 2005。通过运行一个查询从SQL Server获取信息。每次都会执行DBCC DROPCLEANBUFFERS清理缓存区高速缓存(Buffer Cache),用以保证结果可信。我们监控了用于度量磁盘延迟的性能计数器Avg.Disk Transfer/Sec。结果表明,磁盘对齐的Duration和Latency性能有明显提升,提升超过30%。
为了检验磁盘对齐,您需要清楚以下几个概念:
分区起始偏移量(Starting Partition Offset):卷中分区起始偏移量用于确定在早期卷中分配默认数据页给隐藏扇区。
条带单元大小(Stripe Unit Size):在后续数据存储在阵列中下一个磁盘前,数据存储在阵列中当前磁盘的粒度。这个由SAN管理员提供。
文件分配单元大小(File Allocation Unit Size):就是传说中的簇大小。分配磁盘空间的最小单元。此值在OS格式化分区时确定。
为了正确的磁盘分区,需要遵守两个规则:下面的两个计算结果需是整数值。
Partition_Offset / Stripe_Unit_Size
Stripe_Unit_Size / File_Allocation_Unit_size
前面两条中的第一条对性能优化非常重要。
磁盘未对齐示例场景:
某个磁盘的分区起始偏移量为32256bytes(31.5Kb),条带单元大小为65536bytes(64Kb)。Partition_Offset/Stripe_Unit_Size=0.4921875,不是整数,所以磁盘是未对齐的。
磁盘对齐示例场景:
某个磁盘的分区起始偏移量为1048576bytes(1Mb),条带单元大小为65536bytes(64Kb)。Partition_Offset/Stripe_Unit_Size=8,是整数,所以磁盘是对齐的。
经过以上的阐述,现在需要解答的问题是:怎么知道磁盘的对齐状态呢?
我们可以使用WMIC命令获取一个磁盘的偏移量的信息,语法如下:
wmic partition get BlockSize, BootPartition, DeviceID, DiskIndex, HiddenSectors, NumberOfBlocks, StartingOffset, Name, Index
这个命令可以检查SaartingOffset的值。也可以通过DISKPART获知StartingOffset,选定你要分析的磁盘执行list partition命令就可以知首offset了。检查动态磁盘的Offset,需要使用打开-v开关的dmdiag工具。
如果可以使用下面的命令检查文件分配单元大小:
fsutil fsinfo ntfsinfo [drive]
下面的图片展示了上面所有的命令:
总结
很多方面共同作用才能让磁盘发挥最佳性能。在Windows 2003上创建磁盘分区应严格验证条带单元大小和簇大小的正确关系,并做为最佳实践。Windows 2008创建分区时默认对齐。
服务器从Windows 2003更新为2008,已经存在的分区不会自动对齐,而需要重建以最佳化性能。
----------------------------------------------------------------------------------------------------------------
Joe.TJ翻译整理,原文地址:Storage Area Network (SAN) for DBA's
---------------------------------------------------------------------------------------------------------------
我的总结:
1. 原文好多地方摘抄引用了Disk Partition Alignment Best Practices for SQL Server。
2. 我是在找SAN相关资源时看到此文的,看完后发现没有什么关于SAN的内容,有标题党的嫌疑。但是对存储的介绍很有意义就翻译了出来。
3. 文中的“缺少磁盘对齐将迫使第八个用户数据的簇跨越两个条带单元。”,这是对原文的翻译并且对参照了Disk Partition Alignment Best Practices for SQL Server。
我个人对这点很是不解。64kb的条带单元=128扇区,减去隐藏的63个扇区,还有65个扇区供用户使用。每个用户数据簇4kb=8扇区,那么8个用户数据簇=64扇区。
65-64=1,所以应该是第9个用户数据簇才是跨越两个条带单元的,而不是第8个。