首页 > 其他分享 >学习SSD—day1_20240814

学习SSD—day1_20240814

时间:2024-08-16 14:38:24浏览次数:13  
标签:闪存 主机 写入 day1 命令 20240814 SSD 数据

1.SSD的基本概念以及结构

   SSD是一种以半导体(半导体闪存)作为存储介质吗,使用纯电子电路实现的存储设备。   

   SSD硬件包括几大组成部分:主控、闪存、缓存芯片DRAM(可选,有些SSD上可能只有SRAM,并没有配置DRAM)、PCB(电源芯片、电阻、电容等)、接口(SATA、SAS、PCIe等),其主体就是一块PCB

C:\Users\xiaoyuhao\Documents\WeChat Files\wxid_ecocdhno0e8r22\FileStorage\Temp\1723789660661.jpg

1.1主控的主要功能

  (1)负责数据的读些管理:将主机请求的数据读写操作在NAND闪存中完成,并进行必要的缓冲、排序、纠错。

  (2)垃圾回收:根据闪存的特性,数据不能直接覆盖,需要将数据进行擦除后再重新写入,主控来管理这个过程

  (3)磨损均衡:主控需要控制闪存各部分的擦写次数,这样才能避免部分闪存块因过度擦写而损坏 

  (4)错误纠正:我了解到有ECC纠错,主要原理是通过汉明码纠正出发生bit反转的位置。因为大多数的bit反转可以通过重启解决,所以ecc基本都用在服务器的存储设备中,例如内存和固态。且价格相对比消费级产品较贵。

  (5)固件更新:很多产品使用时都会出现bug或是一些不足,通过固件更新来改善或修复这些问题。

  (6)加密:保证数据安全

1.2闪存

  (1)闪存是一种非易失性存储器。非易失性就意味着断电后数据仍然会保留。闪存的存储单元是由浮动栅极晶体管组成的阵列,每个存储单元可以存储一位或者多位的数据,例如以下类型的单元:

  SLC 单层单元、MLC多层单元,TLC三层单元、QLC四层单元。这几个存储的单元存储数据的位数依次增加,可靠性与速度依次降低成本依次下降。

  (2)读写特性:写入时需要将数据写进闪存页,并且再写入数据是不能直接覆盖,写入速度受限于擦除速度。

2.NVME协议基础

  整个固态硬盘存储基本流程其实很简单,数据经过计算机等设备的物理接口,此时进入物理存储层;接着通过闪存转换层,由物理信息转换成逻辑代码,并被计算机识别,整个存储过程结束。而在存储过程中,存在着一系列协议和指令,去引导相关设备进行工作,其中指令协议就起到总体指挥调配的作用,而逻辑协议则是作用于逻辑层中。

C:\Users\xiaoyuhao\Documents\WeChat Files\wxid_ecocdhno0e8r22\FileStorage\Temp\1723789686783.jpg

  常见消费级指令协议、逻辑协议以及物理接口旗下的名词配对关系。

物理接口

逻辑协议

指令协议

SATA

AHCI

ATA

M.2/PCIe

PCIe/U2

NVMe

NVMe

  2.1NVME 定义和作用

  NVMe,全称为Non-Volatile Memory Express, 是一种基于非易失性存储器的传输规范,是跑在PCIE接口上的标准协议制定了Host与SSD之间的通讯命令格式以及命令的执行过程.NVME的诞生以及优势的详细介绍: https://mp.weixin.qq.com/s/nVF2LJlZzlQwWn6OI0cb-g   

  2.2NVME 命令

