存储结构中的对齐(alignment)

  最近,在测试基于ceph的小文件合并方案(见上个博文)时,遇到一个怪异的现象:将librados提供的append接口与我们封装的WriteFullObj接口(osd端是append操作和kvdb的put操作)对比,在处理同样大小的文件时(如4KB,8KB等),WriteFullObj比librados的append操作tps低很多,最初怀疑可能是kvdb的put操作的原因,后来将osd端kvdb的put临时去掉,tps仍然上不去;后来使用iostat观察osd上状态,发现WriteFullObj时,uitl在50%左右,wait cpu在40左右,而librados的append则没这么高。。。。。。。。。。。再仔细观察,WriteFullObj时,r/s对应read操作在30甚至更高,而librados的append则几乎为0。。。。。。。。。。再比较二者的差异,将librados的append操作在刚刚WriteFullObj操作的文件,现象和WriteFullObj一样了。。。。再比较两个操作的文件差异,WriteFullObj操作文件大小非4KB整数倍,非4KB整数倍大小是在情理之中,因为合并时,每个小文件数据前附加了36B大小的元数据描述信息,但这为什么会影响写的性能表现和上述现象呢?脑中闪现以前做磁盘分区时遇到的情况:“warning:partition is not properly aligned for best performance”;那么在读写文件时,是否也要类似地保持alignment以提升性能呢?

经过研究结果如下:

扇区(sector)是磁盘的最小存储单位,通常为512B;块(block)是文件系统中存取的最小单位,通常为1024、2048或4096B,块也是文件系统分配和回收空间的最小单位;

当write向文件末尾追加数据时,文件系统会尝试为数据分配数据块,如果是对数据块的部分写入操作,则需要先将数据块的数据读出(此时可能会被阻塞),然后再整体写入(fetch-before-write)

当一个磁盘文件大小非4KB(块大小)整数倍大小,在文件末尾追加数据就是上述的部分写入操作,从而出现上述read操作很高的现象;

为了证实上述结论,测试如下:

A. 文件系统块大小4KB,调用librados的append操作,每次append数据量大小为1KB,文件最初不存在;

B. 用iostat查看,第4k+1次append时,read量几乎为0;第4k+2、4k+3、4k+4次append时,read量开始飙升;

符合预期;

同样原理,跨block读也无法将系统性能充分发挥;

为了充分提供系统性能,设计存储结构时就需要避免此类情况,业界常用的方案就是padding,write操作在4KB整数位置处;

 

参考:

http://www.seagate.com/cn/zh/tech-insights/advanced-format-4k-sector-hard-drives-master-ti/

https://blogs.oracle.com/dlutz/entry/partition_alignment_guidelines_for_unified

https://www.usenix.org/system/files/conference/fast15/fast15-paper-campello.pdf

http://www.storage-switzerland.com/Articles/Entries/2011/10/27_Improving_VMware_Storage_I_O_Performance_By_Realigning_Partitions.html

http://www.storagereview.com/the_impact_of_misalignment

http://noops.me/?p=747

------------------------------------

http://www.cnblogs.com/wuhuiyuan/p/4760030.html

个人原创,转载请注明出处。

posted @ 2015-08-27 23:26  it_arch_notes  阅读(2930)  评论(0编辑  收藏  举报