1. 首页
  2. 源码解析
  3. 存储与数据库
  4. SSD 的探讨

SSD 的探讨

  • 发布于 2024-10-24
  • 13 次阅读

这篇文章主要来探讨一下SSD相关的问题,以及我们在写代码的时候如何更高效的利用好 SSD 的特性。


SSD 基本特性介绍

  • 读写性能特点

    • SSD(Solid - State Drive)与传统机械硬盘(HDD)相比,具有显著的读写性能优势。其顺序读写速度很快,而且随机读写性能更是远超 HDD。例如,SATA 接口的 SSD 顺序读取速度可达 500MB/s 以上,顺序写入速度可达 500MB/s 以上,而 4K 随机读取速度(衡量小文件和随机访问性能的重要指标)可以轻松达到几十 MB/s 甚至更高,这对于频繁进行小文件读写或者随机访问的应用场景非常有利。

  • 内部存储结构和工作原理

    • SSD 主要由主控芯片、闪存芯片(NAND Flash)、缓存芯片(部分有)等组成。闪存芯片是存储数据的核心部件,数据以二进制的形式存储在闪存芯片的晶体管中。主控芯片管理和传输数据,类似于电脑的 CPU,它决定了 SSD 的读写性能和数据传输速度。当系统发出读写请求时,主控芯片会根据闪存芯片的物理地址和逻辑地址映射关系,快速定位并读写数据。

  • 数据存储单元和寿命问题

    • SSD 的数据存储单元是闪存芯片中的闪存颗粒。闪存颗粒有不同的类型,如 SLC(Single - Level Cell)、MLC(Multi - Level Cell)和 TLC(Triple - Level Cell)。SLC 存储单元可以存储 1 位数据,MLC 存储 2 位,TLC 存储 3 位。SLC 性能和寿命最佳,但成本高;TLC 成本低,但性能和寿命相对较短。闪存芯片有写入寿命限制(P/E Cycles - Program/Erase Cycles),即闪存芯片可以承受的写入 / 擦除循环次数。例如,TLC 闪存一般的 P/E Cycles 在 1000 - 3000 次左右,超过这个次数,闪存单元可能会出现数据错误或者损坏。

  1. 在代码中高效利用 SSD 特性的方法

    • 数据存储和访问模式优化

      • 对齐读写操作:由于 SSD 的内部存储结构特点,数据的读写操作最好按照闪存芯片的物理块大小进行对齐。例如,很多 SSD 的物理块大小是 4KB,在进行文件存储或者数据库存储时,尽量让数据的读写单位是 4KB 的倍数,这样可以充分利用 SSD 的读写性能,减少额外的读写操作。在编程中,可以通过内存分配函数或者文件系统接口来实现数据块的对齐。

      • 顺序读写优化:对于有大量顺序读写需求的应用,如日志文件系统或者视频流存储系统,应该尽量将数据按照顺序写入 SSD。可以通过缓存数据,等到数据量达到一定规模后再一次性顺序写入。在读取数据时,也尽量按照顺序读取,避免随机跳转到不同位置读取小片段数据,这样可以充分发挥 SSD 优秀的顺序读写性能。

    • 文件系统和数据库层面的优化

      • 文件系统选择和配置:选择支持 SSD 特性的文件系统。例如,ext4(Linux)和 NTFS(Windows)在 SSD 环境下都有一定的优化。在配置文件系统时,可以调整参数来适应 SSD。如在 ext4 中,可以调整 inode 大小、块大小等参数,以提高文件系统在 SSD 上的性能。同时,一些新型的文件系统专门为 SSD 设计,如 F2FS(Flash - Friendly File System),它考虑了 SSD 的闪存特性,如磨损均衡、垃圾回收等,能更好地利用 SSD。

      • 数据库存储引擎优化:对于数据库应用,选择合适的存储引擎并进行优化。例如,在使用基于 LSM 树(如 LevelDB、RocksDB)的存储引擎时,由于其对顺序写友好的特性,可以更好地利用 SSD 的性能。在数据库设计中,可以优化索引结构,如 B + Tree 索引的节点大小可以根据 SSD 的块大小进行调整,以减少磁盘 I/O 次数。同时,数据库的缓存策略也很重要,通过合理设置缓存大小和缓存替换策略,可以减少对 SSD 的频繁访问。

    • 内存管理和缓存策略

      • 数据缓存机制:在应用程序中,可以建立数据缓存来减少对 SSD 的直接访问。例如,使用 LRU(Least Recently Used)缓存策略,将经常访问的数据存储在内存缓存中。当需要访问数据时,首先在缓存中查找,如果找到就直接使用,避免了 SSD 的读写操作。同时,缓存的大小应该根据应用程序的内存限制和数据访问模式来合理设置,以达到最佳的性能平衡。

      • 预取和预加载策略:根据应用程序的使用模式,采用预取和预加载策略。例如,在一个图像查看应用中,当用户查看一张图片时,可以预先加载下一张或几张可能查看的图片到内存缓存中。在代码实现中,可以通过分析用户行为或者数据访问的顺序规律,提前将相关数据从 SSD 读取到内存中,提高用户体验和系统性能。

当然,SSD(固态硬盘)具有许多与传统HDD(机械硬盘)不同的特性,这些特性在编写高效代码时需要特别考虑。以下是一些关键点,可以帮助你在写代码时更好地利用SSD的特性:

SSD 的主要特性

  1. 高速随机读写

    • SSD 在随机读写操作上的性能远高于 HDD。这意味着在处理小文件、索引和数据库等需要频繁随机访问的应用中,SSD 能够提供显著的性能提升。

  2. 无寻道时间

    • 由于 SSD 没有机械部件,因此不存在寻道时间和旋转延迟。这使得 SSD 在处理 I/O 密集型任务时更加高效。

  3. 低延迟

    • SSD 的读写延迟非常低,通常在几微秒到几十微秒之间。这对于实时系统和对延迟敏感的应用非常重要。

  4. 有限的写入寿命

    • SSD 的闪存单元有一定的写入寿命限制,称为 P/E 周期(编程/擦除周期)。过度的写入操作会缩短 SSD 的使用寿命。

    • 现代 SSD 通过磨损均衡算法来延长使用寿命,但开发者仍需注意减少不必要的写入操作。

  5. 写放大

    • SSD 的写放大是指实际写入的数据量比用户请求写入的数据量大。这是由于 SSD 的内部管理机制(如垃圾回收和数据搬移)导致的。写放大越高,SSD 的性能和寿命都会受到影响。

  6. TRIM 命令

    • TRIM 命令允许操作系统通知 SSD 哪些块不再使用,从而可以被回收。这有助于提高后续写入操作的性能,并减少写放大。

编写高效代码以利用 SSD 特性

1. 减少不必要的写入操作

  • 合并写入:尽量将多个小的写入操作合并成一个大的写入操作。例如,在日志记录或缓存刷新时,可以累积一定数量的数据后再进行一次写入。

  • 避免重复写入:确保不会重复写入相同的数据。例如,使用高效的缓存策略来避免频繁更新相同的文件或数据块。

  • 批量操作:对于数据库操作,尽量使用批量插入或更新,而不是逐条插入或更新。

2. 优化读取模式

  • 预读:利用预读技术提前加载可能需要的数据,减少 I/O 请求次数。例如,可以在读取一个文件时,同时预读相邻的数据块。

  • 减少随机读取:尽量减少随机读取操作,改为顺序读取。例如,通过合理设计数据结构和存储格式,使相关数据尽可能连续存储。

3. 利用 SSD 的高速随机访问特性

  • 索引和查找:充分利用 SSD 的高速随机访问特性,优化索引和查找操作。例如,在数据库中使用高效的索引结构,如 B+ 树或哈希表。

  • 小文件存储:对于大量小文件的存储,SSD 可以提供更好的性能。合理设计文件系统和目录结构,减少目录层级,提高文件访问效率。

4. 减少写放大

  • 减少碎片:尽量减少数据的碎片化,通过合理的数据布局和管理策略,减少垃圾回收和数据搬移的频率。

  • 使用适当的文件系统:选择适合 SSD 的文件系统,如 ext4、XFS 或 Btrfs,它们支持 TRIM 命令,并且针对 SSD 进行了优化。

  • 避免过度压缩:虽然压缩可以减少存储空间占用,但在 SSD 上过度压缩可能会增加写放大。根据具体情况权衡压缩带来的好处和写放大的影响。

5. 利用 TRIM 命令

  • 启用 TRIM:确保操作系统和文件系统启用了 TRIM 支持。TRIM 命令可以帮助 SSD 更好地管理未使用的空间,提高后续写入操作的性能。

  • 定期执行 TRIM:对于某些应用,可以定期手动执行 TRIM 操作,确保 SSD 保持最佳状态。

6. 监控和调优

  • 性能监控:使用工具如 iostatfiohdparm 来监控 SSD 的性能指标,包括 IOPS、吞吐量和延迟。

  • 调整参数:根据监控结果调整应用程序和系统的参数,如 I/O 调度器、队列深度和缓存设置,以达到最佳性能。

示例代码

以下是一个简单的示例,展示了如何通过合并写入操作来减少写放大:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
​
void writeDataToFile(const std::string& filename, const std::vector<std::string>& data) {
    std::ofstream file(filename, std::ios::app);
    if (!file.is_open()) {
        std::cerr << "Failed to open file: " << filename << std::endl;
        return;
    }
​
    for (const auto& line : data) {
        file << line << std::endl;
    }
​
    file.close();
}
​
int main() {
    std::vector<std::string> data = {"Line 1", "Line 2", "Line 3", "Line 4", "Line 5"};
    writeDataToFile("example.txt", data);
​
    return 0;
}

在这个示例中,我们将多条数据一次性写入文件,而不是逐条写入。这样可以减少写放大,提高写入性能。

总结

  • 减少不必要的写入操作:合并写入、避免重复写入、批量操作。

  • 优化读取模式:预读、减少随机读取。

  • 利用 SSD 的高速随机访问特性:优化索引和查找、小文件存储。

  • 减少写放大:减少碎片、使用适当的文件系统、避免过度压缩。

  • 利用 TRIM 命令:启用 TRIM、定期执行 TRIM。

  • 监控和调优:性能监控、调整参数。

通过以上方法,你可以更好地利用 SSD 的特性,编写出高效且可靠的代码。

SSD固态硬盘的写入放大问题是什么?如何提高SSD的使用寿命?固态硬盘的价格为什么比机械硬盘贵?

SSD 固态硬盘的写入放大问题


  • 定义:写入放大(Write Amplification)是指在 SSD 上实际写入的数据量远远大于用户想要写入的数据量。

  • 产生原因

    • 闪存芯片存储特性:SSD 的闪存芯片不能像机械硬盘那样直接覆盖写数据。对于已经存有数据的 SSD,一次数据写入分为两个动作,先擦除原有数据,再写入新数据。而擦除的单位是块(Block),通常一个块由多个页(Page)组成,比如常见的一个块可能包含 128 个 4KB 大小的页。但写入的最小单位是页,如果要写入的页所在的块已满,即使只写入少量数据,也需要擦除整个块,再将新数据和该块中有用的数据一起写入,导致实际写入的数据量增多。

    • 垃圾回收机制:随着数据的不断写入和删除,SSD 中会产生很多无效数据(即垃圾数据)。为了回收这些垃圾数据以腾出空间供新数据写入,SSD 的主控芯片会进行垃圾回收操作。在这个过程中,会将一些块中的有效数据复制到其他空闲块,然后擦除原来的块。这就使得在写入新数据时,除了用户数据,还会有额外的旧数据的复制和擦除操作,增加了实际的写入量。

    • 损耗均衡需求:为了避免某些块被过度擦写而提前损坏,SSD 的主控芯片会进行损耗均衡操作,尽可能让每个块的擦写次数均匀。这也会导致一些没有新数据写入的块被移动,产生额外的写入操作,从而增加了写入放大系数。

  • 影响:写入放大问题会带来多方面的不良影响。首先,它会增加闪存芯片的擦写次数,缩短 SSD 的使用寿命,因为闪存芯片的寿命是由擦写次数决定的。其次,写入放大导致的额外读写操作会消耗更多的系统资源和能量,影响 SSD 的性能表现,降低读写速度。


提高 SSD 使用寿命的方法


  • 系统设置方面

    • 开启 AHCI 模式:在 BIOS 设置中开启 AHCI(Advanced Host Controller Interface)模式,能够充分发挥 SSD 的性能,减少不必要的读写操作,降低对 SSD 的磨损。如果是 Windows 系统,在安装操作系统前进入 BIOS 将磁盘读写模式设为 “AHCI”;如果已经安装过系统,可通过修改注册表来设置。

    • 关闭不必要的系统服务:Windows 系统中的一些服务,如虚拟内存、Windows Search 服务、Superfetch 服务、系统休眠功能、系统恢复功能等,对于 SSD 来说并非必要,而且会增加读写次数。在物理内存容量足够大的情况下,可以关闭虚拟内存;通过在 “运行” 中输入 “services.msc” 找到相关服务并将其设为 “停止”,关闭 Windows Search 和 Superfetch 服务;使用管理员身份在 cmd 窗口输入 “powercfg -h off” 关闭系统休眠;在系统保护选项中关闭系统恢复功能。

  • 使用习惯方面

    • 减少不必要的文件写入:尽量避免在 SSD 上频繁写入大量临时文件,将大型文件存储在外部硬盘驱动器或云存储服务上。

    • 避免频繁的大量小文件写入:如果有大量小文件需要写入,尽量将它们合并后再进行写入操作,因为频繁的小文件写入会导致更严重的写入放大问题。

  • 磁盘维护方面

    • 定期清理垃圾文件:使用系统自带的磁盘清理工具或第三方清理软件,定期清理 SSD 上的垃圾文件,减少无效数据占用的空间,降低垃圾回收的频率。

    • 启用 TRIM 命令:TRIM 命令可以通知 SSD 哪些数据块是不再使用的,以便 SSD 在空闲时及时进行垃圾回收,保持良好的性能和使用寿命。对于 Windows 用户,TRIM 命令默认启用;对于 Mac 用户,在 macOS 10.10.4 及更高版本中可用。

    • 进行 4K 对齐:4K 对齐可以使 SSD 的读写操作更加高效,减少不必要的读写次数。在 Windows 7 及以上系统中,使用系统自带的格式化工具进行分区时默认是 4K 对齐的,但如果是在之前的系统或者使用第三方分区工具进行分区时,需要注意进行 4K 对齐操作。


固态硬盘的价格比机械硬盘贵的原因


  • 硬件材质成本差异

    • 存储介质方面:机械硬盘主要以机械磁盘为主,集成度和加工难度相对较低,单位成本也较低;而固态硬盘存储介质是以 NAND 闪存颗粒为主,制造工艺和集成度远超机械时代的磁片产品,虽然闪存颗粒的制造成本随着技术发展有所下降,但相较于磁片产品,采购成本依旧较高。

    • 其他硬件方面:固态硬盘的 PCB 板开模成本、主控芯片的采购成本等也较高。这些综合起来导致固态硬盘的硬件出厂成本远超机械硬盘。

  • 技术协议授权费用:当代固态硬盘想要发挥极致的存储性能,需要满足众多技术协议和接口规范的设计需求,例如 NVMe 传输协议的授权、PCIe 接口的权限使用以及主控功能的自定义研发等,这些都需要缴纳一定额度的授权费用,从而增加了成本。

  • 尚未形成规模效应:固态硬盘作为新兴产品,在发展初期尚未形成规模效应,生产和研发成本分摊到每一个产品上的比例较高。虽然随着技术的进步和市场需求的增加,固态硬盘的价格逐渐下降,但目前与机械硬盘相比,价格仍然相对较高。

