Linux – 真实世界的硬件RAID控制器调优(scsi和cciss)

我pipe理的大部分Linux系统都是function硬件RAID控制器(主要是HP Smart Array )。 他们都运行RHEL或CentOS。

我正在寻找真实世界的可调参数来帮助优化将硬盘RAID控制器与SAS磁盘(Smart Array,Perc,LSI等)以及电池供电或闪存备份caching相结合的设置的性能。 假设RAID 1 + 0和多个主轴(4个以上的磁盘)。

我花了相当多的时间调整Linuxnetworking设置以适应低延迟和金融交易应用。 但是其中的许多选项都有详细logging(更改发送/接收缓冲区,修改TCP窗口设置等)。 工程师在存储方面做了什么?

从历史上看,我对I / O调度电梯进行了修改,最近select了deadlinenoop调度程序来提高我的应用程序的性能。 随着RHEL版本的进步,我也注意到SCSI和CCISS块设备的编译默认值也发生了变化。 这对build议的存储子系统设置随着时间的推移已经产生了影响。 但是,从我看到任何明确的build议已经有一段时间了。 而且我知道操作系统默认不是最佳的。 例如,对于在服务器级硬件上部署,似乎128kb的默认预读缓冲区非常小。

以下文章探讨了在块队列上更改预读caching和nr_requests值的性能影响。

http://zackreed.me/articles/54-hp-smart-array-p410-controller-tuning
http://www.overclock.net/t/515068/tuning-a-hp-smart-array-p400-with-linux-why-tuning-really-matters
http://yoshinorimatsunobu.blogspot.com/2009/04/linux-io-scheduler-queue-size-and.html

例如,这些是对HP智能arraysRAID控制器的build议更改:

 echo "noop" > /sys/block/cciss\!c0d0/queue/scheduler blockdev --setra 65536 /dev/cciss/c0d0 echo 512 > /sys/block/cciss\!c0d0/queue/nr_requests echo 2048 > /sys/block/cciss\!c0d0/queue/read_ahead_kb 

还有什么可以可靠地调整,以提高存储性能?
我特别在生产场景中寻找sysctl和sysfs选项。

我发现,当我不得不调整较低的延迟时间和吞吐量时,我已经将nr_request从默认值调低(低至32)。 小批量的想法等于较低的等待时间。

另外对于read_ahead_kb,我发现对于连续读取/写入,增加此值可以提供更好的吞吐量,但是我发现这个选项实际上取决于您的工作负载和IO模式。 例如,在我最近调整的数据库系统上,我改变了这个值来匹配单个数据库页面大小,这有助于减less读取延迟。 超过这个数值的增加或减lesscertificate会伤害我的情况。

至于块设备队列的其他选项或设置:

max_sectors_kb =我已经设置了这个值,以匹配硬件允许进行单次传输(检查sysfs中的max_hw_sectors_kb(RO)文件的值以查看允许的内容)

nomerges =这可以让你禁用或调整查询逻辑来合并io请求。 (closures这个function可以节省一些CPU周期,但是在改变我的系统时我没有看到任何好处,所以我将它保留为默认值)

rq_affinity =我还没有尝试过,但这里是从内核文档背后的解释

如果这个选项是'1',块层将请求完成迁移到最初提交请求的CPU“组”。 对于一些工作负载,由于caching效应,这提供了CPU周期的显着减less。
对于需要最大化完成处理分配的存储configuration,将此选项设置为“2”将强制完成在请求的cpu上运行(绕过“组”聚合逻辑)“

scheduleler =你说你试过截止date和noop。 我已经testing了noop和截止date,但是已经发现了最近为数据库服务器所做的testing的截止date。

NOOPperformance良好,但对于我们的数据库服务器,我仍然能够更好地调整截止date调度程序的性能。

位于/ sys / block / {sd,cciss,dm – } * / queue / iosched /下的最后期限调度程序选项

fifo_batch =类似nr_requests,但是特定于调度程序。 经验法则是将其调整为较低的延迟或提高吞吐量。 控制读取和写入请求的批量大小。

write_expire =设置批量写入的过期时间为5000ms。 再次减小这个值会减less写入延迟,同时增加值会增加吞吐量。

read_expire =设置批量读取的过期时间为500ms。 这里适用相同的规则。

front_merges =我倾向于closures此function,并且默认情况下已启用。 我看不到调度程序需要浪费CPU周期来尝试合并IO请求。

writes_starved =由于最后期限是读取默认值,因此在处理写入批次之前处理2个读取批次。 我发现缺省值2对我的工作负载很好。

一切都取决于你的工作量。

如果提前从某个文件读取大量数据(如stream式传输video), read_ahead_kb可以帮助您。 有时它会严重伤害你。 是的,默认的128KB听起来可能很小,但是具有足够的并发性,听起来就像是大的! 另一方面,对于仅将video从格式转换为另一格式的诸如video编码服务器的服务器,调谐可能是非常好的想法。

nr_requests ,当被推翻时,可以很容易地泛滥你的RAID控制器,这再次损害性能。

在现实世界中,你需要观察延迟 。 如果您连接到SAN,请使用iostatsar或任何您喜欢使用的任何设备,查看I / O请求服务时间是否在屋顶。 当然,这对本地磁盘也有帮助:如果延迟非常大,请考虑通过降低max_requests和其他设置来调整I / O电梯设置。

仅供参考read_ahead_kbblockdev --setra是使用不同单位 (kB对扇区) 设置相同设置的不同方法 :

 foo:~# blockdev --setra 65536 /dev/cciss/c0d0 foo:~# blockdev --getra /dev/cciss/c0d0 65536 foo:~# cat /sys/block/cciss\!c0d0/queue/read_ahead_kb 32768 foo:~# echo 2048 > /sys/block/cciss\!c0d0/queue/read_ahead_kb foo:~# cat /sys/block/cciss\!c0d0/queue/read_ahead_kb 2048 foo:~# blockdev --getra /dev/cciss/c0d0 4096 

所以

 blockdev --setra 65536 /dev/cciss/c0d0 

在你的例子中没有效果。