了解附加模式下的闪存文件系统磨损

Understanding flash file system wear in append mode

本文关键字:闪存 文件系统 模式 了解      更新时间:2023-10-16

我必须在闪存设备(MMC卡)上写入一个不断增长的日志文件,我担心闪存磨损。

假设我使用fopenstd::ofsteam::open以写/附加模式打开日志文件。该文件目前的大小为10MB。如果我只继续追加到文件中,我能保证文件系统不会试图将以前的10MB重新写入新的闪存块吗?

如果这还不清楚,我可以用不同的方式问同样的问题。考虑这个场景:

  1. 创建一个名为"log.txt"的新文件
  2. 向文件追加10kB
  3. 关闭文件
  4. 其他进程写入同一磁盘/分区上的不同文件
  5. 重新打开"log.txt"
  6. 向文件再追加10kB
  7. 关闭文件

这是否具有与这种情况相同的效果(就闪光磨损而言):

  1. 创建一个名为"log.txt"的新文件
  2. 向文件追加20kB
  3. 关闭文件

大多数闪存文件系统都会内置损耗均衡系统,这样就不会反复使用同一部分闪存。

追加不应该是个问题,因为(我希望)当它存储信息时,写入新数据时不会"磨损"——你只会在"擦除"周期中受到磨损,只有当你删除文件时才会发生这种情况[并且文件所在的扇区需要用新数据重写-如果内容不被替换,那么擦除内容就没有意义]。

为了回答您的实际问题,最好使用附加模式,而不是编写另一个新文件。至少你没有"磨损"文件中已经写入的部分——当涉及到闪存时,碎片应该不会成为问题——访问字节0、1、1000和10000000000000需要完全相同的时间,而不是一个老式的硬盘驱动器,在这种硬盘驱动器中,机械头每隔几次读取就必须移动到下一个数据块,较长的移动需要较长的时间。

如果我只继续追加到文件中,我能保证文件系统不会试图将以前的10MB重新写入新的闪存块吗?

这取决于闪存文件系统。与你的愿望相反,有时重写之前的10MB实际上是件好事。也就是说,执行磨损均衡。每个闪存芯片都有一个扇区擦除块大小。这些影响了磨损均衡的动态。每个擦除块在一个生命周期内具有最大周期量。如果你的10MB文件几乎是满闪存,那么移动一些扇区是有意义的,这样就可以在那里进行新的擦除。这在wikipedia的磨损平衡页面上被称为静态磨损平衡

闪存芯片的典型擦除周期为10k-10M。因此,通常情况下,闪存文件系统应级别擦除所有扇区+/-1k内的内容。大多数磁盘都有长期数据和短期数据。希望这能解释移动长寿命数据的必要性。

此外,许多闪存文件系统支持压缩。追加时,应尽量将保持为扇区大小或压缩块大小的最大值。从C++层,这将自然地缓冲在任务级别的内存中。您可以将缓冲区大小设置为匹配和/或仅在确定已写入完整扇区时调用flush()。写入部分扇区(或压缩块)的问题是,这将留下许多部分写入,直到填满完整的擦除块。然后,所有的部分写入都将被擦除。

您不必在应用程序级别注意这一点,但像这样更改日志记录可以显著延长闪存的寿命。当然,一切都在某种程度上取决于闪存文件系统。并非所有这些都会移动静态数据,以确保擦除磨损均衡。它们只能在自由区域上预成型耐磨层;或未使用的闪存空间。