SSD 固态硬盘的写入放大问题

写入放大(Write Amplification, WA) 是指在 SSD 中实际写入的数据量比用户请求写入的数据量大的现象。写入放大是由于 SSD 的内部管理机制(如垃圾回收、磨损均衡等)导致的。以下是写入放大的主要原因:

  1. 垃圾回收(Garbage Collection, GC)

    • SSD 在删除数据时,并不会立即擦除闪存单元中的数据,而是标记为无效。当需要新的空间时,SSD 会进行垃圾回收,将有效数据从一个块复制到另一个块,然后擦除原来的块。

    • 这个过程会导致额外的写入操作,增加了写入放大。

  2. 磨损均衡(Wear Leveling)

    • 为了延长 SSD 的使用寿命,磨损均衡算法会确保所有闪存单元均匀地被使用。这可能导致数据被频繁搬移,从而增加写入放大。

  3. 元数据更新

    • SSD 需要维护大量的元数据来跟踪数据的位置和状态。每次写入操作都可能伴随着元数据的更新,这也增加了写入放大。

  4. 预留空间(Over-Provisioning, OP)

    • SSD 通常会保留一部分空间作为预留空间,用于垃圾回收和其他内部操作。预留空间越大,写入放大越小,但也会减少用户的可用空间。

如何提高 SSD 的使用寿命

  1. 减少不必要的写入操作

    • 合并小的写入操作,减少随机写入。

    • 使用高效的缓存策略,避免频繁更新相同的数据。

  2. 启用 TRIM 命令

    • TRIM 命令允许操作系统通知 SSD 哪些数据块不再使用,可以被回收。这有助于减少垃圾回收的工作量,降低写入放大。

    • 确保操作系统和文件系统支持并启用了 TRIM。

  3. 选择合适的文件系统

    • 使用支持 TRIM 的文件系统,如 ext4、XFS 或 Btrfs。

    • 文件系统的选择也会影响写入放大,例如,某些文件系统对元数据的处理方式更高效。

  4. 使用大容量 SSD

    • 大容量 SSD 通常具有更多的预留空间,可以更好地管理垃圾回收和磨损均衡,从而降低写入放大。

  5. 定期维护

    • 定期执行磁盘优化工具,如 Windows 的 chkdsk 或 Linux 的 fstrim,以保持 SSD 的最佳状态。

  6. 合理设置 I/O 调度器

    • 对于 I/O 密集型应用,选择适合 SSD 的 I/O 调度器,如 noopdeadline,这些调度器可以减少延迟并提高性能。

固态硬盘的价格为什么比机械硬盘贵

固态硬盘(SSD)比机械硬盘(HDD)价格更高的原因主要包括以下几个方面:

  1. 制造成本

    • SSD 使用的是 NAND 闪存芯片,而 NAND 闪存的制造工艺复杂且成本较高。相比之下,HDD 的主要部件是磁盘、磁头和电机,制造成本相对较低。

    • NAND 闪存芯片的生产需要高精度的光刻技术和多层堆叠技术,这进一步增加了制造成本。

  2. 存储密度

    • 目前,HDD 的存储密度已经非常高,单盘可以达到数 TB 甚至更多。而 SSD 的存储密度虽然也在不断提高,但每 GB 的成本仍然高于 HDD。

    • 例如,企业级 SSD 可能提供更高的性能和可靠性,但其每 GB 的成本远高于同等容量的 HDD。

  3. 性能优势

    • SSD 提供了显著的性能优势,包括更快的读写速度、更低的延迟和更好的 IOPS(每秒输入输出操作次数)。这些性能优势使得 SSD 成为高性能计算和关键任务应用的首选。

    • 性能的提升往往伴随着更高的成本,因此 SSD 的价格更高。

  4. 耐用性和可靠性

    • SSD 没有机械部件,因此更加耐用,抗震性更好。这使得 SSD 在移动设备和恶劣环境下更为可靠。

    • SSD 的平均无故障时间(MTBF)通常高于 HDD,减少了维护和更换的成本。

  5. 市场需求和供应

    • SSD 的市场需求不断增长,尤其是在数据中心、笔记本电脑和高端台式机等领域。然而,NAND 闪存的供应受到产能限制,这导致了供需失衡,推高了价格。

    • 相比之下,HDD 的市场相对成熟,供应链稳定,价格竞争激烈,因此价格相对较低。

总结

  • 写入放大:由于垃圾回收、磨损均衡、元数据更新等原因导致实际写入的数据量大于用户请求的数据量。

  • 提高 SSD 使用寿命:减少不必要的写入操作、启用 TRIM 命令、选择合适的文件系统、使用大容量 SSD、定期维护、合理设置 I/O 调度器。

  • SSD 价格高的原因:制造成本高、存储密度低、性能优势、耐用性和可靠性、市场需求和供应因素。

通过理解这些特性,你可以更好地利用 SSD 的优势,并采取适当的措施来延长其使用寿命。

4k对齐是什么意思

  1. 基本概念

    • “4K 对齐” 是一种磁盘存储的概念,这里的 “4K” 指的是 4096 字节,它是一个数据存储单位。在磁盘存储中,数据是按照扇区(Sector)来存储的,传统的机械硬盘每个扇区大小一般是 512 字节。而固态硬盘(SSD)和高级格式化后的机械硬盘在存储方式上有所不同,它们的基本存储单元是 4096 字节,这被称为 “4K 扇区”。

    • 4K 对齐就是指将硬盘分区的起始点和每个数据的存储单元都按照 4096 字节的整数倍来进行划分和存储,使得数据的存储和读取能够与硬盘的物理存储结构相匹配。

  2. 重要性

    • 对 SSD 的重要性

      • 性能提升:对于固态硬盘来说,4K 对齐是非常重要的。SSD 的读写操作是以 4K 扇区为基本单位进行的。如果没有 4K 对齐,数据可能会存储在两个 4K 扇区之间,当读取或写入这些数据时,就需要读取或操作两个扇区,这会导致额外的读写操作,从而降低读写速度。例如,在进行小文件读取时,如果文件没有按照 4K 对齐存储,可能需要读取两个 4K 扇区才能获取完整的文件,而 4K 对齐后可以直接读取一个扇区获取文件,提高了读取效率。

      • 延长使用寿命:由于 SSD 存在写入放大问题,不合理的存储方式会增加写入放大系数。4K 对齐可以使数据存储更加合理,减少不必要的写入操作,从而降低写入放大倍数,延长固态硬盘的使用寿命。

    • 对高级格式化后的机械硬盘的重要性

      • 提高存储效率:高级格式化后的机械硬盘采用了更大的 4K 扇区,4K 对齐可以使数据正好存储在完整的扇区中,避免了数据跨扇区存储的情况,提高了存储效率,减少了空间浪费。

      • 兼容性和稳定性:一些操作系统和磁盘管理工具在处理 4K 对齐的磁盘时能够更好地发挥功能,提高了磁盘的兼容性和系统的稳定性。例如,在进行文件系统格式化、分区调整等操作时,4K 对齐的磁盘更不容易出现错误。

  3. 如何实现 4K 对齐

    • 在操作系统安装过程中对齐:在安装 Windows 7 及以上操作系统时,使用系统自带的磁盘分区工具进行分区,默认情况下会自动进行 4K 对齐。在安装过程中,安装程序会根据磁盘的物理特性和文件系统要求,将分区的起始位置和大小设置为 4096 字节的整数倍。

    • 使用第三方分区工具对齐:如果是在已有操作系统的情况下进行分区或者对未对齐的磁盘进行修复,可以使用第三方分区工具,如 DiskGenius。在 DiskGenius 中,可以通过 “分区 - 对齐分区到扇区整数倍” 功能来进行 4K 对齐操作。一般选择 “4096 字节(4K)” 作为对齐参数,然后对相应的分区进行操作即可。

4K对齐是一种磁盘分区和格式化的技术,它确保数据在存储介质上以4KB为单位进行对齐。这种对齐方式可以提高存储设备(尤其是SSD)的性能和寿命。以下是关于4K对齐的一些详细解释:

什么是4K对齐?

  1. 块大小

    • 现代硬盘(包括HDD和SSD)通常使用4KB作为基本的存储块(也称为扇区)。这意味着每次读写操作至少涉及4KB的数据。

    • 4K对齐是指将文件系统中的簇(cluster)或逻辑块与物理存储介质上的4KB扇区对齐。

  2. 对齐方式

    • 在4K对齐的情况下,每个逻辑块的起始位置是4KB的整数倍。例如,如果一个文件系统的簇大小是4KB,那么每个簇的起始地址应该是4096字节的倍数。

为什么需要4K对齐?

  1. 提高性能

    • 4K对齐可以减少不必要的I/O操作,从而提高读写性能。如果数据不对齐,一次读写操作可能需要访问两个相邻的4KB扇区,这会增加额外的I/O开销。

    • 对于SSD来说,4K对齐尤为重要,因为SSD的擦除和写入操作是以页(通常是4KB)为单位进行的。不对齐会导致更多的擦除和写入操作,从而降低性能并增加写放大。

  2. 延长SSD寿命

    • 由于4K对齐减少了不必要的擦除和写入操作,因此可以减少SSD的磨损,从而延长其使用寿命。

    • 写放大现象在SSD中尤为明显,通过4K对齐可以有效减少写放大,进而减少闪存单元的磨损。

  3. 兼容性

    • 许多现代操作系统和文件系统默认支持4K对齐。例如,Windows 7及更高版本、Linux等都支持4K对齐。

    • 一些旧的操作系统和文件系统可能不支持4K对齐,但在现代环境中,这种情况越来越少见。

如何检查和设置4K对齐

检查4K对齐

  • Windows

    • 可以使用msinfo32命令来查看磁盘的对齐状态。打开“运行”对话框(Win + R),输入msinfo32,然后按回车键。

    • 在“系统信息”窗口中,找到“组件” -> “存储” -> “磁盘”,查看“分区起始偏移”字段。如果该值是4096的倍数,则表示该分区是4K对齐的。

  • Linux

    • 可以使用fdiskparted工具来检查分区的对齐情况。

    • 例如,使用parted工具:

      sudo parted /dev/sdX unit s print

      查看分区的起始位置是否是8192(即4096个扇区,假设每个扇区512字节)的倍数。

设置4K对齐

  • 新磁盘

    • 在新的磁盘上创建分区时,大多数现代分区工具(如GParted、Disk Management等)会自动进行4K对齐。

    • 如果手动创建分区,确保分区的起始位置是4096字节的倍数。

  • 现有磁盘

    • 如果现有的磁盘没有进行4K对齐,可以通过重新分区和格式化来实现对齐。但请注意,这将删除磁盘上的所有数据,因此在操作前务必备份重要数据。

    • 使用工具如GPartedDisk Management重新分区,并确保选择4K对齐选项。

总结

  • 4K对齐:确保数据在存储介质上以4KB为单位进行对齐。

  • 优点:提高性能、延长SSD寿命、更好的兼容性。

  • 检查和设置:可以使用系统工具检查对齐状态,并在创建新分区时确保4K对齐。

通过确保磁盘的4K对齐,你可以充分利用SSD的性能优势,并延长其使用寿命。

SSD 基本介绍

其实现在 SSD 已经很普及了,SSD 被称之为固态硬盘是相对于普通的机械硬盘 HDD 而言,因为它没有机械结构。普通的机械硬盘 HDD 一般都需要将执行器臂将读写头定位在驱动器的正确区域上以读取或写入信息。

因为驱动器磁头必须在磁盘的某个区域对齐才能读取或写入数据,并且磁盘不断旋转,所以在访问数据之前会有延迟。HDD 的延迟通常以毫秒为单位,硬盘驱动器通常需要10-15ms才能在驱动器上找到数据并开始读取,即使是现在 15000 转的 HDD 延迟最低也要 4ms,IOPS(每秒的输入输出量) 在 200 左右,顺序读写速度在300MB/s 左右 。

反观我们看现在 SSD,以三星的 990 PRO为例,读写速度最高达到了 7000+ MB/s ,IOPS 高达 1,400K,延迟在 41us 左右,这么一对比,大家可以知道其实 SSD 比 HDD 快了好几个数量级。

SSD 内部结构

SSD 的内部结构一般是由三部分构成:1. Controller 控制器 ;2.DRAM缓存;3.NAND闪存;

控制器是用来控制 SSD 的所有操作的,从实际读取和写入数据到执行垃圾回收和耗损均衡算法等,以保证SSD 的速度及整洁度;

DRAM缓存不是所有的硬盘都有,对于我们上面提到的 990 PRO 来说会有 2GB 左右的缓存,主要是用来存放的是逻辑物理映射表,控制器会通过缓存的映射表来查找数据使用。还承载了一部分待写入的数据,等够一页的时候一次性写入到NAND颗粒里面,用来缓解写入放大;

顺带提一下无缓的固态硬盘也不用过于担心性能问题,一般来说会使用 HMB 技术通过PCIe通道找内存借用一部分内存空间来存储映射表,在每次开机的时候往内存写入部分常用的FTL表,这个空间大小通常是64MB。像我们国产的致钛TiPlus7100就是采用的无缓+HMB机制,其速度也不差。

  1. 控制器(Controller)

    • 功能概述

      • 控制器是 SSD 的 “大脑”,它在 SSD 的运行过程中发挥着核心的管理和数据传输功能。它负责管理和传输数据,包括从主机接收数据和指令,然后将这些指令转换为对 NAND 闪存芯片的操作。例如,当计算机向 SSD 写入数据时,控制器会根据数据的大小、类型以及存储位置等因素,合理地安排数据在 NAND 闪存中的存储方式。

    • 性能关键因素

      • 控制器的性能主要取决于其芯片设计和处理能力。一个高性能的控制器能够支持更高的数据传输速率和更多的并发操作。例如,它可以通过采用更先进的闪存通道技术,实现同时对多个 NAND 闪存芯片进行读写操作,从而提高 SSD 的整体读写速度。同时,控制器还决定了 SSD 能够支持的功能,如是否支持 NVMe(Non - Volatile Memory Express)协议。采用 NVMe 协议的 SSD,其控制器可以充分利用 PCIe(Peripheral Component Interconnect Express)接口的高速特性,实现比传统 SATA 接口更快的传输速度。

  2. DRAM 缓存(DRAM Cache)

    • 功能概述

      • DRAM 缓存的主要作用是临时存储数据,以提高 SSD 的读写性能。它就像是一个数据的 “中转站”,当主机频繁地读取或写入某些数据时,这些数据会先存储在 DRAM 缓存中。例如,在读取数据时,如果数据正好在 DRAM 缓存中,就可以直接从缓存中快速提取,而无需从相对较慢的 NAND 闪存中读取,大大提高了读取速度。在写入数据时,数据可以先暂存在 DRAM 缓存中,等到缓存满或者达到一定的条件后,再批量写入 NAND 闪存,减少了对 NAND 闪存的频繁写入操作,也有助于提高性能。

    • 缓存策略与大小影响

      • DRAM 缓存的大小和缓存策略对 SSD 的性能有重要影响。较大的 DRAM 缓存可以存储更多的数据,从而提高缓存命中率。缓存命中率是指在缓存中找到所需数据的概率,命中率越高,SSD 的性能就越好。缓存策略包括诸如 LRU(Least Recently Used)等,即当缓存已满时,优先替换掉最久未使用的数据。不同的 SSD 厂商可能会采用不同的缓存策略来优化性能。不过,需要注意的是,并不是所有的 SSD 都有 DRAM 缓存,一些无缓存的 SSD 会采用其他技术来弥补没有缓存带来的性能损失。

  3. NAND 闪存(NAND Flash)

    • 功能概述

      • NAND 闪存是 SSD 存储数据的核心部件,数据以二进制的形式存储在闪存芯片的晶体管中。它就像是 SSD 的 “仓库”,用于长期存储大量的数据。与传统的机械硬盘不同,NAND 闪存没有机械部件,这使得 SSD 具有更快的读写速度、更低的能耗和更好的抗震性。例如,NAND 闪存通过闪存单元来存储数据,这些闪存单元可以被编程(写入数据)和擦除,从而实现数据的存储和更新。

    • 不同类型及特点

      • NAND 闪存分为不同的类型,如 SLC(Single - Level Cell)、MLC(Multi - Level Cell)和 TLC(Triple - Level Cell)。SLC 每个存储单元只存储 1 位数据,它具有速度快、寿命长(P/E Cycles - Program/Erase Cycles 可达 10 万次左右)、可靠性高的特点,但成本也较高,一般用于高端企业级 SSD。MLC 每个存储单元存储 2 位数据,其性能和寿命介于 SLC 和 TLC 之间,P/E Cycles 一般在 3000 - 10000 次左右,成本适中。TLC 每个存储单元存储 3 位数据,成本最低,但读写速度相对较慢,寿命较短(P/E Cycles 通常在 1000 - 3000 次左右),常用于消费级 SSD。