NVME包含两种命令:Admin CommandIO Command, Admin Command作用:用于Host管理和控制SSD, IO Command作用:用于Host和SSD之间传输数据

  2.3nvme命令执行过程

  • 1. Host写指令到SQ中:
    主机(Host)生成一个写命令,并将其写入到NVMe提交队列(Submission Queue,SQ)中。这个队列位于主机的内存中,队列中存储了多个要执行的命令。每个命令都有一个描述符,其中包含了命令类型(如读、写)、目标地址、数据长度等信息。
  • 2. Host写DoorBell,通知SSD取指令:
    主机在将命令写入提交队列后,会通过写入“DoorBell寄存器”通知SSD控制器,告知有新的命令已经放入队列。这个寄存器类似于一个“门铃”,它是SSD控制器用于接收通知的方式。
  • 3. SSD收到通知,从SQ中取走指令:
    SSD控制器接收到主机的通知后,会读取提交队列中的命令。SSD控制器知道从哪里开始读取命令,因为主机会更新队列的“头指针”,指向最新放入的命令。
  • 4. SSD执行指令:
    SSD控制器解析命令,根据命令的类型执行相应的操作。例如,对于写命令,SSD会将主机提供的数据写入到内部的NAND闪存中。对于读命令,SSD会从NAND闪存中读取数据并准备返回给主机。
  • 5. SSD执行指令完成,将执行结果写入CQ中:
    当SSD完成了命令执行后,会将执行结果写入完成队列(Completion Queue,CQ)中,就像每次写个函数,接口都需要有返回值。CQ同样位于主机内存中,用来存储每个命令的执行结果和状态信息(如成功、失败或错误代码)。
  • 6. SSD生成中断,通知Host指令执行完成:
    SSD在将结果写入完成队列后,会向主机发出一个中断信号,通知主机该命令已经完成。这个中断可以通过硬件中断的形式触发,确保主机能够及时响应。
  • 7. Host收到通知,开始处理CQ,查看指令完成后返回的状态和数据:
    主机收到中断后,会处理完成队列中的条目,查看每个命令的执行结果。这包括检查状态码,确定操作是否成功,以及读取相关的数据或错误信息。
  • 8. Host写DoorBell,通知SSD执行结果已处理,然后释放CQ:
    主机处理完完成队列中的条目后,会再次通过写DoorBell寄存器通知SSD控制器,表示这些完成队列条目已经被处理,可以释放空间用于后续的命令结果。SSD控制器收到这个通知后,会更新队列的“尾指针”,确保下次新的结果可以正确写入。

总结:
整个流程展示了NVMe协议中主机和SSD之间的高效通信机制,充分利用了提交队列和完成队列的并行处理能力,实现了高速、低延迟的数据读写。每一步中,通过“DoorBell”寄存器和中断机制,确保了主机和SSD之间的快速、同步协调。这个过程让我想到了http协议的三次握手与四次挥手。

C:\Users\xiaoyuhao\Documents\WeChat Files\wxid_ecocdhno0e8r22\FileStorage\Temp\1723789715081.jpg

3.SSD基本工作原理

  操作系统对SSD发出请求,文件系统需要将这些请求转换成SSD能够识别的命令才能进行对应的操作,就像电源适配器一样。SSD的输入是命令(Command),输出是数据(Data)和命令状态(Command Status)。SSD前端(Front End)接收用户命令请求,经过内部计算和处理,输出用户所需要的数据或状态。

C:\Users\xiaoyuhao\Documents\WeChat Files\wxid_ecocdhno0e8r22\FileStorage\Temp\1723789753565.jpg

SSD系统调用

3.1SSD的读写

在写入时:

  (1) 主机发送写命令:主机(如电脑、服务器)通过接口(如NVMe、SATA等)向SSD发送写命令,并附带要写入的数据。这些命令通过存储协议(如NVMe协议)进行传输。
  (2)SSD接收命令并缓存数据:SSD接收到写命令后,首先会将数据暂时存储在其内部的RAM缓存中。这个缓存是高速度、低延迟的存储区域,可以极大地提高数据处理速度,避免频繁的闪存写入操作带来的延迟。(缓存系统一般都是用来提高读写速度的小容量、高速存储工具) 在某些情况下,数据也可能直接写入到SSD的SLC缓存区域,这种区域利用了SLC(Single-Level Cell)闪存的高写入速度特性来进一步加速写入。
  (3)FTL(闪存转换层)分配地址:FTL(Flash Translation Layer)是SSD固件中的一个关键部分。它负责将主机看到的逻辑地址(LBA,Logical Block Address)映射到实际的物理闪存地址。当数据存入RAM缓存后,FTL会为每个逻辑数据块分配一个具体的闪存物理地址。由于NAND闪存的特性,数据不能覆盖写入,所以FTL还要考虑磨损均衡(Wear Leveling)和垃圾回收(Garbage Collection)等任务,确保存储寿命和性能的优化。
  (4)数据积累与写入闪存:当缓存中的数据达到一定数量或触发某些条件(如缓存满或达到时间阈值)后,FTL会生成一个写请求,准备将数据写入实际的NAND闪存。这个写请求会被发送到SSD的后端控制器,后端控制器根据请求中的信息,将缓存中的数据写入到对应的NAND闪存块中。
  (5)NAND闪存写入:SSD的后端控制器按照FTL分配的物理地址,将数据从缓存写入到NAND闪存的对应页中。由于NAND闪存是以页为单位进行写入,以块为单位进行擦除的,因此这个写入过程可能涉及复杂的页、块管理操作。如果写入的页在一个新的闪存块中,写操作会比较直接。但如果需要在已经使用的块中写入新数据,可能会触发垃圾回收操作,移动和合并有效数据,腾出空间进行写入。
  (6)写入完成与确认:数据成功写入NAND闪存后,SSD会更新相应的映射表,并向主机发送写入完成的确认信息。之后,这些数据就会永久保存在闪存中,直到需要更新或删除为止。


 在读取时:host发来读取命令,SSD就需要根据逻辑地址映射出需要读取需要读取数据的物理地址,使后端从闪存将数据传输到缓存,前端再将这些数据返回给host

