我管理的大多数 Linux 系统都配有硬件 RAID 控制器(大部分HP 智能阵列)。它们都运行 RHEL 或 CentOS。
我正在寻找实际可调参数,以帮助优化包含硬件 RAID 控制器和 SAS 磁盘(智能阵列、Perc、LSI 等)以及电池支持或闪存支持的缓存的设置的性能。假设 RAID 1+0 和多个主轴(4 个以上磁盘)。
我花了大量时间来调整 Linux 网络设置,以实现低延迟和金融交易应用程序。但其中许多选项都有详细记录(更改发送/接收缓冲区、修改 TCP 窗口设置等)。工程师在存储方面做什么?
从历史上看,我曾对I/O调度电梯,最近选择了deadline
和noop
调度程序来提高我的应用程序的性能。随着 RHEL 版本的进步,我还注意到 SCSI 和 CCISS 块设备的编译默认值也发生了变化。随着时间的推移,这对推荐的存储子系统设置产生了影响。但是,我已经有一段时间没有看到任何明确的建议了。而且我知道操作系统的默认值并不是最佳的。例如,对于服务器级硬件上的部署来说,128kb 的默认预读缓冲区似乎非常小。
以下文章探讨了更改预读缓存和请求数块队列上的值。
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 Smart Array RAID 控制器的建议更改:
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 选项。
答案1
我发现,当我必须调整以降低延迟与吞吐量时,我会将 nr_requests 从其默认值调低(低至 32)。其理念是,更小的批次等于更低的延迟。
对于 read_ahead_kb,我发现对于顺序读取/写入,增加此值可以提供更好的吞吐量,但我发现此选项实际上取决于您的工作负载和 IO 模式。例如,在我最近调整的数据库系统上,我将此值更改为匹配单个数据库页面大小,这有助于减少读取延迟。在我的案例中,增加或减少超过此值都会损害性能。
至于块设备队列的其他选项或设置:
最大扇区数= 我已将此值设置为与硬件允许的单次传输值相匹配(检查 sysfs 中的 max_hw_sectors_kb(RO)文件的值以查看允许的值)
名词= 这可让您禁用或调整合并 io 请求的查找逻辑。(关闭此功能可以节省一些 CPU 周期,但我没有看到在我的系统中更改此功能有什么好处,因此我将其保留为默认设置)
rq_affinity= 我还没有尝试过,但是这是内核文档中对此的解释
如果此选项为“1”,则块层将请求完成迁移到最初提交请求的 CPU“组”。对于某些工作负载,由于缓存效应,这可以显著减少 CPU 周期。
对于需要最大化完成处理分布的存储配置,将此选项设置为“2”会强制完成在请求的 CPU 上运行(绕过“组”聚合逻辑)”
调度程序= 您说您尝试了 deadline 和 noop。我测试了 noop 和 deadline,但在我最近为数据库服务器进行的测试中发现 deadline 胜出。
NOOP 表现良好,但对于我们的数据库服务器,我仍然能够通过调整截止期限调度程序实现更好的性能。
位于 /sys/block/{sd,cciss,dm-}*/queue/iosched/ 下的截止期限调度程序的选项:
fifo_batch= 有点像 nr_requests,但特定于调度程序。经验法则是将其调低以降低延迟或调高以增加吞吐量。控制读取和写入请求的批处理大小。
写入有效期= 设置批量写入的过期时间,默认为 5000ms。再次降低此值可降低写入延迟,而增加此值可提高吞吐量。
读取过期时间= 设置读取批次的过期时间,默认为 500ms。此处适用相同规则。
前端合并= 我倾向于关闭此功能,但默认情况下它是打开的。我认为调度程序没有必要浪费 CPU 周期来尝试合并 IO 请求。
写入饥饿= 由于 deadline 是针对读取的,因此这里的默认值是在处理写入批次之前处理 2 个读取批次。我发现默认值 2 对我的工作量来说很合适。
答案2
最重要的是,一切都取决于你的工作量。
read_ahead_kb
如果提前从某个文件读取大量数据确实很有帮助,例如在流式传输视频时,它可以为您提供帮助。有时,这可能会对您造成严重伤害。是的,默认的 128 KB 听起来很小,但只要有足够的并发性,它就会开始听起来很大!另一方面,对于仅将视频从一种格式转换为另一种格式的视频编码服务器等服务器,这可能是一个非常好的调整主意。
nr_requests
当过度调整时,很容易淹没您的 RAID 控制器,从而再次损害性能。
在现实世界中,你需要观察延迟iostat
。如果您已连接到 SAN,请使用 或任何您喜欢使用的工具查看sar
,看看 I/O 请求服务时间是否过长。当然,这也有助于本地磁盘:如果延迟非常大,请考虑通过降低 max_requests 和其他设置来调低 I/O 提升设置。
答案3
read_ahead_kb
仅供参考blockdev --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
在您的示例中没有效果。