以下是对这段内容的详细解释:


一、控制器的作用


  1. 全面控制操作

    • 控制器在固态硬盘(SSD)中起着至关重要的作用,它就像是 SSD 的 “指挥中心”,掌控着所有的操作流程。从最基本的数据读取和写入任务开始,当系统发出读取或写入数据的指令时,控制器负责接收并处理这些指令,协调各个部件进行相应的操作。例如,在读取数据时,控制器会根据请求的数据地址,从 NAND 闪存中准确地定位并读取数据,然后将数据传输给主机系统。

    • 对于垃圾回收和耗损均衡算法的执行,控制器也起着关键作用。随着数据的不断写入、删除和更新,SSD 中会产生大量的无效数据,这就需要垃圾回收机制来清理这些无效数据,为新数据腾出空间。控制器会启动垃圾回收操作,将有效数据移动到新的位置,并擦除含有无效数据的闪存块。同时,为了延长 SSD 的使用寿命,控制器会执行耗损均衡算法,确保各个闪存块的擦写次数尽量均匀分布,避免某些块过度磨损而提前损坏。

  2. 保证速度及整洁度

    • 通过高效地管理数据的读写和处理各种操作,控制器能够保证 SSD 的速度。它可以优化数据的存储布局,提高数据的读取和写入效率。例如,控制器可以采用并行读写技术,同时对多个闪存芯片进行操作,从而大大提高数据传输速度。此外,控制器还负责管理缓存(如果有),合理地利用缓存空间来加速数据的访问。

    • 在保持 SSD 的 “整洁度” 方面,控制器通过垃圾回收和耗损均衡算法,确保 SSD 中的数据存储有序,减少无效数据的堆积,保持闪存空间的高效利用。这样可以避免因无效数据过多而导致的性能下降,同时也有助于延长 SSD 的使用寿命。


二、DRAM 缓存的作用及不同类型 SSD 的解决方案


  1. 有缓存的 SSD(以 990 PRO 为例)

    • 存储逻辑物理映射表:在一些高性能的 SSD 中,如 990 PRO,DRAM 缓存主要用于存放逻辑物理映射表。这个映射表记录了逻辑地址(即主机系统看到的地址)和物理地址(即 NAND 闪存中的实际存储地址)之间的对应关系。控制器通过缓存的映射表可以快速查找数据的实际存储位置,从而提高数据的读取速度。例如,当主机系统请求读取某个逻辑地址的数据时,控制器可以立即在缓存的映射表中查找对应的物理地址,然后从 NAND 闪存中读取数据。

    • 缓解写入放大:DRAM 缓存还承载了一部分待写入的数据。当数据写入 SSD 时,它们首先会被暂存在缓存中,等积累到一定数量(够一页的时候),控制器会一次性将这些数据写入到 NAND 颗粒里面。这样做可以减少对 NAND 闪存的频繁写入操作,从而缓解写入放大问题。写入放大是指实际写入到 NAND 闪存中的数据量与主机系统请求写入的数据量之比,写入放大系数越小,对 SSD 的寿命和性能越有利。

  2. 无缓存的 SSD(以致钛 TiPlus7100 为例)

    • HMB 技术的应用:对于无缓存的固态硬盘,如国产的致钛 TiPlus7100,会采用 HMB(Host Memory Buffer)技术。这种技术通过 PCIe 通道向主机系统的内存借用一部分内存空间来存储映射表。在每次开机的时候,SSD 会往内存写入部分常用的 FTL(Flash Translation Layer)表,这个空间大小通常是 64MB。这样,虽然没有专门的 DRAM 缓存,但通过借用主机内存,SSD 仍然能够实现一定程度的性能提升。

    • 性能表现:采用无缓 + HMB 机制的 SSD,其速度也不差。虽然可能在某些极端情况下不如有专门 DRAM 缓存的 SSD,但在大多数日常使用场景中,它们能够提供足够快的数据传输速度,满足用户的需求。例如,在普通的办公应用、网页浏览、视频播放等场景中,致钛 TiPlus7100 这样的无缓存 SSD 可以与有缓存的 SSD 表现相当,甚至在一些方面可能还有优势,比如成本更低、功耗更低等。

是的,SSD(固态硬盘)的内部结构通常由三部分组成:控制器(Controller)、DRAM缓存和NAND闪存。每部分都有其特定的功能,共同协作以提供高性能的存储解决方案。

1. 控制器(Controller)

控制器是SSD的大脑,负责管理数据在主机和NAND闪存之间的传输。它执行以下主要功能:

  • 接口协议处理:控制器通过标准接口(如SATA、PCIe/NVMe等)与主机通信。

  • FTL(Flash Translation Layer):将逻辑地址转换为物理地址,实现磨损均衡、垃圾回收等功能。

  • 错误校正码(ECC):检测并纠正读取数据时可能出现的错误。

  • 坏块管理:标记并隔离损坏的闪存块,确保数据完整性。

  • 加密:支持硬件级别的数据加密,增强数据安全性。

  • 电源故障保护:在意外断电时保护数据,防止数据丢失或损坏。

2. DRAM缓存

DRAM缓存用于存储映射表(通常是FTL的一部分)和其他临时数据,以提高读写性能。它的主要作用包括:

  • 映射表缓存:存储逻辑地址到物理地址的映射关系,加快地址转换速度。

  • 读写缓冲:暂存即将写入NAND闪存的数据或从NAND闪存读取的数据,减少直接访问NAND闪存的次数,提高性能。

  • 元数据缓存:存储其他重要的元数据信息,如坏块列表、日志信息等。

3. NAND闪存

NAND闪存是SSD的实际存储介质,用于持久化存储数据。NAND闪存具有以下特点:

  • 非易失性:即使断电,数据也能保持不丢失。

  • 高密度:可以存储大量数据,目前单个芯片容量可以达到数TB。

  • 有限的写入寿命:每个NAND单元有一定的编程/擦除(P/E)周期限制,超过这个限制后,该单元可能会失效。

  • 页和块结构:NAND闪存按页(Page)读写,按块(Block)擦除。一个块包含多个页,通常一个页的大小为4KB或8KB,一个块的大小为128KB到几个MB不等。

  • 多层堆叠技术:现代NAND闪存采用多层堆叠技术(如3D NAND),可以在相同的物理空间内存储更多数据,提高存储密度。

总结

  • 控制器:负责管理数据传输、地址转换、错误校正、坏块管理等。

  • DRAM缓存:用于存储映射表和临时数据,提高读写性能。

  • NAND闪存:实际存储介质,非易失性,高密度,但有有限的写入寿命。

这三部分共同工作,使得SSD能够提供高速的读写性能、低延迟和高可靠性。理解这些组成部分及其功能有助于更好地利用SSD的优势,并在设计和使用存储系统时做出更明智的决策。

NAND 闪存是最终用来存放数据的地方,它不仅决定了SSD的使用寿命,而且对SSD的性能影响也非常大。比如大家所熟知的 SLC, MLC, TLC 闪存。NAND本身由所谓的浮栅晶体管组成,它是一种非易失性存储器,即使不通电也能保持状态,NAND 由一个个浮栅晶体管堆叠而成。根据每个浮栅晶体管可以保存1bit, 2bit, 3bit数据量可以分为SLC, MLC, TLC。


1个Page 一般是4KB 或者 8 KB ,上面我们提到的 990 PRO 是 16KB, 不同 SSD 大小也不同。因为浮栅晶体管被分组并以非常特定的属性访问,所以我们只能按页来进行数据的读写,如下简化图中红色的每一行都代表一个 Page ,写数据的时候会给行列两端加上不同的电压,加电压只能加到行和列上,所以没法控制到单个浮栅晶体管;


Block 是擦除的基本单位,每个 Block 会包含 128 到 256 个上面这样的 Page。如下图由于一块 Block 上面的所有浮栅晶体管其实是共用一个衬底,只要给这个衬底施加高压,浮栅晶体管里面存储的数据就会被清空,所以 Block 是擦除数据的基本单位。


  1. NAND 闪存在 SSD 中的核心地位

    • NAND 闪存是固态硬盘(SSD)存储数据的最终场所,就像传统硬盘中的磁盘一样,它的重要性不言而喻。其性能和寿命直接关系到 SSD 的整体品质。

    • 使用寿命方面:SSD 的使用寿命主要取决于 NAND 闪存的可擦写次数,也就是 P/E(Program/Erase)循环次数。不同类型的 NAND 闪存,如 SLC、MLC 和 TLC,其 P/E 循环次数差异较大。SLC 闪存的 P/E 循环次数最高,可达到 10 万次左右,这意味着它可以承受大量的数据写入和擦除操作,因此使用寿命较长。MLC 闪存的 P/E 循环次数一般在 3000 - 10000 次之间,使用寿命适中。TLC 闪存的 P/E 循环次数相对较少,通常在 1000 - 3000 次左右,使用寿命较短。所以,在对数据存储安全性和持久性要求较高的场景中,如企业级数据存储,SLC 闪存更受青睐;而对于一般的消费级产品,TLC 闪存因其成本优势被广泛使用。

    • 性能影响方面:NAND 闪存对 SSD 的性能也有巨大的影响。在读写速度上,SLC 闪存由于每个存储单元只存储 1bit 数据,其读写速度最快。这是因为在读写过程中,控制器可以更简单、更快速地处理每个存储单元的数据。MLC 闪存每个存储单元存储 2bit 数据,读写速度稍慢于 SLC。TLC 闪存每个存储单元存储 3bit 数据,读写速度相对最慢。这是因为随着每个存储单元存储数据量的增加,闪存的读写操作变得更加复杂,需要更多的时间来处理。例如,在读取数据时,控制器需要更复杂的信号处理来区分每个存储单元中的 3bit 数据,从而导致读取速度下降。

  2. NAND 闪存的基本组成单元 - 浮栅晶体管

    • NAND 闪存由浮栅晶体管组成,浮栅晶体管是一种非易失性存储器。非易失性意味着即使在断电的情况下,存储在其中的数据也不会丢失,这是它与随机存取存储器(RAM)的重要区别之一。浮栅晶体管的结构使其能够在不通电的情况下保持数据状态。

    • 这些浮栅晶体管是堆叠在一起的,通过不同的电子状态来表示数据。这种堆叠结构使得 NAND 闪存能够在较小的物理空间内存储大量的数据。例如,在制造工艺不断进步的情况下,通过增加浮栅晶体管的堆叠层数,可以在不增加芯片面积的情况下大幅提高存储容量。

  3. SLC、MLC 和 TLC 闪存的区别

    • SLC(Single - Level Cell)闪存:每个浮栅晶体管只能保存 1bit 数据,这使得它在读写性能和寿命方面表现出色。由于存储的数据状态简单,控制器可以高效地进行读写操作,因此读写速度快,而且能够承受大量的擦写操作。不过,SLC 闪存的成本较高,因为在相同的存储容量需求下,它需要更多的晶体管,所以主要用于对性能和寿命要求极高的高端应用场景,如企业级服务器和高性能存储设备。

    • MLC(Multi - Level Cell)闪存:每个浮栅晶体管可以保存 2bit 数据。相较于 SLC 闪存,它在存储容量上有一定的提升,因为相同数量的晶体管可以存储两倍于 SLC 的数据量。然而,由于每个存储单元存储的数据状态变多,读写操作相对复杂,读写速度会比 SLC 闪存慢一些,寿命也会有所降低。MLC 闪存在性能、容量和成本之间取得了一定的平衡,常用于一些对性能和寿命有一定要求,但对成本也比较敏感的应用场景,如高端消费级 SSD 和一些工业控制设备。

    • TLC(Triple - Level Cell)闪存:每个浮栅晶体管能够保存 3bit 数据,这使得它在存储容量上相比 MLC 闪存又有了进一步的提升。但由于每个存储单元存储的数据状态更加复杂,读写速度会更慢,而且 P/E 循环次数也较少,寿命相对较短。TLC 闪存的优势在于成本较低,能够提供较大的存储容量,适合用于对读写速度和寿命要求不是特别高的普通消费级应用,如日常办公电脑、笔记本电脑和一些消费电子产品的存储设备。

是的,NAND闪存是SSD中用来持久化存储数据的部分,它不仅决定了SSD的使用寿命,还对性能有重大影响。NAND闪存根据每个存储单元可以保存的数据位数不同,主要分为以下几种类型:

1. SLC (Single-Level Cell) 单层单元

  • 存储容量:每个存储单元只能保存1位(bit)数据。

  • 优点

    • 高耐久性:SLC闪存的写入/擦除(P/E)周期通常在100,000次左右,因此具有较长的使用寿命。

    • 高性能:由于每个单元只存储一位数据,读写速度较快,延迟较低。

    • 高可靠性:较少出现数据错误,因为只需要判断一个电压水平。

  • 缺点

    • 成本较高:由于每个单元只存储一位数据,所以单位容量的成本较高。

    • 存储密度低:相对于MLC和TLC,SLC的存储密度较低。

2. MLC (Multi-Level Cell) 多层单元

  • 存储容量:每个存储单元可以保存2位(bit)数据。

  • 优点

    • 成本效益:相比SLC,MLC可以在相同的物理空间内存储更多的数据,因此单位容量的成本较低。

    • 较高的存储密度:每个单元存储两位数据,提高了存储密度。

  • 缺点

    • 较低的耐久性:MLC的P/E周期通常在3,000到10,000次之间,比SLC要低得多。

    • 性能略低:由于需要区分四个不同的电压水平,读写速度和延迟略低于SLC。

    • 可靠性稍差:由于需要更精细的电压控制,更容易出现数据错误。

3. TLC (Triple-Level Cell) 三层单元

  • 存储容量:每个存储单元可以保存3位(bit)数据。

  • 优点

    • 成本更低:TLC可以在相同的物理空间内存储更多的数据,进一步降低了单位容量的成本。

    • 更高的存储密度:每个单元存储三位数据,提供了更高的存储密度。

  • 缺点

    • 最低的耐久性:TLC的P/E周期通常在1,000到3,000次之间,比MLC还要低。

    • 性能较低:由于需要区分八个不同的电压水平,读写速度和延迟较SLC和MLC都要低。

    • 可靠性较差:由于需要非常精细的电压控制,更容易出现数据错误。

