不知道大家有没有考虑过这样一个问题:在RAID中是否可以支持TRIM操作?

 

试想在SSD上建立RAID之后,应用软件(文件系统)直接运行在RAID软件之上,那么此时如何通过TRIM命令将SSD中的数据块unmap掉呢?看起来这好像不是一个问题,其实对于RAID而言这是一个比较大的问题。存储老吴可以带领大家从研发人员的角度一探RAIDTRIM所引入的问题,从中也可以一窥用户所应该注意的问题。

 

目前,RAID方面的开源软件是MD,很多用户对MD这套软件是非常热衷的。认为这套软件运行非常的稳定,性能不错,功能很全,并且还有很多技术人员对其进行免费开源维护。其实,和专业的RAID存储软件相比,MD就是一个演示系统。目前,在MD软件中是不支持SSDTRIM操作的,不是说不想加入这个功能,而是并不容易添加这个功能,这会涉及到很多的开发工作量。

 

对于SSDTRIM操作,其主要想法是通过释放SSD内部一个逻辑地址(LBA)的映射数据块来提升SSD本身的性能。这主要是由于SSD内部采用FTL的方式对所有写入数据采用Append write(追加写)的方式,所以,当没有空闲资源的时候,SSD需要通过启动垃圾回收来获取空闲资源。垃圾回收对SSD的性能影响巨大,因此,如果业务能够主动释放空闲资源,那么SSD内部的垃圾回收就会轻松很多,从而可以提升SSD本身性能。TRIM操作就是让应用层主动释放空闲资源的机制。

 

当应用软件直接架构在SSD上时,其可以很容易的向SSD通过发送TRIM命令来回收资源。但是,在应用软件和SSD之间引入RAID之后,情况发生了巨大变化。首先,让我们来认识一下一个普通的RAID数据布局,这个数据布局会显得非常规整:

wKioL1XCNcWz5NlxAAC0t656BIg065.jpg


在这样的数据布局中,每个条带都会存在一个数据校验块(RAID5),一旦条带中的一个数据块发生故障时,通过校验数据P就可以恢复故障数据。假设此时,位于RAID之上的文件系统想要TRIM一个数据块,这个数据块正好落在SSD1D数据块区域。对于这种操作,RAID需要做什么呢?一个很直观的操作是当RAIDSSD1上的D数据块TRIM掉之后,需要更新这个条带中的P数据块。原因在于TRIM操作之后,SSD1上的D数据块发生了变化,如果想要保证条带数据的一致性,必须更新P数据块。条带中一个数据块的TRIM操作引发了条带校验数据的更新。这是条带RAIDTRIM操作的重要代价。

 

其实,事实远比条带更新更加糟糕。一个SSD中的数据块被TRIM之后,这个数据块中的数据会变的不确定。例如一个数据块被TRIM之后,读取的数据可能和原来一样,也有可能为零。并且随着时间的变化,存储块TRIM之后的数据会发生变化。而这完全取决于SSD内部固件程序的实现。这种数据的不确定性给RAID带来的致命的数据正确性问题。例如,上述案例中SSD1中的D数据块被TRIM之后,根据TRIM之后的数据更新P校验数据。过一段时间之后SSD1中的D数据块可能发生了变化,此时整个条带的数据将会处于不一致性状态,对数据的正确性造成影响。

 

从上述分析来看,RAID的数据TRIM最好以条带为单位,当一个条带中的数据全部可以TRIM,那么此时才可以对SSD发送TRIM操作命令。所以,在RAID中,TRIM操作被放大到了条带级别,不再是原来的Sector块级别操作了。

 

但是,通常RAID设备暴露给用户仍然是Sector级别的块设备对象,文件系统仍然会给RAID发送Sector级别的TRIM操作。对于这种情况,RAID如何将Sector级别的TRIM操作转换成条带级别的TRIM呢?这就需要RAID内部进行TRIM的合并,例如通过采用Bitmap机制将TRIM操作记录下来,当合并到一定程度之后,再对整条带进行TRIM操作。这种设计将会造成较大的实现复杂度,并且还有很多的问题需要考虑,例如Bitmap占用内存容量,异常掉电等问题。所以,一个优秀的RAID数据保护软件,将TRIM问题处理好是需要化一番真功夫的,并不是一件很容易的事情。

 

(来自存储老吴的博客——存储之道)