标签:闪存,主机,写入,day1,命令,20240814,SSD,数据
From: https://www.cnblogs.com/xyh0703/p/18362780

相关文章

  • day1打卡
    704:二分查找题目链接:https://leetcode.cn/problems/binary-search/这个还是比较简单的intsearch(vector&nums,inttarget){intlow=0;inthigh=nums.size()-1;intmid=(low+high)/2;while(nums[mid]!=target||low>=high){if(nums[mid]<target){......
  • 代码随想录Day16
    513.找树左下角的值给定一个二叉树的根节点root,请找出该二叉树的最底层最左边节点的值。假设二叉树中至少有一个节点。示例1:输入:root=[2,1,3]输出:1示例2:输入:[1,2,3,4,null,5,6,null,null,7]输出:7提示:二叉树的节点个数的范围是[1,104]-231<=......
  • 输出流FileOutputStream day16
    packagecom.shujia.day16.ketang;importjava.io.File;importjava.io.FileOutputStream;/*IO流:输入输出流按照流向划分:输入流:将外部存储数据-->java输出流:java-->外部存储工具中按照类型划分:字节流(万......
  • C语言学习笔记 Day13(复合类型/自定义类型)
    Day13 内容梳理:目录Chapter9 复合类型(自定义类型)9.1结构体(1)结构体变量定义、初始化(2)嵌套结构体(3)结构体赋值(4)结构体和指针(5)结构体做函数参数9.2共用体(联合体)9.3枚举9.4typedef关键字Chapter9 复合类型(自定义类型)9.1结构体有时需要将不同类型的数组......
  • 代码随想录Day15
    110.平衡二叉树(优先掌握递归)给定一个二叉树,判断它是否是平衡二叉树平衡二叉树是指该树所有节点的左右子树的深度相差不超过1。示例1:输入:root=[3,9,20,null,null,15,7]输出:true示例2:输入:root=[1,2,2,3,3,null,null,4,4]输出:false示例3:输入:root=[]输出:t......
  • 集合的工具类:Collections day15
    packagecom.shujia.day15;importjava.util.ArrayList;importjava.util.Collections;importjava.util.List;/*java提供了专门操作集合的工具类:Collections静态成员方法:publicstatic<T>voidsort(List<T>list)对List集合进行升序......
  • 异常以及处理方案 day15
    /*异常:java程序编译或者运行时遇到的错误java中的异常分为3种:Throwable:Error:错误Exception:编译时期异常RuntimeException(运行时期异常)举例,该例子仅上课使用,如现实生活遇到,概不负责。魏一民想要去大蜀山,......
  • DBeaver 24.1.4版本发布,原生支持GaussDB!
    【摘要】华为云GaussDB一直致力于完善生态体系的构建,为用户提供最佳的使用体验。DBeaver作为一款开源的数据库管理软件,因其广泛的数据库兼容、丰富的功能特性以及多操作系统支持,成为了众多数据库开发者的首选。可喜的是,刚刚发布的DBeaver24.1.4版本,原生支持了GaussDB数据库,这一......
  • HashMap和Hashtable的区别 day15
    /*Map:存储元素的特点是每一个元素是一个键值对{【name:"魏一民"】,【age:18】}Map集合的共同拥有的特点:1、Map集合中的元素,键是唯一的,不会在一个Map集合发现两个相同的键1001:魏一民1002:陈真1001:小虎2......
  • 代码随想录Day14
    226.翻转二叉树给你一棵二叉树的根节点root,翻转这棵二叉树,并返回其根节点。示例1:输入:root=[4,2,7,1,3,6,9]输出:[4,7,2,9,6,3,1]示例2:输入:root=[2,1,3]输出:[2,3,1]示例3:输入:root=[]输出:[]提示:树中节点数目范围在[0,100]内-100<=Node.val<=100......