4. QLC (Quad-Level Cell) 四层单元

  • 存储容量:每个存储单元可以保存4位(bit)数据。

  • 优点

    • 成本更低:QLC可以在相同的物理空间内存储更多的数据,进一步降低了单位容量的成本。

    • 最高的存储密度:每个单元存储四位数据,提供了最高的存储密度。

  • 缺点

    • 最低的耐久性:QLC的P/E周期通常在100到1,000次之间,比TLC还要低。

    • 性能较低:由于需要区分十六个不同的电压水平,读写速度和延迟较SLC、MLC和TLC都要低。

    • 可靠性较差:由于需要非常精细的电压控制,更容易出现数据错误。

浮栅晶体管的工作原理

NAND闪存的基本存储单元是浮栅晶体管。浮栅晶体管由以下几个部分组成:

  • 源极(Source)漏极(Drain):用于电流通过。

  • 控制栅(Control Gate):用于控制浮栅上的电荷。

  • 浮栅(Floating Gate):位于控制栅下方,与周围的绝缘材料隔离,用于存储电荷。

工作原理

  1. 编程(写入)

    • 通过向控制栅施加高电压,并在源极或漏极施加适当的电压,使电子穿过氧化层进入浮栅。

    • 一旦电子被注入浮栅,它们会被困在那里,即使断电也不会丢失,从而保持数据状态。

  2. 擦除

    • 通过向控制栅施加负电压,并在源极或漏极施加正电压,使电子从浮栅中被抽出。

    • 擦除操作通常是按块进行的,而不是按页进行。

  3. 读取

    • 通过向控制栅施加一定的电压,检测源极和漏极之间的电流。

    • 根据电流的大小,可以判断浮栅中的电荷量,从而确定存储的数据。

总结

  • SLC:高耐久性、高性能、高可靠性,但成本较高。

  • MLC:成本效益较好,存储密度较高,但耐久性和性能略低。

  • TLC:成本更低,存储密度更高,但耐久性和性能更低。

  • QLC:成本最低,存储密度最高,但耐久性和性能最低。

了解这些不同类型NAND闪存的特点,可以帮助你在选择SSD时做出更适合特定应用需求的决策。例如,对于需要高性能和高可靠性的企业级应用,SLC可能是更好的选择;而对于需要大容量且成本敏感的消费级应用,TLC或QLC可能更为合适。

为啥 SSD寿命是有限的?

其实这取决于浮栅晶体管的结构,它的结构下图所示,我不打算概述它的原理,但是我们可以知道在浮栅晶体管中电子是存储在浮栅层的,读写数据的时候电子需要穿过隧穿层,由隧穿层来锁住电子,隧穿层穿越次数是有限制的,进出次数多了,就锁不住电子了,那么该 Block 就没法擦写数据了。

所以如果一直在同一个 Block 擦写数据,这个 Block 的寿命很快就会消耗完,为了有效的延迟 SSD 的使用寿命就很考验 Block 的管理技术了,后面我们可以看看现在的 SSD 有哪些管理抓手。

是的,SSD 的寿命有限主要是由于 NAND 闪存中浮栅晶体管的物理特性。具体来说,这种限制主要与浮栅晶体管中的隧穿层(Tunnel Oxide Layer)有关。以下是详细的解释:

浮栅晶体管的结构和工作原理

浮栅晶体管由以下几个部分组成:

  • 源极(Source)漏极(Drain):用于电流通过。

  • 控制栅(Control Gate):用于控制浮栅上的电荷。

  • 浮栅(Floating Gate):位于控制栅下方,与周围的绝缘材料隔离,用于存储电荷。

  • 隧穿层(Tunnel Oxide Layer):位于浮栅和硅衬底之间,负责电子的隧穿。

工作原理

  1. 编程(写入)

    • 通过向控制栅施加高电压,并在源极或漏极施加适当的电压,使电子穿过隧穿层进入浮栅。

    • 一旦电子被注入浮栅,它们会被困在那里,即使断电也不会丢失,从而保持数据状态。

  2. 擦除

    • 通过向控制栅施加负电压,并在源极或漏极施加正电压,使电子从浮栅中被抽出。

    • 擦除操作通常是按块进行的,而不是按页进行。

  3. 读取

    • 通过向控制栅施加一定的电压,检测源极和漏极之间的电流。

    • 根据电流的大小,可以判断浮栅中的电荷量,从而确定存储的数据。

寿命有限的原因

  1. 隧穿层的磨损

    • 隧穿层的主要功能是允许电子在编程和擦除操作中穿过,同时在其他时间阻止电子逃逸。

    • 每次编程和擦除操作都会导致隧穿层发生微小的物理变化,这些变化会逐渐累积。

    • 随着时间的推移,隧穿层的绝缘性能会下降,导致电子更容易逃逸,从而使浮栅中的电荷不稳定。

  2. P/E 周期限制

    • 每个浮栅晶体管都有一个编程/擦除(P/E)周期的限制,超过这个限制后,隧穿层的绝缘性能会显著下降,浮栅中的电荷无法可靠地保持。

    • SLC、MLC、TLC 和 QLC 的 P/E 周期不同:

      • SLC:大约 100,000 到 1,000,000 次。

      • MLC:大约 3,000 到 10,000 次。

      • TLC:大约 1,000 到 3,000 次。

      • QLC:大约 100 到 1,000 次。

  3. 坏块管理

    • SSD 控制器会监测每个块的健康状况,并在某个块达到其 P/E 周期限制时将其标记为坏块。

    • 控制器会将坏块从可用空间中移除,并使用预留的空间来替代这些坏块,以确保数据的完整性。

延长 SSD 寿命的方法

  1. 减少不必要的写入操作

    • 合并小的写入操作,减少随机写入。

    • 使用高效的缓存策略,避免频繁更新相同的数据。

  2. 启用 TRIM 命令

    • TRIM 命令允许操作系统通知 SSD 哪些数据块不再使用,可以被回收。这有助于减少垃圾回收的工作量,降低写入放大。

    • 确保操作系统和文件系统支持并启用了 TRIM。

  3. 选择合适的文件系统

    • 使用支持 TRIM 的文件系统,如 ext4、XFS 或 Btrfs。

    • 文件系统的选择也会影响写入放大,例如,某些文件系统对元数据的处理方式更高效。

  4. 使用大容量 SSD

    • 大容量 SSD 通常具有更多的预留空间,可以更好地管理垃圾回收和磨损均衡,从而降低写入放大。

  5. 定期维护

    • 定期执行磁盘优化工具,如 Windows 的 chkdsk 或 Linux 的 fstrim,以保持 SSD 的最佳状态。

  6. 合理设置 I/O 调度器

    • 对于 I/O 密集型应用,选择适合 SSD 的 I/O 调度器,如 noopdeadline,这些调度器可以减少延迟并提高性能。

总结

SSD 的寿命有限主要是由于 NAND 闪存中浮栅晶体管的隧穿层在多次编程和擦除操作后会逐渐磨损,导致浮栅中的电荷无法可靠地保持。通过减少不必要的写入操作、启用 TRIM 命令、选择合适的文件系统、使用大容量 SSD 以及定期维护等方法,可以有效地延长 SSD 的使用寿命。

  1. 浮栅晶体管结构与数据存储原理

    • SSD 中的 NAND 闪存是由浮栅晶体管组成的。在浮栅晶体管结构中,电子存储在浮栅层。当写入数据时,电子通过隧穿效应穿过隧穿层进入浮栅层,而在读取数据时,电子的状态也会通过隧穿层来检测。隧穿层在这里起着关键的作用,它就像是一个 “电子阀门”,控制着电子的进出。

    • 这种基于隧穿效应的读写机制是 NAND 闪存能够实现数据存储和读取的基础。然而,隧穿层的材料和物理特性决定了它能够承受的电子穿越次数是有限的。

  2. P/E 循环与 SSD 寿命的关联

    • 每次对 NAND 闪存进行写入(Program)和擦除(Erase)操作,也就是一次 P/E 循环,电子都需要穿过隧穿层进出浮栅层。随着 P/E 循环次数的增加,隧穿层的性能逐渐下降。

    • 当隧穿层经过大量的电子穿越后,它会出现 “老化” 现象,无法有效地锁住电子。一旦这种情况发生,浮栅层中的电子状态就会变得不稳定,导致数据存储出现错误,最终使得该存储块(Block)无法正常进行擦写操作。

    • 这就是为什么 SSD 的寿命是有限的,其寿命主要取决于 NAND 闪存能够承受的 P/E 循环次数。不同类型的 NAND 闪存(如 SLC、MLC、TLC)由于其结构和材料的差异,所能承受的 P/E 循环次数不同,从而具有不同的使用寿命。例如,SLC 闪存由于其结构相对简单,电子存储和读取过程对隧穿层的损耗较小,所以能够承受较高的 P/E 循环次数,寿命较长;而 TLC 闪存因为每个存储单元存储的数据量更多,电子进出隧穿层的频率相对更高,对隧穿层的损耗更快,所以 P/E 循环次数较低,寿命也较短。


读、写、擦除

当首次向SSD写入数据时,因为数据都处于已擦除的状态,所以数据可以直接写入,至少一次性写入一个 Page。因为在写入的时候会按照 Page 为单位进行写入,所以如果要写入的数据小于一个 Page,那么其余写入超过必要的数据称为写入放大

只有空闲的Page才能被写入,并且是不能覆盖的,所以在修改数据的时候数据会被写入到一个空闲页面中,一旦被持久化到页面上,原来的旧页面会被标记成 stale 状态,表示它可以被擦除。

所以一个 Page 变成 stale 状态之后唯一能让它们再次使用的方式就是擦除它们,但是擦除的维度我们上面也讲过了,是以 Block 为维度进行擦除的,并且擦除命令不由用户控制,擦除命令是由SSD控制器中的垃圾回收机制进程在需要回收陈旧页面以腾出空闲空间时自动触发的。

除了上面提到的写入放大以外,如果在写入数据的时候不是以 Page 为单位进行写入,会导致Page 被修改并写回驱动器之前被读入缓存,这种操作被称为读-修改-写,比直接操作页面要慢。

所以我们写入数据的时候应该要对齐写入,也就是按 Page 整倍大小写入。并且为了最大限度地提高吞吐量,尽可能将小写入保留到 RAM 中的缓冲区中,当缓冲区已满时,执行一次大写入以批处理所有小写入。

  1. 首次写入数据的规则与写入放大概念

    • 首次写入:在 SSD 首次写入数据时,由于闪存中的数据都处于已擦除状态,所以可以直接写入。写入操作是以 Page 为单位进行的,这是由 SSD 的内部存储结构决定的。例如,如果一个 Page 的大小是 4KB,那么每次写入操作至少是 4KB 的数据量。

    • 写入放大的产生:当要写入的数据小于一个 Page 时,为了完成写入操作,也需要占用一个完整的 Page,此时超出实际需要写入的数据量就产生了写入放大。这种写入放大现象会导致额外的数据写入,增加了闪存的写入负担,也会影响 SSD 的使用寿命和性能。例如,若要写入 1KB 的数据,但必须按照 4KB 的 Page 单位写入,就会造成写入放大。

  2. 数据修改、stale 状态与页面回收

    • 数据修改规则:SSD 中只有空闲的 Page 才能被写入新数据,并且不能直接覆盖已有的数据。当修改数据时,新的数据会被写入到一个空闲页面中。一旦新数据被持久化到新页面上,原来存储旧数据的页面就会被标记为 stale 状态,表示这个页面的数据已经过时,可以被擦除。这种机制是为了保证数据的完整性和存储的有序性。

    • 页面擦除机制:对于处于 stale 状态的 Page,要让它们再次被使用,唯一的方式就是擦除它们。不过,擦除操作不是以 Page 为单位,而是以 Block 为单位进行的。Block 是由多个 Page 组成的存储单元。而且,擦除命令不由用户控制,而是由 SSD 控制器中的垃圾回收机制在需要回收陈旧页面以腾出空闲空间时自动触发。例如,一个 Block 包含 128 个 Page,当其中有足够多的 Page 被标记为 stale 状态时,垃圾回收机制会启动,擦除整个 Block,从而回收空间用于新数据的写入。

  3. 读 - 修改 - 写操作及写入对齐的重要性

    • 读 - 修改 - 写操作:除了写入放大问题,如果在写入数据的时候不是以 Page 为单位进行写入,会导致 Page 在被修改并写回驱动器之前需要被读入缓存,这种操作被称为读 - 修改 - 写。这种操作相对复杂,比直接以 Page 为单位的操作要慢。这是因为涉及到额外的读取和缓存操作,增加了数据处理的步骤和时间。

    • 写入对齐的必要性:为了提高写入效率,我们写入数据的时候应该要对齐写入,也就是按 Page 整倍大小写入。这样可以避免写入放大和读 - 修改 - 写操作,提高数据写入的速度和效率。同时,为了最大限度地提高吞吐量,还应该尽可能将小写入保留到 RAM 中的缓冲区中。当缓冲区已满时,执行一次大写入以批处理所有小写入。例如,可以将多个小数据块先存储在内存缓冲区中,等到缓冲区积累了足够多的数据,达到 Page 的整数倍大小后,再一次性写入 SSD,这样可以减少写入次数,提高整体的写入性能。


  1. 你对SSD的读、写、擦除操作以及相关的优化策略描述得非常详细。下面我将总结并补充一些关键点,以确保对这些概念有更全面的理解。

    读、写、擦除操作

    写入操作

    1. 首次写入

      • 当SSD中的Page处于已擦除状态时,数据可以直接写入。

      • 写入操作是以Page为单位进行的,通常一个Page的大小是4KB或8KB。

      • 如果写入的数据小于一个Page,剩余的空间会被填充(通常是全0),这称为“写入放大”。

    2. 修改数据

      • 由于NAND闪存的特性,Page不能被直接覆盖。因此,当需要修改数据时,新的数据会被写入到一个新的空闲Page中。

      • 原来的旧Page会被标记为stale(陈旧)状态,表示它可以被擦除。

    3. 写入放大

      • 写入放大是指实际写入的数据量大于用户请求写入的数据量的现象。

      • 例如,如果写入的数据小于一个Page,那么整个Page都会被写入,导致写入放大。

      • 通过合并小写入操作,可以减少写入放大。

    擦除操作

    1. 擦除单位

      • 擦除操作是以Block为单位进行的,而不是Page。一个Block通常包含多个Page。

      • 擦除操作会清除整个Block中的所有数据,使其恢复到已擦除状态。

    2. 垃圾回收

      • SSD控制器中的垃圾回收机制会在需要回收陈旧Page以腾出空闲空间时自动触发擦除操作。

      • 垃圾回收过程会将有效数据从一个Block复制到另一个Block,然后擦除原来的Block。

      • 这个过程也会导致写入放大,因为需要额外的写入操作来移动数据。

    读取操作

    1. 读取操作

      • 读取操作是以Page为单位进行的。

      • 读取速度通常比写入和擦除操作快得多。

    优化策略

    对齐写入

    1. 按Page对齐写入

      • 尽量按Page的整倍大小写入数据,以避免写入放大。

      • 例如,如果Page大小是4KB,尽量每次写入4KB的整数倍数据。

    2. 合并小写入

      • 将多个小写入操作合并成一个大的写入操作,以减少写入放大。

      • 可以在内存中缓存小写入,当缓存满时再执行一次大写入。

    读-修改-写

    1. 避免读-修改-写

      • 如果写入的数据不是Page的整倍大小,会导致读-修改-写操作,即先读取整个Page,修改后再写回。

      • 读-修改-写操作比直接写入要慢,因为它涉及额外的读取和写入操作。

      • 通过按Page对齐写入,可以避免这种操作。

    缓冲区

    1. 使用缓冲区

      • 在内存中设置一个缓冲区,将小写入暂时存储在缓冲区中。

      • 当缓冲区满时,执行一次大写入,将所有数据一次性写入SSD。

      • 这种方法可以显著提高写入性能,并减少写入放大。

    TRIM命令

    1. 启用TRIM

      • TRIM命令允许操作系统通知SSD哪些Page不再使用,可以被回收。

      • 启用TRIM可以减少垃圾回收的工作量,降低写入放大。

      • 确保操作系统和文件系统支持并启用了TRIM。

    总结

    • 写入操作:首次写入时数据可以直接写入已擦除的Page;修改数据时,新数据写入空闲Page,旧Page标记为stale。

    • 擦除操作:以Block为单位进行,由垃圾回收机制自动触发。

    • 读取操作:以Page为单位进行,速度较快。

    • 优化策略

      • 按Page对齐写入,减少写入放大。

      • 合并小写入,使用缓冲区批量写入。

      • 避免读-修改-写操作。

      • 启用TRIM命令,帮助垃圾回收。

    通过这些优化策略,可以最大限度地提高SSD的性能和寿命。

  1. 写入放大的详细解释

    • 现象描述:当写入的数据小于一个 Page(SSD 存储的基本单位)时,系统为了按照 Page 为单位进行存储,会将剩余的空间填充(通常是用全 0 填充),使得实际写入的数据量达到一个 Page 的大小。这种情况就被称为 “写入放大”。例如,假设一个 Page 大小是 4KB,而要写入的数据只有 1KB,那么系统会将剩下的 3KB 空间用 0 填充后再写入,这就导致了实际写入的 4KB 比原本需要写入的 1KB 多了很多。

    • 对 SSD 性能和寿命的影响:写入放大现象对 SSD 的性能和寿命有显著的负面影响。从性能方面来看,由于写入的数据量比实际需要的多,这会增加写入操作的时间和资源消耗。每次写入放大都意味着更多的数据需要在 SSD 内部传输和写入闪存,这可能会降低写入速度,特别是在频繁进行小数据写入的场景中。从寿命角度考虑,SSD 闪存的寿命是有限的,主要取决于写入 / 擦除(P/E)循环次数。写入放大导致了更多的写入操作,会加速闪存的磨损,从而缩短 SSD 的使用寿命。例如,在 P/E 循环次数有限的 TLC 闪存中,频繁的写入放大可能会更快地耗尽闪存的寿命。

    • 如何减少写入放大:为了减少写入放大,一种方法是尽量使写入的数据大小为 Page 的整数倍。在软件层面,可以通过优化应用程序的写入逻辑来实现。例如,在数据库存储系统中,可以将多个小数据记录组合成一个大小接近 Page 整数倍的数据块后再进行写入。另外,一些 SSD 控制器也会采用先进的算法和缓存策略来缓解写入放大。比如,通过智能的缓存管理,将小数据积累到接近 Page 大小后再写入闪存,或者对频繁更新的数据进行特殊处理,以减少不必要的填充和额外写入。

