最近,在测试基于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

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

存储结构中的对齐(alignment)的更多相关文章

  1. C++ 学习笔记3,struct长度測试,struct存储时的对齐方式

    之所以专门为struct的长度写一篇測试,是由于原来c++对于struct的变量, 在分配内存的时候,c++对struct有一种特殊的存储机制. 看以下的測试: 一.在Windows7 32bit , ...

  2. c语言结构体在内存中存储,字节对齐

    注意: 出于效率的考虑,C语言引入了字节对齐机制,一般来说,不同的编译器字节对齐机制有所不同,但还是有以下3条通用准则: (1)结构体变量的大小能够被其最宽基本类型成员的大小所整除: (2)结构体每个 ...

  3. [c/c++] programming之路(28)、结构体存储和内存对齐+枚举类型+typedef+深拷贝和浅拷贝

    一.结构体存储 #include<stdio.h> #include<stdlib.h> struct info{ char c; //1 2 4 8 double num; ...

  4. C语言结构体在内存中的存储情况探究------内存对齐

    条件(先看一下各个基本类型都占几个字节): void size_(){ printf("char类型:%d\n", sizeof(char)); printf("int类 ...

  5. C-边界对齐

    转自:http://blog.csdn.net/b_h_l/article/details/7738197 许 多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值 ...

  6. 数据对齐 posix_memalign 函数详解

    对齐 数 据的对齐(alignment)是指数据的地址和由硬件条件决定的内存块大小之间的关系.一个变量的地址是它大小的倍数的时候,这就叫做自然对齐 (naturally aligned).例如,对于一 ...

  7. 解析C语言结构体对齐(内存对齐问题)

    C语言结构体对齐也是老生常谈的话题了.基本上是面试题的必考题.内容虽然很基础,但一不小心就会弄错.写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的 ...

  8. c语言中struct的内存对齐

    为了让CPU能够更舒服地访问到变量,struct中的各成员变量的存储地址有一套对齐的机制.这个机制概括起来有两点:第一,每个成员变量的首地址,必须是它的类型的对齐值的整数倍,如果不满足,它与前一个成员 ...

  9. C语言-结构体内存对齐

    C语言结构体对齐也是老生常谈的话题了.基本上是面试题的必考题.内容虽然很基础,但一不小心就会弄错.写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的 ...

随机推荐

  1. Yum本地源配置

    1.mount -t auto /dev/cdrom /mnt      使用光驱 mount -t iso9660 -o loop /home/software/rhel-server-6.4-x8 ...

  2. iphone练习之手势识别(双击、捏、旋转、拖动、划动、长按)UITapGestureRecognizer

    首先新建一个基于Sigle view Application的项目,名为GestureTest;我的项目结构如下: 往viewController.xib文件里拖动一个imageView,并使覆盖整个 ...

  3. 转载 SharePoint【Site Definition 系列】– 创建Content Type

    转载原地址:  http://www.cnblogs.com/wsdj-ITtech/archive/2012/09/01/2470274.html Sharepoint本身就是一个丰富的大容器,里面 ...

  4. cocos2d-x 3.0 开发(一) Hello_New_World

    1.Previous On 2dx     2dx 的3.0版本是个与以往不同的版本.变化比2dx从1.x 到2.x的变化还要大不少.具体的新功能可以参见:CocoaChina大会见闻——cocos2 ...

  5. express源码剖析2

    当使用express时,代码会这样写: var express = require('express'); 如果创建一个express的应用,代码会这样写: var app = express(); ...

  6. [一位菜鸟的COCOS-2D编程之路]打飞机中机种敌机和战机损毁时的爆炸效果

    1.第一步,添加爆炸动画 //添加玩家飞机飞行动画 id _playerFlyAction; id _playerBlowupAnimation; //战机爆炸动画 id _enemyBlowupAn ...

  7. 转(HP大中华区总裁孙振耀退休感言)

    开篇转发一篇好文,苦闷,消沉,寂寞,堕落的时候看看. 发现这篇文章是09年之前就有人转发到自己博客了.放到自己的地盘,容易记起有这么个心灵鸡汤.   一.关于工作与生活 我有个有趣的观察,外企公司多的 ...

  8. 剑指OFFER之第一个只出现一次的字符(九度OJ1283)

    题目描述: 在一个字符串(1<=字符串长度<=10000,全部由大写字母组成)中找到第一个只出现一次的字符. 输入: 输入有多组数据每一组输入一个字符串. 输出: 输出第一个只出现一次的字 ...

  9. mysql数据库全局只读和会话只读问题解析

    对于系统的发布是经常有的事情,有些时候需要隔绝外界对数据库的更改但是还要求可以读取数据,对于mss sql 这个就是很简单,直接属性—>选项—>只读 ,但是对于mysql这是不同的,今天仔 ...

  10. MinGW安装和使用总结

    0.前言 最近对开源编译平台和编译器产生了兴趣,借博客平台总结一些东西(包括minGW,eclipse,sourcery和GDB调试等内容).总感觉时间一长某些东西自己都会忘记,过段时间回头看看自己的 ...