1 IO Scheduler
Centos6系统默认的IO调度器是CFQ(Completely Fair Queuing),Kafka是顺序IO读写模型,使用Deadline和NOOP无疑是更好地选择。
Deadline:对于读写操作有截止时间,对读和写操作用两条不同的队列管理,可以解决读取饥饿的现象。因为操作系统对读请求是同步处理的,写入请求可以异步处理。操作系统可以数据写到内存,然后对IO队列中的请求做合并,提高IO的吞吐量。通过设置read_expire < write_expire时间,避免读取操作处于饥饿调度的状态。对于数据库存储应用,Deadline是最佳的IO Scheduler,甚至很多PCIE卡作为设备内置默认参数。
NOOP:是建立在FIFO调度模型之上的,并合相邻IO请求。Noop容易出现读取操作饥饿现象,使用NOOP调度,需要磁盘有足够的IO能力。对于SSD基于闪存技术存储介质和SAN存储,NOOP也是首选的调度器。
CFQ是对每个进程维护一个IO队列,IO Scheduler对每个IO队列轮询,对于不同的进程IO请求处理是公平的,平均IO响应时间很小。每个进程队列可以设置IO优先级使得有更多的调度时间片。比较适合理算的读写模型。
传统的IO Elevator调度算法是基于减小机械盘磁头寻道时间和提高吞吐量目的设计的。IO Scheduler的选用需要根据硬件设备和应用的IO请求模式来决定。
2 充分利用内存提高kafka读写性能
之前也提到过了,数据写入到磁盘可以异步进行,先把数据放到内存中,在集中的写到外部存储上。dirty_ratio 和 dirty_background_ration适当增大,充分利用内存和文件缓存buffer。
但是还有个疑问,dirty page什么时候写回到磁盘?这个是由dirty_writeback_centisecs和dirty_expire_centisecs两个参数控制的。
dirty_writeback_centisecs,控制 pdflush/flush/kdmflush等进程的唤醒时间。
dirty_expire_centisecs,控制dirty page刷盘时间点。
减小这两个参数,可以使数据快速落盘,避免os crash引起的数据的丢失。另外,减小dirty_writeback_centisecs和dirty_expire_centisecs,解决IO Spike现象。
通过磁盘监控发现写入量wrqm/s和awit时间波动很大。
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sda 0.23 3634.10 22.63 95.70 1599.63 29838.41 265.67 0.06 0.54 0.27 3.25
sda 0.00 69.00 0.00 28.00 0.00 776.00 27.71 0.00 0.14 0.14 0.40
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 3049.00 0.00 79.00 0.00 25024.00 316.76 0.03 0.42 0.06 0.50
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda 0.00 1767.00 4.00 66.00 32.00 14664.00 209.94 0.07 0.97 0.39 2.70
sda 0.00 0.00 4.00 0.00 144.00 0.00 36.00 0.01 2.25 2.50 1.00
sda 0.00 0.00 4.00 1.00 40.00 8.00 9.60 0.03 5.80 5.60 2.80
sda 0.00 8457.00 0.00 360.00 0.00 70536.00 195.93 0.80 2.22 0.20 7.30
sda 0.00 1619.00 2.00 56.00 24.00 13400.00 231.45 0.04 0.69 0.31 1.80
sda 0.00 2.00 0.00 2.00 0.00 32.00 16.00 0.00 2.00 2.00 0.40
sda 0.00 0.00 3.00 1.00 32.00 8.00 10.00 0.00 0.00 0.00 0.00
sda 0.00 0.00 4.00 0.00 40.00 0.00 10.00 0.00 0.00 0.00 0.00
sda 0.00 8941.00 3.00 186.00 24.00 73016.00 386.46 0.73 3.87 0.12 2.30
page cache中dirty apge的数量出现骤减。
for((;;));do cat /proc/vmstat | egrep "dirty ";sleep 1 ;done
nr_dirty 25118
nr_dirty 26808
nr_dirty 28103
nr_dirty 16704
nr_dirty 18365
对于kafa来说,数据append方式追加到文件末尾,因而内存中的dirty page很少被再次更新。合理做法是把dirty page快速的flush到磁盘上,而不是默认的是30s执行一次write back。这样可以大幅度减少单次操操作的数据量,消除io-wait突然增高的现象。
dirty_writeback_centisecs=100,每1s中唤醒一次pdflush进程。
dirty_expire_centisecs=100,dirty page过了一秒就从内存写回到磁盘。
下图是io await的优化效果,经过参数调整之后,IO-await有明显的下降。
3 文件系统
我们生产上常用多块SATA做raid10,容量过时使用Ext4,很容易格式化异常(需要系统补丁支持)。Ext4系统支持最大16TB的分区,而是用XFS文件系统可以达到100TB+。相比Ext4,XFS文件系统性能更好,而稳定稍弱一点,很多参数也不需要优化。主要注意两个参数的优化:
1)nobarrier,XFS可以有数据丢失保护机制,因而可以关闭底层硬件的强制刷盘策略,何况在线机器还有raid卡保护。
2)noatime,完全没有必要的文件系统元数据的更新。
推荐的XFS挂载参数:rw,noatime,nodiratime,noikeep,nobarrier,allocsize=128M,attr2,largeio,inode64,swalloc 。关于文件系统方面,主要参考官方的建议。
参考资料:
File Cache:https://lonesysadmin.net/2013/12/22/better-linux-disk-caching-performance-vm-dirty_ratio/
Ext4:https://en.wikipedia.org/wiki/Ext4
Kafka: http://kafka.apache.org/documentation.html#appvsosflush