细说TRIM命令

  1. TRIM 命令的定义与背景

    • 定义:TRIM 是一种高级命令,用于通知固态硬盘(SSD)哪些数据块(Data Blocks)是不再被使用的,这样 SSD 的控制器就可以在后台对这些无效数据块进行垃圾回收(Garbage Collection)和损耗均衡(Wear - Leveling)等操作,从而保持 SSD 的性能和延长其使用寿命。

    • 背景:在传统的机械硬盘(HDD)中,写入数据时可以直接覆盖原有数据,因为其存储原理是基于磁头在高速旋转的盘片上进行数据的读写。但 SSD 基于闪存(Flash)技术,数据的写入操作比较复杂。闪存不能直接覆盖写入,需要先擦除原有数据才能写入新数据。而且,擦除操作是以块(Block)为单位进行的,而写入操作的最小单位是页(Page)。当操作系统删除一个文件或者对文件进行修改后,SSD 并不知道这些数据已经是无效的,在没有 TRIM 命令的情况下,这些无效数据仍然会占据闪存空间,随着时间的推移,会导致 SSD 性能下降。

  2. TRIM 命令的工作机制

    • 操作系统层面:当操作系统(如 Windows、Linux 等)发出 TRIM 命令时,它会通过相应的存储驱动程序将这个命令传递给 SSD。例如,在 Windows 系统中,当用户删除一个文件或者格式化一个分区时,操作系统会在合适的时机发送 TRIM 命令给 SSD。这个命令包含了关于哪些数据块可以被视为无效的信息,通常是通过逻辑块地址(LBA - Logical Block Addressing)来标识这些数据块。

    • SSD 控制器层面:SSD 控制器收到 TRIM 命令后,会根据命令中提供的信息更新内部的闪存映射表(Flash Mapping Table)。这个映射表记录了逻辑地址和物理闪存地址之间的对应关系。通过更新映射表,控制器将这些被标记为无效的数据块标记为可回收状态。然后,在后台空闲时间或者在一定的条件下(如闪存空间不足、写入性能下降等),控制器会启动垃圾回收机制,将这些无效数据块中的有效数据迁移到其他空闲的块中,然后对这些无效块进行擦除操作,从而释放出空间用于新数据的写入。

  3. TRIM 命令的作用和好处

    • 性能提升:随着时间的推移,SSD 中如果积累了大量的无效数据,会导致写入性能下降。这是因为在写入新数据时,SSD 可能需要先处理这些无效数据,例如进行数据迁移等操作。TRIM 命令可以及时清理这些无效数据,使得 SSD 在写入新数据时可以直接使用空闲的空间,从而提高写入速度。例如,在频繁进行文件删除和更新的场景中,如数据库服务器或者文件服务器,启用 TRIM 命令可以显著提高 SSD 的写入性能。

    • 延长使用寿命:由于 SSD 的闪存具有有限的写入 / 擦除(P/E - Program/Erase)循环寿命,过多的无效数据会导致不必要的写入操作,从而加速闪存的磨损。TRIM 命令通过减少无效数据的积累,降低了垃圾回收和写入操作的频率,从而延长了 SSD 的使用寿命。特别是对于使用 TLC(Triple - Level Cell)和 QLC(Quad - Level Cell)等写入寿命相对较短的闪存类型的 SSD,TRIM 命令的作用更加明显。

  4. TRIM 命令的兼容性和启用方式

    • 兼容性:大多数现代操作系统都支持 TRIM 命令,包括 Windows 7 及以上版本、Linux 内核 3.1 及以上版本等。不过,要完全发挥 TRIM 命令的作用,还需要 SSD 本身也支持 TRIM 功能。一些较老的 SSD 或者低端 SSD 可能不支持 TRIM,在这种情况下,即使操作系统发送了 TRIM 命令,也无法实现对无效数据的有效清理。

    • 启用方式:在 Windows 系统中,TRIM 命令默认是启用的。用户可以通过在命令提示符(Command Prompt)中输入 “fsutil behavior query DisableDeleteNotify” 命令来检查是否启用了 TRIM。如果返回值为 “0”,则表示 TRIM 已启用;如果为 “1”,则表示 TRIM 被禁用。在 Linux 系统中,一般通过文件系统挂载选项来启用 TRIM。例如,在使用 ext4 文件系统挂载 SSD 分区时,可以在 “/etc/fstab” 文件中添加 “discard” 选项来启用 TRIM,如 “/dev/sda1 /mnt/ssd ext4 defaults,discard 0 0”。不过,在某些特殊情况下,启用 TRIM 可能会导致一些兼容性问题或者轻微的性能下降,如在使用某些 RAID(Redundant Array of Inexpensive Disks)配置或者加密文件系统时,需要谨慎使用。

TRIM 命令是 SSD 管理中的一个重要特性,它有助于提高 SSD 的性能和延长其使用寿命。下面是对 TRIM 命令的详细解释:

什么是 TRIM 命令?

TRIM 命令是一种 ATA 命令(对于 SATA 接口)或 NVMe 命令(对于 PCIe/NVMe 接口),允许操作系统通知 SSD 哪些数据块不再使用,可以被擦除并回收。这使得 SSD 可以更有效地管理其内部存储空间,并减少写入放大。

TRIM 命令的工作原理

  1. 标记未使用的数据块

    • 当文件在操作系统中被删除时,操作系统会将相应的逻辑地址标记为可用。

    • 但是,这些数据在 SSD 上仍然存在,只是被标记为无效。SSD 控制器并不知道这些数据块是否真的可以被回收。

  2. 发送 TRIM 命令

    • 操作系统通过 TRIM 命令告诉 SSD 哪些数据块不再使用。

    • 这些数据块会被标记为可擦除,但不会立即被擦除。

  3. 垃圾回收

    • 在需要回收空间时,SSD 控制器会在后台执行垃圾回收操作。

    • 由于已经知道了哪些数据块可以被擦除,控制器可以直接擦除这些块,而不需要先读取和移动有效数据。

TRIM 命令的优势

  1. 减少写入放大

    • 通过提前标记未使用的数据块,垃圾回收过程可以更高效地进行,减少了不必要的数据搬移。

    • 减少写入放大意味着减少了对 NAND 闪存的磨损,从而延长了 SSD 的寿命。

  2. 提高写入性能

    • 由于垃圾回收更加高效,写入操作的速度也会提高。

    • 未使用的数据块已经被标记为可擦除,因此新的写入操作可以直接利用这些空闲的空间,而不需要等待垃圾回收完成。

  3. 提高整体性能

    • 通过减少垃圾回收的频率和复杂性,TRIM 命令有助于保持 SSD 的长期高性能。

    • 避免了因频繁垃圾回收导致的性能下降。

启用 TRIM 命令

在 Windows 中启用 TRIM

  1. 检查 TRIM 是否已启用

    fsutil behavior query DisableDeleteNotify

    如果输出为 DisableDeleteNotify = 0,则 TRIM 已启用。如果为 1,则 TRIM 未启用。

  2. 启用 TRIM

    fsutil behavior set DisableDeleteNotify 0
  3. 定期运行优化工具

    • Windows 有一个内置的优化工具,可以手动或自动运行 TRIM 命令。

    • 打开“我的电脑”,右键点击 SSD,选择“属性” -> “工具” -> “优化”。

    • 你也可以使用命令行工具 defrag 来手动触发 TRIM:

      defrag C: /L /H /G

在 Linux 中启用 TRIM

  1. 检查文件系统支持

    • 确保你的文件系统支持 TRIM。常见的支持 TRIM 的文件系统包括 ext4 和 XFS。

  2. 挂载选项

    • /etc/fstab 文件中添加 discard 选项来启用 TRIM。例如:

      UUID=your-ssd-uuid /mnt/ssd ext4 defaults,discard 0 0
  3. 手动运行 TRIM

    • 使用 fstrim 命令手动运行 TRIM:

      sudo fstrim -v /
    • 你也可以设置一个定时任务(如 cron job)来定期运行 TRIM:

      0 2 * * * /sbin/fstrim -v / >> /var/log/fstrim.log

注意事项

  1. 过度使用 TRIM

    • 虽然 TRIM 有助于提高性能,但过于频繁地运行 TRIM 也可能增加 SSD 的负担。因此,建议按照推荐的频率(如每周一次)运行 TRIM。

  2. 不支持 TRIM 的 SSD

    • 一些老旧的 SSD 可能不支持 TRIM 命令。在这种情况下,启用 TRIM 可能没有效果,甚至可能导致问题。确保你的 SSD 支持 TRIM。

  3. RAID 配置

    • 在 RAID 配置中,TRIM 命令的支持可能有限。某些硬件 RAID 控制器和软件 RAID 解决方案可能不支持 TRIM 或需要特定的配置。

总结

TRIM 命令通过让操作系统通知 SSD 哪些数据块不再使用,从而提高了 SSD 的性能和寿命。在现代操作系统中,TRIM 通常是默认启用的,但在某些情况下可能需要手动配置。通过合理使用 TRIM 命令,你可以最大限度地发挥 SSD 的潜力,并延长其使用寿命。

  1. TRIM 命令与接口类型的关系

    • ATA 命令(SATA 接口):在 SATA 接口的 SSD 中,TRIM 是一种 ATA 命令。当操作系统检测到某些数据块不再需要时,会通过 SATA 接口发送这个 ATA - TRIM 命令给 SSD。SATA 接口是一种较为传统的硬盘接口,广泛应用于各种存储设备。通过这种方式,操作系统和 SSD 之间建立了一种通信机制,使得 SSD 能够知晓哪些数据块可以被回收利用。

    • NVMe 命令(PCIe/NVMe 接口):对于采用 PCIe/NVMe 接口的高性能 SSD,TRIM 以 NVMe 命令的形式存在。NVMe(Non - Volatile Memory Express)是专门为闪存存储设备设计的高性能接口协议。与 SATA 接口相比,NVMe 接口具有更高的带宽和更低的延迟,能够充分发挥 SSD 的性能优势。在这种接口下,TRIM 命令的传输更加高效,使得 SSD 可以更快地响应操作系统的请求,及时清理不再使用的数据块。

  2. TRIM 命令对 SSD 内部存储空间管理的作用

    • 有效空间回收:当操作系统发送 TRIM 命令后,SSD 能够精确地识别哪些数据块是可以被擦除的。这就好比给 SSD 一个 “清单”,让它知道哪些是 “垃圾” 可以清理。例如,在一个文件被删除或者被覆盖后,操作系统发送 TRIM 命令告知 SSD 相关的数据块已经不需要了。SSD 收到命令后,就可以将这些数据块标记为可回收状态,然后在适当的时候(比如垃圾回收过程中)进行擦除操作,将这些空间重新变为可用状态,从而增加了有效的存储空间。

    • 优化存储布局:TRIM 命令还有助于 SSD 优化其内部的存储布局。随着数据的不断写入和删除,SSD 内部的存储状态可能会变得混乱。通过 TRIM 命令清理无效数据块后,SSD 可以更加合理地安排新数据的存储位置,提高存储效率。例如,它可以将相关的数据存储在相邻的位置,方便后续的顺序读取和写入操作,进一步提升了 SSD 的性能。

  3. TRIM 命令减少写入放大的原理

    • 减少不必要的写入操作:写入放大是指实际写入到 SSD 中的数据量大于用户期望写入的数据量的现象。这主要是因为 SSD 的闪存写入特性,在写入新数据之前需要先擦除旧数据,而且擦除单位(Block)和写入单位(Page)不同。当没有 TRIM 命令时,SSD 可能会频繁地对包含无效数据的块进行不必要的操作。而 TRIM 命令使得 SSD 能够及时清理无效数据块,避免了在写入新数据时对这些无效数据进行额外的处理,从而减少了实际写入的数据量,有效地降低了写入放大系数。

    • 提高垃圾回收效率:垃圾回收机制是 SSD 维护内部存储空间的重要手段。在没有 TRIM 命令的情况下,垃圾回收过程可能会比较复杂和低效。因为 SSD 不知道哪些数据是真正的无效数据,可能会将一些还可能有用的数据块也进行处理。TRIM 命令为垃圾回收提供了明确的信息,使得垃圾回收可以更加精准地只处理那些被标记为无效的数据块,减少了对有效数据的移动和重新写入,从而减少了写入放大。

垃圾回收

