打通IO栈:一次编译服务器性能优化实战( 五 )


咱们回到当前待优化的服务器 , 当前使用的是什么IO调度器呢?
# cat /sys/block/vda/queue/schedulernone# cat /sys/block/sda/queue/schedulernoop [deadline] cfq这服务器的内核版本是
# uname -r3.13.0-170-generic查看Linux内核git提交记录 , 发现在 3.13.0 的内核版本上还没有实现适用于多队列的IO调度算法 , 且此时还没完全切到多队列架构 , 因此使用单队列的 sda 设备依然存在传统的noop , deadline和cfq调度算法 , 而使用多队列的 vda 设备(virtio)的IO调度算法只有none 。 为了使用mq-deadline调度算法把内核升级的风险似乎很大 。 因此IO调度算法方面没太多可优化的 。
但Request层优化只能这样了?既然IO调度算法无法优化 , 我们是否可以修改queue相关的参数?例如加大Request队列的长度 , 加大预读的数据量 。
在/sys/block/vda/queue中有两个可写的文件nr_requests和read_ahead_kb , 前者是配置块层最大可以申请的request数量 , 后者是预读最大的数据量 。 默认情况下 ,
nr_request = 128read_ahead_kb = 128我扩大为
nr_request = 1024read_ahead_kb = 512优化效果优化后 , 在满负荷的情况下 , 查看内存使用情况:
# cat /proc/meminfoMemTotal:49459060 kBMemFree:1233512 kBBuffers:12643752 kBCached:21447280 kBActive:19860928 kBInactive:16930904 kBActive(anon):2704008 kBInactive(anon):19004 kBActive(file):17156920 kBInactive(file): 16911900 kB...Dirty:7437540 kBWriteback:1456 kB可以看到 , 文件相关内存(Active(file) + Inactive(file) )达到了32.49GB , 脏数据达到7.09GB 。 脏数据量比预期要少 , 远没达到dirty_background_ratio和dirty_ratio设置的阈值 。 因此 , 如果需要缓存更多的写数据 , 只能延长定时唤醒回刷的时间dirty_writeback_centisecs 。 这个服务器主要用于编译SDK , 读的需求远大于写 , 因此缓存更多的脏数据没太大意义 。
我还发现Buffers达到了12G , 应该是ext4的inode占用了大量的缓存 。 如上分析的 , 此服务器的ext4有大量富余的inode , 在缓存的元数据里 , 无效的inode不知道占比多少 。 减少inode数量 , 提高inode利用率 , 说不定可以提高inode预读的命中率 。
优化后 , 一次使能8个SDK并行编译 , 走完一次完整的编译流程(包括更新代码 , 抓取提交 , 编译内核 , 编译SDK等) , 在没有进入错误处理流程的情况下 , 用时大概13分钟 。
这次的优化就到这里结束了 , 等后期使用过程如果还有问题再做调整 。
【打通IO栈:一次编译服务器性能优化实战】本文来自公众号:Linux阅码场 , 作者:廖威雄 , 就职于珠海全志科技股份有限公司 , 负责Linux IO全栈研发、性能优化、开源社区开发交流、Linux 内核开源社区pstore/blk,mtdpstore模块的作者(与maintainer交流中)、大客户存储技术支持、全志首个UBI存储方案主导人、全志首个RTOS NFTL主导人 。