ZFS的ashift参数解读

引言

在使用ZFS的时候发现一个现象,创建一个ZFS卷后,某些情况下这个卷在zpool中占用的空间比实际使用的空间大很多,这个问题的出现让人不禁一身冷汗,难道ZFS在某些情况下会导致大量空间损耗,我们来一步步的分析下这个问题。

测试分析

首先想到的可能原因就是blocksize,测试结果也正如我们所料,如下图,在8K的时候正常,但是在4K的时候却出现了,而且正好是放大两倍:
image.png

但是问题就这么简单? No No No(手动摇头)

先是理论上就讲不通,因为底层盘如果是HDD那么它的sector(扇区)是512B,如果是SSD那么就是4K(可能存在8K的,我们使用的均是4K),所以无论底层盘是什么,IO的最小操作单位只要不小于4K就不会引起放大,所以ZFS卷的blocksize设为4K还出现这个问题就说不通。第二点就是,我们之前测试了很多次的4K的blocksize都没有发现这个问题,于是找到一个之前的老环境,结果发现无论4K还是8K都是正常结果,这就尴尬了,只能先喝杯水淡定下。

重新对比下环境,操作系统、ZFS版本,创建卷的过程都一样,唯一不一样的就是不是同一个zpool,而创建zpool的过程中我们改动的唯一参数就是——ashift,这个从来没引起我注意的参数,然后就查了下它的官方解释:

Top-level vdevs contain an internal property called ashift, which stands for alignment shift. It is set at vdev creation and it is immutable. It can be read using the zdb command. It is calculated as the maximum base 2 logarithm of the physical sector size of any child vdev and it alters the disk format such that writes are always done according to it. This makes 2^ashift the smallest possible IO on a vdev.

这段说明总结起来就是——ashift参数就是设置zpool中对于底层IO操作的最小单位,它的值是以2为底的IO最小操单位的对数,豁然开朗!

验证

于是通过zdb命令查询下这个参数的值,不出所料有问题的zpool中ashift设置的是13,同时在不设置这个ashift参数的方式新创建新的zpool也不会出现这个问题。

找到问题了!但是,慢着!到底是谁设置这个参数为13的?算了,不管了(手动甩锅)… …


深入讨论

接着说ashift参数,它会根据底层盘的驱动报告的sector(扇区)大小自动设置,比如底层盘为HDD一般会报告自己的sector(扇区)为512B,那么ashift的默认值就是9,所以看起来如果不设置就没问题,但是Flash-based的存储设备(例如Flash卡)可能由于某些原因并不会准确的报告自己的sector(扇区),它们可能会伪装成512B,实际却是4K或者8K,因此设置ashift某些情况下是必须的。

整个存储模型分为三层,它们共同决定了这个异常现象的出现:

1. zvol的blocksize

2. zpool的逻辑sector(ashift控制)

3. 物理sector

如果要使整个存储模型运转正常,必须满足如下公式:

zvol的blocksize  >=  zpool的逻辑sector  >=  物理sector

番外

最后说一句题外话:硬件的标准的参差不齐着实让人头痛,只能硬件不够软件凑了。

猜你喜欢

转载自blog.csdn.net/zhanghedong526/article/details/80058535
zfs