数据以 Page 为单位写入到存储中。然而,存储器只能以较大的单位 Block 擦除。如果不再需要一个Block 中某些Page内的数据,仅会读取该块中含有有效数据的Page,并重新写入到另一个先前擦除的空 Block 中,然后将原来的 Block 进行擦除,擦除之后的 Block 又可以重新使用,这个过程叫做垃圾回收。

所有的SSD都包含不同程度的垃圾回收机制,但在执行的频率和速度上有所不同,垃圾回收占了SSD上写入放大的很大一部分。

比如上面这个例子中,在 Block 1000 中写入 x,y,z 三个数据,然后想要修改 PPN 为 0 的这块数据时由于不能覆盖,所以只能在 PPN 为 3 的 Page 上面写入 x` 。当后台的垃圾回收进程启动的时候会将有效的数据拷入到另一个空闲的 BLock 中,然后将原来的 Block 1000 中的数据擦除。


磨损平衡

SSD 擦除写入的次数也叫做 P/E 周期( program/erase cycle),由于 P/E 周期是有限的,所以假设SSD其中数据总是从同一个精确的块中读取和写入,那么这块 Block 很快就达到了使用寿命的上限,SSD控制器会将其标记为不可用。然后磁盘的整体容量会下降。

所以实现磨损均衡(wear leveling)是控制器的主要目标之一,即在块之间尽可能均匀地分配P/E周期,理想情况下,所有块都将达到其P/E周期限制并同时磨损。

我这里用长江存储致钛的图来解释一下,上面三张是没有磨损均衡的,那么反复写就会出现坏页,下面三张是有磨损均衡,那么控制器会根据不同的算法挑选出擦写次数较低的 Page 进行写入。

当然我们也知道,理论和现实总是有区别的,具体实现起来还是很难的。因为想要磨损均衡,那必须要写入的时候将一些Block的数据进行移动,这一过程本身会导致写入放大的增加。因此,块管理是最大化磨损均衡和最小化写入放大之间的权衡,也就是它是一个 trade-off 的艺术。


磨损均衡分为静态磨损均衡与动态磨损均衡。动态磨损平衡是指当需要更改某个Page中的数据时,将新的数据写入擦除次数较少的物理页上,同时将原页标为无效页,动态磨损平衡算法的缺点在于,如果刚刚写入的数据很快又被更新,那么,刚刚更新过的数据块很快又变成无效页,如果频繁更新,无疑会让保存冷数据的Block极少得到擦除,对闪存整体寿命产生不利影响。早期的SSD主控多用动态磨损平衡算法。

静态磨损均衡是在每次写入时从空白Page中挑选擦写次数最少的进行写入,并且为了防止冷数据的Block极少得到擦除,静态磨损均衡会在条件具备的情况下搬走长期占用Block的不变数据,将其释放出来用于新数据写入,从而避免过度消耗其他闪存单元的寿命。

你对磨损均衡(wear leveling)的理解非常准确。磨损均衡是SSD控制器用来延长SSD寿命的重要技术之一。通过均匀分配P/E周期,可以确保所有存储块的磨损程度大致相同,从而避免某些块过早失效导致整体容量下降。下面我将详细解释磨损均衡的工作原理、实现方法以及它与写入放大之间的权衡。

磨损均衡的工作原理

磨损均衡的核心目标是在所有存储块之间均匀分配P/E周期。这样做的目的是确保没有某个特定的块因为频繁的擦除和写入操作而提前达到其使用寿命的上限。以下是磨损均衡的一些关键点:

  1. 静态磨损均衡

    • 静态磨损均衡发生在垃圾回收过程中。当一个Block中的数据被标记为无效时,控制器会将该Block中的有效数据移动到其他Block中,然后擦除这个Block。

    • 通过这种方式,控制器可以确保所有Block的磨损程度大致相同。

  2. 动态磨损均衡

    • 动态磨损均衡发生在数据写入过程中。控制器会根据每个Block的P/E周期计数来选择一个磨损程度较低的Block进行写入。

    • 这样可以确保新写入的数据不会总是写入到同一个Block中,从而均匀地分配P/E周期。

实现方法

  1. P/E周期计数

    • 控制器维护一个P/E周期计数表,记录每个Block的擦除次数。

    • 在选择写入或垃圾回收的目标Block时,控制器会参考这个计数表,优先选择P/E周期较低的Block。

  2. 数据搬移

    • 在垃圾回收过程中,控制器会将有效数据从磨损程度较高的Block搬移到磨损程度较低的Block。

    • 这个过程可能会导致写入放大,因为需要额外的写入操作来移动数据。

  3. 算法优化

    • 控制器使用复杂的算法来平衡磨损均衡和写入放大之间的关系。例如,一些控制器可能会在垃圾回收时选择多个磨损程度较低的Block,以减少单次搬移的数据量。

写入放大与磨损均衡的权衡

磨损均衡和写入放大之间存在一种权衡关系。为了实现磨损均衡,控制器需要在写入和垃圾回收过程中进行数据搬移,这会导致写入放大。以下是一些具体的权衡点:

  1. 写入放大增加

    • 为了实现磨损均衡,控制器需要在垃圾回收过程中将有效数据从一个Block搬移到另一个Block。这会导致额外的写入操作,从而增加写入放大。

    • 例如,如果一个Block中有50%的有效数据,垃圾回收时需要将这些有效数据搬移到一个新的Block中,然后再擦除原来的Block。

  2. 性能影响

    • 数据搬移和垃圾回收操作会占用SSD的I/O带宽,可能会影响读写性能。

    • 如果垃圾回收过于频繁,可能会导致SSD的性能显著下降。

  3. 磨损均衡策略

    • 不同的SSD控制器可能会采用不同的磨损均衡策略。有些控制器可能更注重磨损均衡,即使这意味着更高的写入放大;而有些控制器则可能更注重性能,尽量减少写入放大。

    • 例如,一些高端SSD可能会使用更复杂的算法来平衡磨损均衡和写入放大,以实现最佳的整体性能和寿命。

总结

  • 磨损均衡:通过均匀分配P/E周期,确保所有存储块的磨损程度大致相同,从而延长SSD的使用寿命。

  • 静态磨损均衡:在垃圾回收过程中,将有效数据从磨损程度较高的Block搬移到磨损程度较低的Block。

  • 动态磨损均衡:在数据写入过程中,选择磨损程度较低的Block进行写入。

  • 写入放大:为了实现磨损均衡,控制器需要进行数据搬移,这会导致额外的写入操作,从而增加写入放大。

  • 权衡:磨损均衡和写入放大之间存在权衡关系,控制器需要在最大化磨损均衡和最小化写入放大之间找到一个平衡点。

通过理解这些概念和技术,你可以更好地了解SSD的工作原理,并在实际应用中做出更明智的选择。例如,在选择SSD时,可以考虑其磨损均衡算法和写入放大的控制能力,以确保获得最佳的性能和寿命。

  1. P/E 周期与 SSD 寿命的关联

    • P/E 周期的含义及限制:P/E 周期(Program/Erase Cycle)是指固态硬盘(SSD)中闪存芯片的写入(Program)和擦除(Erase)操作的循环次数。闪存的这种物理特性决定了它不能无限制地进行写入和擦除。例如,常见的 TLC(Triple - Level Cell)闪存的 P/E 周期一般在 1000 - 3000 次左右,而 SLC(Single - Level Cell)闪存的 P/E 周期可达到 10 万次左右。一旦某个块(Block)的 P/E 周期达到了其上限,这个块就会被 SSD 控制器标记为不可用。

    • 对 SSD 容量的影响:当 SSD 中的某些块因为达到 P/E 周期上限而不可用时,磁盘的整体可用容量会下降。这是因为这些不可用的块不能再存储新的数据,就好像一个仓库中有一部分空间因为损坏而无法使用一样。而且,如果大量的块都达到寿命上限,SSD 可能会出现性能下降、数据丢失等严重问题。

  2. 磨损均衡的目标与理想情况

    • 磨损均衡的目标:磨损均衡(Wear Leveling)是 SSD 控制器的一个重要功能,其主要目标是在 SSD 的各个块之间尽可能均匀地分配 P/E 周期。这样可以避免某些块因为过度使用而过早损坏,延长 SSD 的整体使用寿命。例如,通过合理地分配写入和擦除操作,使得所有的块都能在一定程度上被利用,而不是让少数几个块承担大部分的读写任务。

    • 理想的磨损均衡情况:在理想情况下,所有的块都将达到其 P/E 周期限制并同时磨损。这意味着整个 SSD 的闪存芯片都能被充分利用,没有因为局部过度磨损而导致的容量损失或性能下降。这种理想状态可以最大限度地发挥 SSD 的存储潜力,让用户能够更长久地使用 SSD 的全部容量。

  3. 磨损均衡的实现方式与挑战

    • 实现方式示例:以长江存储致钛的产品为例,通过图表可以直观地看到磨损均衡的效果。在没有磨损均衡的情况下,反复对同一个区域进行写入会导致出现坏页(无法正常存储数据的页面)。而有磨损均衡机制时,控制器会根据不同的算法挑选出擦写次数较低的页面(Page)进行写入。这些算法可能会考虑到各个块的擦写历史、当前的存储状态等多种因素。例如,一些算法会记录每个块的 P/E 周期次数,在有新的写入请求时,选择次数较低的块来执行写入操作。

    • 面临的挑战:虽然磨损均衡的理论目标很明确,但在实际实现中却面临诸多困难。其中一个关键问题是写入放大的增加。为了实现磨损均衡,需要将一些块的数据进行移动,例如,当选择一个擦写次数较低的块来写入新数据时,可能需要先将其他块中的有效数据移动到这个目标块中。这个过程会导致写入放大,即实际写入的数据量大于用户期望写入的数据量。因为每次数据移动都可能涉及多次写入操作,而且还可能会影响到 SSD 的性能和内部存储结构的稳定性。所以,在块管理中,需要在最大化磨损均衡和最小化写入放大之间进行权衡,这是一个复杂的平衡过程,需要精心设计控制器的算法和策略。


预留空间

预留空间 Over-provisioning,也叫OP,指的是 SSD 一般会保留一部分的空间对用户不可见,大多数的厂商都会预留7%到25%左右的空间,额外的预留空间有助于降低控制器写入闪存时的写入放大。用户可以通过将磁盘分区为低于其最大物理容量的逻辑容量来创建更多的过度配置。例如,可以在100 GB驱动器中创建一个90 GB分区,并将剩余的10 GB预留不使用。

比如下面的这种图中, 是我找到金士顿官网的预留空间图:

预留空间(Over-provisioning, OP)是SSD设计中的一个重要特性,它指的是SSD中的一部分存储空间对用户不可见,这部分空间被保留给控制器用于内部管理和优化。预留空间有助于提高SSD的性能和延长其使用寿命。以下是关于预留空间的详细解释:

什么是预留空间?

预留空间是指SSD中的一部分存储空间,这部分空间不向用户公开,而是留给SSD控制器进行内部管理和优化。通常,厂商会在SSD出厂时预设一定的预留空间,范围大约在7%到25%之间。

预留空间的作用

  1. 降低写入放大

    • 预留空间提供了额外的空间供垃圾回收使用。当需要回收陈旧数据块时,控制器可以将有效数据移动到预留空间中,然后再擦除原来的块。

    • 这样可以减少因垃圾回收导致的数据搬移,从而降低写入放大。

  2. 提高性能

    • 由于有额外的空间可用,控制器可以在更少的限制下进行垃圾回收和数据管理,从而提高写入性能。

    • 预留空间还可以帮助减少延迟,特别是在高负载情况下。

  3. 延长寿命

    • 通过减少写入放大,预留空间可以延长NAND闪存的P/E周期,从而延长SSD的整体使用寿命。

    • 由于磨损均衡更加均匀,所有存储块的磨损程度会更加一致,进一步延长了SSD的寿命。

  4. 改善垃圾回收效率

    • 预留空间使得垃圾回收过程更加高效,因为控制器有更多的空间来处理无效数据块。

    • 这减少了垃圾回收的频率和复杂性,从而提高了整体性能。

用户如何创建更多的预留空间

虽然大多数SSD出厂时已经预设了一定的预留空间,但用户也可以通过以下方法创建更多的预留空间:

  1. 分区设置

    • 在对SSD进行分区时,可以将逻辑容量设置为小于物理容量。例如,对于一个100GB的SSD,可以只创建一个90GB的分区,剩下的10GB作为预留空间。

    • 这可以通过磁盘管理工具(如Windows的磁盘管理器或Linux的fdisk/parted)来实现。

  2. 操作系统配置

    • 一些操作系统允许用户手动配置预留空间。例如,在Linux中,可以使用fstrim命令结合特定的挂载选项来实现。

    • 你可以在/etc/fstab文件中添加discard选项,并确保定期运行fstrim命令来维护预留空间。

示例:在Windows中创建预留空间

假设你有一个1TB的SSD,你想创建一个900GB的分区,留下100GB作为预留空间。以下是具体步骤:

  1. 打开磁盘管理器

    • Win + X 键,选择“磁盘管理”。

  2. 初始化新磁盘

    • 如果是新安装的SSD,可能需要先初始化磁盘。右键点击未分配的空间,选择“新建简单卷”。

  3. 创建分区

    • 在“新建简单卷向导”中,输入你希望的卷大小(例如900GB)。

    • 按照向导的提示完成分区创建。

  4. 格式化分区

    • 右键点击新创建的分区,选择“格式化”,选择文件系统(如NTFS),并设置卷标等信息。

    • 完成格式化后,这个分区就可以正常使用了。

总结

  • 预留空间:SSD中的一部分存储空间对用户不可见,用于内部管理和优化。

  • 作用:降低写入放大、提高性能、延长寿命、改善垃圾回收效率。

  • 用户配置:可以通过分区设置和操作系统配置来创建更多的预留空间。

通过合理配置预留空间,你可以显著提高SSD的性能和寿命,使其更好地服务于你的计算需求。

  1. 预留空间(Over - provisioning,OP)的定义和基本原理

    • 定义:预留空间是指固态硬盘(SSD)厂商在产品设计过程中,故意保留一部分磁盘空间,这部分空间对用户是不可见的。它是一种优化策略,用于提升 SSD 的性能和寿命。

    • 基本原理:通过预留空间,SSD 控制器在管理数据写入和存储时有了更多的 “缓冲地带”。当有新的数据写入时,控制器可以利用这部分预留空间更灵活地安排数据存储位置,避免了因空间紧张而频繁地进行垃圾回收和数据迁移等操作,从而减少写入放大。

  2. 预留空间对写入放大的影响

    • 写入放大的产生机制:写入放大主要是因为 SSD 闪存的写入特性,即不能直接覆盖写入,需要先擦除旧数据才能写入新数据,且擦除单位(Block)和写入单位(Page)不同。当没有足够的空闲空间时,为了写入新数据,可能需要对包含有效数据的块进行大量的垃圾回收和数据迁移操作,导致实际写入的数据量远远大于用户期望写入的数据量。

    • 预留空间的缓解作用:预留空间为控制器提供了更多的空闲块。当有新的数据写入时,控制器可以优先使用这些预留的空闲块,减少了对已存储数据块的干扰。例如,当写入的数据量较小,且有预留空间时,控制器可以直接将数据写入预留空间中的空闲块,而不需要对其他已存储数据的块进行复杂的操作,从而有效地降低了写入放大系数。

  3. 预留空间的常见比例和用户创建方式

    • 常见比例:大多数厂商会预留 7% 到 25% 左右的空间作为预留空间。不同厂商可能会根据产品的定位、闪存类型和预期的使用场景等因素来确定具体的预留空间比例。例如,对于一些高性能、高可靠性要求的企业级 SSD,预留空间比例可能会更高,接近 25%,以确保在高负载的数据写入和频繁的读写操作下,仍然能够保持良好的性能和较长的使用寿命。

    • 用户创建方式:用户可以通过将磁盘分区为低于其最大物理容量的逻辑容量来创建更多的过度配置。例如,对于一个 100GB 的驱动器,用户可以创建一个 90GB 的分区,将剩余的 10GB 预留不使用。这样,这 10GB 就成为了额外的预留空间,被 SSD 控制器用于优化数据存储和写入操作。这种方式为用户提供了一定的灵活性,可以根据自己的需求和对性能的期望来调整预留空间的大小。不过,需要注意的是,预留空间过多会导致用户可用空间减少,所以需要在性能提升和可用空间之间进行合理的权衡。

预留空间主要是给 SSD 控制器使用,一方面是用来做是用来做磨损平衡,替换可见空间中被磨损的 Block,另一方面是用来提升性能使用;

因为上面也提到了,SSD 的写入是无法覆盖的,只能在空白页面上写入,所以在这个过程中预留空间足够大则从空白的页中进行写入,可以减少擦除次数也能够减少有效数据的再次写入,降低 Block 的磨损,从而提升硬盘的耐用性。

预留空间在读写工作负载很重的时候可以充当NAND闪存块的缓冲区,帮助垃圾回收机制处理吸收写入高峰。因为垃圾回收擦除数据比写入要花费更多的时间,垃圾回收一般在空闲的时候做,如果在负载很重的时候垃圾回收来不及擦除,那么可能会和写入操作同时进行,而预留空间可以作为缓冲区给垃圾回收机制留出足够的时间来赶上并再次擦除块。

另一方面预留空间也可以减少垃圾回收次数,空白页面多了自然就不用频繁的做垃圾回收了,这同时也减少了写入放大。

Trim

简单来说,TRIM主要是优化固态硬盘,解决SSD使用后的降速与寿命的问题。

原本在机械硬盘上,写入数据时,Windows会通知硬盘先将以前的擦除,再将新的数据写入到磁盘中。而在删除数据时,Windows只会在此处做个标记,说明这里应该是没有东西了,等到真正要写入数据时再来真正删除,由于这个标记只是在操作系统层面,SSD 并不知道哪些数据被删了,所以我们日常的文件删除,都只是一个操作系统层面的逻辑删除。这也是为什么,很多时候我们不小心删除了对应的文件,我们可以通过各种恢复软件,把数据找回来。

SSD 只有当操作系统在同一个被删了的 Block 里面写入数据的时候才知道这个数据已经被删了,那么才会把它标记成废弃,等待垃圾回收。。这就导致,我们为了磨损均衡,很多时候在都在搬运很多已经删除了的数据。这就会产生很多不必要的数据读写和擦除,既消耗了 SSD 的性能,也缩短了 SSD 的使用寿命

比如上面这个图中,我们在系统层面删除了程序3,但是在SSD 的逻辑块层面,其实并不知道这个事情。这个时候,如果我们需要对 SSD 进行垃圾回收操作,程序3占用的物理页仍然要在这个过程中,被搬运到其他的 Block 里面去。只有当操作系统在里面重新写入数据的时候SSD才会把它标记成废弃掉。

TRIM指令让操作系统可以告诉固态驱动器哪些数据块是不会再使用的;否则SSD控制器不知道可以回收这些闲置数据块。TRIM的简约性将极大减少写入负担,同时允许SSD更好地在后台预删除闲置的数据块,以便让这些数据块可以更快地预备新的写入。

TRIM命令只有在SSD控制器、操作系统和文件系统支持它的情况下才有效。

  1. TRIM 的优化目标

    • TRIM 的主要目的是优化固态硬盘(SSD)的性能,着重解决 SSD 在使用一段时间后出现的速度下降和寿命缩短的问题。在 SSD 的使用过程中,由于其内部存储结构和工作原理与机械硬盘不同,会产生一些影响性能和寿命的因素,而 TRIM 就是为了应对这些问题而设计的。

  2. 机械硬盘与 SSD 写入和删除机制对比

    • 机械硬盘机制:在机械硬盘中,当 Windows 操作系统要写入数据时,会通知硬盘先擦除原有数据,然后再将新数据写入磁盘。这种方式相对直接,因为机械硬盘的存储介质是磁性材料,数据的覆盖写入比较容易实现。而在删除数据时,Windows 只是在文件系统层面做个标记,表示这个位置的数据已经被删除,但实际上数据仍然保留在磁盘上,直到新的数据覆盖写入这个位置。这种标记方式使得在需要时可以通过数据恢复软件找回被删除的数据。

    • SSD 机制与问题:SSD 的情况则不同。在删除数据时,同样只是操作系统层面的逻辑删除,SSD 本身并不知道哪些数据被删除了。只有当操作系统在同一个被删除数据的块(Block)里写入新数据时,SSD 才会意识到这个块中的部分数据已经被删除,然后将其标记为废弃,等待垃圾回收。这就导致在进行磨损均衡等操作时,可能会搬运很多实际上已经被删除的数据。因为磨损均衡算法通常是基于块的擦写次数来均衡数据的存储位置,而不知道哪些数据是真正无效的,所以会产生许多不必要的数据读写和擦除操作。这些额外的操作会消耗 SSD 的性能,比如降低读写速度,同时也会因为增加了闪存的写入 / 擦除(P/E)次数而缩短 SSD 的使用寿命。

并发性

来看并发性之前,先来看看 SSD 具体的层级结构,SSD 使用层级的方式管理NAND Flash。Controller会使用多Channel的方式与NAND Flash Chip连接。每个Channel可以被视为一条数据传输路线,多个通道可以让控制器同时读写更多的数据,提高数据传输的速度和效率。每个NAND Flash Chip内部封装(Packaging)了多个Die,每个Die上排列了多个Plane,每个Plane中包含多个Block,每个Block中有多个Page。

  • Channel级别:Controller可以同时使用多个Channel在不同的NAND Flash Chip上执行不同的操作

  • Chip级别:连接在相同Channel上的不同的不同Chip,也可以使用流水线(Interleaving)的方式同时执行不同的命令

  • Die级别:一个Chip封装多个Die,Chip可以把不同的命令发送到多个Die上并行执行

  • Plane级别:一个Die包含多个Plane,相同的命令(读、写、擦除)可以在一个Die的多个Plane上同时执行

像我们上面提到的 990 Pro 这款 SSD,有 8条 Channel,每条Channel可以传输2,000 MT/s,MT/s代表每秒百万次传输(MegaTransfers per second)。每个 Chip 里面有 16 个 Die,每个 Die 有 4 个 Plane。

  1. SSD 层级结构回顾

    • SSD 采用层级式的结构来管理 NAND Flash。这种结构从宏观的控制器(Controller)到微观的 Page,每一层级都有其特定的功能和作用。其中,控制器是整个 SSD 的核心管理部件,它通过多个 Channel 与 NAND Flash Chip 相连。

  2. 通道(Channel)的作用

    • 数据传输路线类比:可以将每个 Channel 看作是一条独立的数据传输路线。就像在一个交通网络中,多条道路可以同时允许车辆行驶,多个通道使得控制器能够同时进行多个数据的读写操作。例如,在一个拥有 4 个通道的 SSD 中,控制器理论上可以同时向 4 个不同的 NAND Flash Chip 发送读写指令,这大大提高了数据传输的速度和效率。这种并行的数据传输方式是 SSD 实现高速读写的一个重要因素。

  3. NAND Flash 内部结构细化

    • 封装(Packaging)内的 Die:每个 NAND Flash Chip 内部有多个 Die。Die 可以看作是 NAND Flash 的基本功能单元,它们在物理上是相对独立的,并且每个 Die 都能够进行数据的存储和读取操作。

    • Die 上的 Plane:在每个 Die 上排列着多个 Plane。Plane 同样是存储单元的一种划分,它们在存储和读取数据时也具有一定的独立性,并且在某些操作模式下可以同时工作,进一步提高了数据处理的并行性。

    • Plane 中的 Block 和 Page:每个 Plane 包含多个 Block,而 Block 又是由多个 Page 组成的。Page 是 SSD 写入和读取数据的最小单位,Block 则是擦除操作的最小单位。这种精细的划分使得 SSD 在数据存储和管理上更加灵活,能够根据不同的读写需求和数据类型,采用合适的操作单位来优化性能。例如,在写入小文件时,可以以 Page 为单位进行操作,而在进行垃圾回收等操作时,则以 Block 为单位来处理无效数据。

了解SSD的层级结构对于理解其并发性至关重要。SSD通过多层结构和并行处理来提高数据传输速度和效率。下面是SSD的具体层级结构及其对并发性的影响:

SSD 层级结构

  1. Controller(控制器)

    • 控制器是SSD的大脑,负责管理所有读写操作、垃圾回收、磨损均衡等。

    • 控制器通过多个通道(Channel)与NAND Flash芯片连接,实现并行数据传输。

  2. Channel(通道)

    • 每个通道是一条独立的数据传输路线,允许多个通道同时进行读写操作。

    • 通道的数量越多,SSD可以同时处理的数据量就越大,从而提高整体性能。

  3. NAND Flash Chip(闪存芯片)

    • 每个NAND Flash芯片内部封装了多个Die。

    • 通过多个通道连接多个NAND Flash芯片,可以进一步提高并发性和数据传输速率。

  4. Die(晶粒)

    • Die是NAND Flash芯片中的一个独立存储单元,每个Die可以独立进行读写操作。

    • 多个Die可以通过并行操作来提高数据吞吐量。

  5. Plane(平面)

    • 每个Die包含多个Plane,每个Plane可以独立进行读写操作。

    • Plane的存在使得Die可以在同一时间处理更多的读写请求,进一步提高并发性。

  6. Block(块)

    • 每个Plane包含多个Block,Block是擦除操作的基本单位。

    • 擦除操作只能在Block级别进行,而不能在Page级别进行。

  7. Page(页)

    • 每个Block包含多个Page,Page是读写操作的基本单位。

    • 读写操作可以在Page级别进行,但必须在一个Block内完成。

并发性的实现

通过上述层级结构,SSD能够实现高度的并发性,从而提高数据传输速度和效率。以下是并发性在不同层级的具体实现:

1. 多通道(Multi-Channel)

  • 并行数据传输:控制器通过多个通道同时与多个NAND Flash芯片进行数据传输。

  • 提高带宽:每个通道都可以独立传输数据,因此总带宽是单个通道带宽的倍数。

2. 多Die(Multi-Die)

  • 独立操作:每个Die可以独立进行读写操作,这意味着多个Die可以同时处理不同的读写请求。

  • 增加并发度:通过多个Die的并行操作,可以显著提高数据吞吐量。

3. 多Plane(Multi-Plane)

  • 独立读写:每个Plane可以独立进行读写操作,这意味着在一个Die中,多个Plane可以同时处理不同的读写请求。

  • 提高响应速度:通过多个Plane的并行操作,可以减少读写操作的延迟,提高响应速度。

示例

假设一个SSD有以下配置:

  • 8个通道,每个通道连接一个NAND Flash芯片。

  • 每个NAND Flash芯片有4个Die

  • 每个Die有2个Plane

  • 每个Plane有1024个Block

  • 每个Block有256个Page

在这种情况下,SSD可以实现以下并发性:

  • 8个通道可以同时传输数据,提高了数据传输的带宽。

  • 每个通道上的4个Die可以独立进行读写操作,增加了并发度。

  • 每个Die上的2个Plane可以同时处理读写请求,进一步提高了并发性。

总结

  • 多通道:允许多个NAND Flash芯片同时进行数据传输,提高总带宽。

  • 多Die:每个Die可以独立进行读写操作,增加并发度。

  • 多Plane:每个Plane可以独立进行读写操作,进一步提高并发性和响应速度。

通过这些层级结构和并行处理机制,SSD能够实现高效的并发性,从而提供高速的数据传输和低延迟的读写操作。这种设计使得SSD在处理大量并发I/O请求时表现出色,特别适用于高性能计算、数据中心和企业级应用。

写的并发性

所以通过上面信息可以知道,SSD 是可以并行写入多个 Block 的,所以利用 SSD 多级并行机制,可以被并行访问的最大数量的 Block 集合称为一组 Cluster Blocks,它的可以从几十MB到几百MB,具体取决于控制器策略、SSD 容量、NAND 闪存类型等,不过我查过了,一般厂商没有给出这个具体的大小。

利用Cluster Blocks的并行性能,SSD可以把一次大块写打散到多个Cluster Blocks上并行执行,有效降低时延,提高吞吐量。

如果写操作每次写入的数据量小于 Cluster Blocks 大小时则顺序写的吞吐量显著高于随机写,所以如果随机写入既是Cluster Blocks 的倍数,那么它们的性能与顺序写入一样好。两者的区别主要体现在以下两个方面:

  • 小块写入会导致更多的映射表更新,而顺序写可以合并映射表的更新;

  • 小块随机写更容易造成某个Block中少量的Page被设置为无效,需要进行擦除,加剧垃圾回收过程的写放大;

最后,关于并发,其实用一个线程写入一大块数据和用许多并发线程写入许多较小块数据一样快。事实上,一个大写入保证了SSD的所有内部并行性都被使用。因此,尝试并行执行多个写入不会提高吞吐量。然而,与单线程访问相比,许多并行写入会导致延迟增加。所以一次大写入比多次小并发写入要好。

再来就是当写入很小并且无法合并的时候,多线程是有益的,许多并发的小写请求将提供比单个小写请求更好的吞吐量。所以如果I/O很小并且无法批处理,最好使用多个线程。

总结就是这样:

大块写

小块写

单线程

最快

最慢

多线程并发

无助于吞吐量,提高时延

有助于提高多级并发机制的利用,提高吞吐量

  1. Cluster Blocks 的概念及特性

    • 定义与大小范围:SSD 可以并行写入多个 Block,利用 SSD 的多级并行机制,可被并行访问的最大数量的 Block 集合称为一组 Cluster Blocks。其大小通常在几十 MB 到几百 MB 之间,具体取决于控制器策略、SSD 容量、NAND 闪存类型等多种因素。由于各厂商通常不会明确给出这个具体大小,所以在实际应用中需要通过测试和经验来大致了解其范围。

    • 并行性能优势:利用 Cluster Blocks 的并行性能,SSD 可以将一次大块写操作打散到多个 Cluster Blocks 上并行执行。这就好比将一个大任务分解成多个小任务同时进行处理,能够有效降低时延,提高吞吐量。例如,在进行大数据文件写入时,SSD 可以同时对多个 Block 进行写入操作,大大缩短了写入时间。

  2. 顺序写与随机写对比

    • 性能差异:如果写操作每次写入的数据量小于 Cluster Blocks 大小时,顺序写的吞吐量显著高于随机写。这是因为顺序写可以更好地利用 SSD 的内部结构和并行机制,减少了寻址和数据调度的时间开销。而随机写由于数据的分散性,需要更多的时间来定位和写入数据。然而,如果随机写入的数据量是 Cluster Blocks 的倍数,那么它们的性能与顺序写入一样好。这是因为在这种情况下,随机写也可以充分利用 SSD 的并行性能,将数据分散到多个 Cluster Blocks 上同时写入。

    • 区别体现:两者的区别主要体现在两个方面。一方面,小块写入会导致更多的映射表更新,而顺序写可以合并映射表的更新。映射表是用于记录逻辑地址和物理地址对应关系的重要数据结构,频繁的小块写入会不断更新映射表,增加了系统的负担。另一方面,小块随机写更容易造成某个 Block 中少量的 Page 被设置为无效,需要进行擦除,加剧了垃圾回收过程的写放大。而顺序写可以减少无效 Page 的产生,降低垃圾回收的频率。

  3. 并发写入的性能分析

    • 大写入与多线程小写入的比较:关于并发,用一个线程写入一大块数据和用许多并发线程写入许多较小块数据在某些情况下速度一样快。事实上,一个大写入保证了 SSD 的所有内部并行性都被使用。因此,尝试并行执行多个写入通常不会提高吞吐量。然而,与单线程访问相比,许多并行写入会导致延迟增加。这是因为多个线程同时竞争 SSD 的资源,可能会导致资源冲突和调度开销增加。所以,一次大写入比多次小并发写入要好。

    • 小数据写入时多线程的优势:当写入的数据很小并且无法合并的时候,多线程是有益的。许多并发的小写请求将提供比单个小写请求更好的吞吐量。这是因为多个线程可以同时处理小数据写入,充分利用 SSD 的并行性能,提高系统的整体响应速度。所以,如果 I/O 很小并且无法批处理,最好使用多个线程。这样可以在一定程度上提高系统的性能,减少小数据写入的延迟。

你对SSD的写并发性和Cluster Blocks的理解非常到位。下面我将详细解释这些概念,并补充一些关键点,以确保对这些概念有更全面的理解。

Cluster Blocks 和并行写入

Cluster Blocks 是指一组可以被并行访问的最大数量的Block集合。这个集合的大小取决于控制器策略、SSD容量、NAND闪存类型等因素。虽然具体大小因厂商而异,但通常在几十MB到几百MB之间。

利用Cluster Blocks的并行性能,SSD可以将一次大块写操作打散到多个Cluster Blocks上并行执行,从而有效降低时延并提高吞吐量。

顺序写与随机写

  1. 顺序写

    • 顺序写是指连续地写入大量数据,通常是按Page或Block的顺序进行。

    • 顺序写的优势在于它可以最大化利用SSD的内部并行性,减少映射表更新的频率,从而提高吞吐量和减少写放大。

    • 例如,一个大文件的连续写入可以充分利用Cluster Blocks的并行性,实现高性能的数据传输。

  2. 随机写

    • 随机写是指不连续地写入小块数据,这些数据分布在不同的位置。

    • 随机写会导致更多的映射表更新,因为每个小块写入都需要更新映射表。

    • 随机写还可能导致某些Block中只有少量Page被设置为无效,这会增加垃圾回收的复杂性和写放大。

写操作的并发性

单线程大块写入 vs 多线程小块写入

  1. 单线程大块写入

    • 当写入的数据量较大且可以合并时,单线程的大块写入可以充分利用SSD的内部并行性。

    • 由于数据是连续的,映射表更新较少,垃圾回收的压力也较小,因此这种写入方式可以获得较高的吞吐量和较低的延迟。

    • 例如,一个大文件的连续写入可以通过单线程高效完成。

  2. 多线程小块写入

    • 当写入的数据量较小且无法合并时,多线程的小块写入可以提供更好的吞吐量。

    • 每个小块写入可能涉及不同的Cluster Blocks,通过多个线程并发写入,可以充分利用SSD的并行性。

    • 但是,多线程写入会增加映射表更新的频率,导致更多的写放大,并且可能会增加整体的延迟。

    • 例如,数据库事务中的小块写入可以通过多线程并发执行来提高性能。

具体应用场景

  • 大文件传输:对于大文件的连续写入,使用单线程大块写入是最优选择。这样可以最大化利用SSD的内部并行性,提高吞吐量并减少延迟。

  • 数据库事务:对于数据库中的小块随机写入,使用多线程并发写入可以提高吞吐量。尽管会有更多的映射表更新和写放大,但总体性能会更好。

  • 日志记录:对于频繁的小块写入(如日志记录),使用多线程并发写入可以显著提高性能,因为这些写入操作通常是独立且分散的。

总结

  • Cluster Blocks:一组可以并行访问的最大数量的Block集合,用于提高写入性能。

  • 顺序写:适用于大块连续数据写入,可以最大化利用SSD的内部并行性,提高吞吐量和减少写放大。

  • 随机写:适用于小块分散数据写入,需要更多的映射表更新和垃圾回收,导致更高的写放大和延迟。

  • 单线程大块写入:适用于大文件连续写入,可以充分利用SSD的并行性,提高性能。

  • 多线程小块写入:适用于小块分散写入,可以提高吞吐量,但会增加映射表更新和写放大。

通过理解这些概念和技术,你可以更好地优化应用程序的I/O操作,从而提高SSD的整体性能和寿命。

读的并发性

同样的为了提高读取性能,最好将相关数据一起写入。因为读取性能是写入模式的结果。当一次写入一大块数据时,它会分布在单独的NAND闪存芯片上。因此,您应该在同一页、块或集群块中写入相关数据,这样以后就可以利用内部并行性,通过单个I/O请求更快地读取这些数据。

因为写入的时候SSD会尽量的把所写的Page打散到多个Clustered Block上进行并行,那么读操作如果同时读取这些Page将会获得最多的并行。相反如果读操作总是读取不同写操作写入的Page,那么这些Page很可能处于相同的Plane上,必须串行读取。如上图所示。

对于多线程并发小块数据读取来说,性能是不如单线程大块数据读取的,因为这不能用到预读机制,这种机制通过预先读取可能接下来会被请求的数据到缓存中,减少了数据访问的等待时间,从而提升了读取性能。

在编程时如何更好的利用SSD

更好的利用SSD可以获得一些免费的好处,如:提升应用程序性能、延长SSD的寿命、提高SSD的 IO 效率等等。

区分冷热数据

假设我们将冷热数据混合排布在同一个区块,对于 SSD 来说,如果要修改其中的一小块内容(小于 1 页),SSD 仍然会读取整页的数据,这样会导致写入放大。所以对于一些改动非常频繁的热数据应该尽可能的 cache 住在内存里,然后批量的进行更新,这样不仅更快,而且还能提升SSD寿命。

采用紧凑的数据结构

这其实也和 SSD 的结构相关,更紧凑的数据结构可以尽量让数据都聚拢在同一个 Block 中,减少 SSD 的读取操作,同时也能更好的利用缓存。同样的,由于SSD 写入方式的特殊性,紧凑数据结构将关联数据放置到相邻区域,减少可能的垃圾回收的同时,还能够降低写入放大带来的问题。

写的数据最好是页大小的倍数

避免写入小于NAND闪存页面大小的数据块,以最大限度地减少写入放大并防止读取-修改-写入操作。目前页面的最大大小为16 KB,因此默认情况下应使用该值,此大小取决于SSD型号。

当数据不足一页时为了最大限度地提高吞吐量,尽可能将小写入保留到RAM中的缓冲区中,当缓冲区已满时,执行一次大写入以批处理所有小写入。

将相关数据一起写入

读取性能是写入模式的结果。当一次写入一大块数据时,它会分布在单独的NAND闪存芯片上。因此,您应该在同一 Page、Block或 clustered block 中写入相关数据,这样以后就可以利用内部并行性,通过单个I/O请求更快地读取这些数据。

尽量避免读写混合

由小交错读写混合组成的工作负载将阻止内部缓存和预读机制正常工作,并将导致吞吐量下降。最好避免同时读取和写入,并在大块中一个接一个地执行它们,最好是clustered block的大小。例如,如果必须更新1000个文件,您可以迭代文件,对文件进行读写,然后移动到下一个文件,但那会很慢。最好一次读取所有1000个文件,然后一次写回这1000个文件。

不要总以为随机写入比顺序写入慢

如果写入很小(即低于clustered block的大小),则随机写入比顺序写入慢。如果写入既是clustered block的倍数,又与clustered block的大小对齐,随机写入将使用所有可用的内部并行级别,并且执行与顺序写入一样好。对于大多数驱动器,集群块的大小为16 MB或32 MB,因此使用32 MB是安全的。

大型单线程读取优于许多小型并发读取

上面我们也提到了,并发随机读取不能充分利用预读机制。此外,多个逻辑块地址可能最终在同一芯片上,没有利用或内部并行性。大型读取操作将访问顺序地址,因此能够使用预读缓冲区(如果存在)并使用内部并行性。因此,如果用例允许,最好发出大型读取请求。

大型单线程写入优于许多小型并发写入

大型单线程写入请求提供与许多小型并发写入相同的吞吐量,但是就延迟而言,大型单线程写入比并发写入具有更好的响应时间。因此,只要有可能,最好执行单线程大型写入。

当写入量很小并且无法分组或缓冲时,才使用多线程写

许多并发的小写请求将提供比单个小写请求更好的吞吐量。所以如果I/O很小并且无法批处理,最好使用多个线程。

对于读写负载很高的工作,应该配置更大的预留空间

预留空间有助于磨损均衡机制应对NAND闪存单元固有的有限生命周期。对于写入不那么重的工作负载,10%到15%的过度配置就足够了。对于持续随机写入的工作负载,保持高达25%的过度配置将提高性能。过度配置将充当NAND闪存块的缓冲区,帮助垃圾回收机制处理吸收写入高峰。

  1. 提高读取性能的方法

    • 为了提高读取性能,最好将相关数据一起写入。这是因为读取性能在很大程度上取决于写入模式。当一次写入一大块数据时,数据会分布在单独的 NAND 闪存芯片上。例如,假设一个 SSD 由多个 NAND 闪存芯片组成,当进行一次大容量的数据写入操作时,数据会被分散存储在不同的芯片上,这样可以充分利用 SSD 的并行写入能力。而如果在写入时将相关数据一起写入,例如将一个文件的所有数据块连续写入,那么在读取时就可以利用 SSD 的内部并行性,通过单个 I/O 请求更快地读取这些数据。

    • 具体来说,应该在同一页(Page)、块(Block)或集群块(Cluster Blocks)中写入相关数据。这样做的好处是,当需要读取这些相关数据时,SSD 可以同时从多个存储单元中读取数据,提高读取速度。例如,如果一个数据库系统将相关的表数据一起写入到 SSD 的同一个 Block 中,那么在查询这些数据时,SSD 可以更快地读取这些数据,因为它们可以同时从多个 Page 中读取,而不是分散在不同的 Block 或 Plane 中。

  2. 读操作的并行性与限制

    • 由于写入的时候 SSD 会尽量把所写的 Page 打散到多个 Clustered Block 上进行并行,所以读操作如果同时读取这些 Page 将会获得最多的并行。这是因为这些 Page 分布在不同的存储单元中,可以同时被读取。例如,当一个应用程序需要读取一个大文件时,如果这个文件的数据在写入时被分散存储在多个 Clustered Block 中,那么在读取时,SSD 可以同时从多个 Block 中读取这些数据,大大提高了读取速度。

    • 相反,如果读操作总是读取不同写操作写入的 Page,那么这些 Page 很可能处于相同的 Plane 上,必须串行读取。这是因为在 SSD 的层级结构中,同一 Plane 上的 Page 通常不能同时被读取,需要依次进行读取操作。例如,如果一个数据库系统的查询操作总是随机读取不同文件的数据,那么这些数据很可能分布在同一个 Plane 上,导致读取速度变慢。

  3. 多线程并发小块数据读取与单线程大块数据读取的性能对比

    • 对于多线程并发小块数据读取来说,性能是不如单线程大块数据读取的。这主要是因为多线程并发小块数据读取不能用到预读机制。预读机制是指 SSD 通过预先读取可能接下来会被请求的数据到缓存中,减少了数据访问的等待时间,从而提升了读取性能。例如,当一个应用程序顺序读取一个大文件时,SSD 可以预测到接下来可能会读取的部分数据,并提前将这些数据读取到缓存中。这样,当应用程序真正需要这些数据时,可以直接从缓存中读取,大大提高了读取速度。

    • 而在多线程并发小块数据读取的情况下,由于数据的随机性和分散性,SSD 很难准确预测哪些数据会被接下来请求,因此无法有效地利用预读机制。例如,多个线程同时随机读取小数据块时,SSD 无法确定哪些数据会被下一个线程请求,所以无法提前将数据读取到缓存中,导致读取性能不如单线程大块数据读取。

你对SSD读取性能的理解非常准确。为了提高读取性能,确实需要考虑数据的写入模式和内部并行性。下面我将进一步详细解释这些概念,并提供一些优化建议。

读取性能与写入模式

写入模式的影响

  1. 大块连续写入

    • 当一次写入一大块数据时,SSD控制器会尽量将这些数据分散到多个NAND闪存芯片、Die、Plane或Cluster Blocks上,以便利用内部并行性。

    • 这种写入方式可以确保在后续读取时,可以通过并行读取来提高性能。

  2. 小块随机写入

    • 如果数据是通过多次小块随机写入的,那么这些数据可能会分布在不同的位置,甚至可能在同一Plane内。

    • 在这种情况下,读取这些数据时无法充分利用并行性,因为同一Plane内的Page必须串行读取。

读取并发性

单线程大块读取 vs 多线程小块读取

  1. 单线程大块读取

    • 单线程的大块读取可以充分利用SSD的内部并行性。

    • 控制器可以同时从多个NAND闪存芯片、Die、Plane或Cluster Blocks中读取数据,从而提高吞吐量。

    • 此外,预读机制(Prefetching)在这种情况下也非常有效。预读机制会预先将可能接下来会被请求的数据加载到缓存中,减少数据访问的等待时间,进一步提升读取性能。

  2. 多线程小块读取

    • 多线程的小块读取虽然可以增加并发性,但由于每个小块读取涉及的数据量较小,且可能分布不均匀,因此无法充分利用SSD的内部并行性。

    • 每个小块读取可能需要独立的I/O请求,增加了I/O开销。

    • 预读机制在这种情况下效果有限,因为小块数据的读取模式较难预测。

优化策略

  1. 数据布局优化

    • 尽量将相关数据一起写入,这样在读取时可以利用内部并行性。

    • 确保数据在写入时被分散到多个NAND闪存芯片、Die、Plane或Cluster Blocks上。

  2. 合并小块读取

    • 如果应用中存在大量小块读取操作,可以尝试将这些小块读取合并成一个大的读取请求。

    • 例如,在数据库查询中,可以将多个小块读取合并为一个大的范围查询。

  3. 预读机制

    • 利用SSD的预读机制,提前将可能被请求的数据加载到缓存中。

    • 许多操作系统和文件系统都支持预读机制,如Linux中的readahead

  4. 使用合适的数据结构

    • 使用合适的数据结构来组织数据,以便更好地进行批量读取。

    • 例如,在日志文件中,可以将相关的日志条目存储在一起,而不是分散存储。

  5. I/O调度器优化

    • 选择合适的I/O调度器,以优化读取性能。

    • 对于SSD,通常推荐使用noopdeadline调度器,因为它们减少了延迟并提高了响应速度。

示例

假设你有一个应用程序需要频繁读取大量小块数据:

  • 原始情况:每次读取一个小块数据,导致大量的I/O请求,性能较差。

  • 优化后:将这些小块数据合并成一个大的读取请求,或者将相关数据存储在一起,这样可以在一次读取中获取所有所需数据,显著提高读取性能。

总结

  • 写入模式:大块连续写入可以更好地利用SSD的内部并行性,而小块随机写入会导致数据分布不均,影响读取性能。

  • 读取并发性:单线程大块读取可以充分利用并行性和预读机制,而多线程小块读取则难以发挥这些优势。

  • 优化策略:通过数据布局优化、合并小块读取、利用预读机制、选择合适的数据结构和I/O调度器,可以显著提高SSD的读取性能。

通过这些优化策略,你可以更好地利用SSD的高性能特性,提高应用程序的整体性能。