闪存存储器主要分为NAND和XOR两种类型,其中NAND型是专为数据存储设计。本文的闪存映射方法主要是针对NAND类型的闪存芯片。一个NAND类型的闪存芯片的存储空间是由块(Block)构成,每个块又划分为固定大小的页,块是擦写操作的最小单元,页是读写操作的最小单元。由于闪存存储器的硬件特性,闪存的更新操作有自己的特点,在对数据进行更新前需要先进行擦写操作,然后才能将新数据写入,并且擦写操作是以块为单位,读写操作是以页为单位。由于擦写操作涉及的最小单元远大于读写操作的最小单元,需要对一个擦写块内不需要更新的数据提供有效的保护。在闪存存储管理中普遍采用的数据更新方法是非本地更新的方法(Out-place Update),通过构建闪存映射层,在进行更新操作时,将更新的数据写到其他空闲的存储位置,利用内存中的地址映射表记录数据存储位置的变化。非本地更新的方法避免了更新时整块数据的读出写入,从而减少数据复制次数和块擦写次数,提高系统的整体性能。闪存映射层是闪存进行非本地更新存储管理的关键,主要由地址映射和垃圾回收机制两部分构成。
根据地址映射粒度的不同,可以将地址映射方法分为三种:页映射(Page Mapping)、块映射(BlockingMapping)和混合映射(Hybrid Mapping)。页映射是以页为单位进行地址映射,在内存中保存基手页的映射表,每一逻辑页都有一项与之对应的物理页,页映射方法具有灵活性高的优点,但由于需要为每个逻辑页面建立地址映射表项,需要占用大量内存空间。块映射算法是以块为单位进行地址映射,逻辑块内地址偏移与物理块内偏移保持一致。该方法仅需要在内存中保留块映射表,建立从逻辑块到物理块的映射关系,块映射算法优点是内存占用量少,不受闪存容量增大的影响,缺点是在处理小数据更新上性能较差,一小块数据的更新会引起对整个块内容的复制。混合映射方法结合了块映射和页映射的优点,首先以块映射方法建立逻辑块和物理块的映射关系,同时对块内数据采用页映射方法组织。混合映射算法内存空间占用量少,同时对小数据更新比块映射算法更加灵活、代价少。
垃圾回收是闪存存储系统特有的空间管理机制。在闪存存储管理中,由于采用非本地更新的方法,当闪存的存储空间消耗完时,就需要回收无效数据占用的空间。为了回收无效数据占用的空间,必须先将擦写单位内的有效数据转移到其他空闲区域,然后擦写整个单元,回收过程主要涉及有效数据复制和块擦写两个耗时耗能的操作。垃圾回收工作需要从闪存中选择回收对象,转移有效数据,最后完成对象擦除。进行垃圾回收时选择不同的区域进行擦除,代价是不同的,垃圾回收器设计的目就是要减少有效数据复制和块擦写次数,以提高系统性能。不同粒度的地址映射方法在不同写模式下,垃圾回收的性能有较大差异。在此给出了一种能够根据写模式进行自适应判断的闪存映射方法。通过对顺序写和随机写进行判断,将顺序写从随机写中分离,对顺序写采用块映射组织日记块数据,对随机写采用混合映射方法,并为热数据分配多个日记块,延迟对热数据的垃圾回收,以提高垃圾回收的性能。通过实验表明这里构建的闪存映射方法能够在不需要占用大量的内存空间前提下,减少垃圾回收过程的有效数据复制和块擦写,从而优化闪存系统的性能。
1 闪存存储系统的体系结构
本文构建的闪存存储管理的体系结构见图1,将系统分为文件系统层、闪存管理层和闪存驱动层。闪存映射层负责对闪存设备进行存储管理,通过地址映射和垃圾回收技术将闪存转换为块设备。地址映射主要完成闪存块的分配和地址映射信息管理,负责处理文件系统层的读写请求,将文件系统提供的逻辑地址转换为闪存的物理地址;垃圾回收则负责回收无效数据占用的空间,主要涉及有效数据复制和块擦写两个耗时耗能的过程。
1.1 地址映射结构
闪存映射层的作用是将文件系统的逻辑地址转换为闪存的物理地址,因此需要在内存建立逻辑地址和物理地址的映射关系,同时管理物理地址的状态变换。本文通过图2所示的地址映射结构进行地址映射管理,将文件系统提供的逻辑地址分为四部分:逻辑组号、组内块号、块内页号和页内偏移地址。其中逻辑页和逻辑块大小分别与闪存存储器的读写页和擦写块大小相同。每个逻辑组是由N个连续的逻辑块构成,N可以根据应用类型进行设置,在图2中N的数目为2。将闪存存储器中的物理块分为数据块和日记块,数据块用于存放原数据,日记块用于存放更新数据,同时又将日记块划分为顺序日记块和随机日记块。数据块和顺序日记块内的内容是以块映射方法组织,而随机日记块采用混合映射粒度组织数据。逻辑块和数据块通过内存中的块映射表建立对应关系,每一个逻辑块都有惟一的数据块与之对应。与逻辑组对应的N个数据块构成一个数据组。每个顺序日记块对应惟一的数据块,在对数据块进行顺序更新操作时,为其分配顺序日记块存储更新数据。每个数据组可以根据需求动态分配多个随机日记块,日记块的数目是由该组数据访问的冷热属性来决定的,对于有频繁更新数据的组会动态分配较多的日记块。随机日记块是组内共享的,对组内任一数据块的随机更新数据都可以存储到随机日记块中,从而提高空间利用率。为了提高查找效率,对有随机日记块的数据组,在内存中构建组内页映射表,记录逻辑地址对应的更新数据在随机日记块内的存储位置,通过组内页映射表,在进行读取时不需要遍历日记块来获取数据的存储位置,从而提高系统性能。
1.2 写请求处理过程
地址映射的主要作用是通过在内存中构建地址映射表,将文件系统的逻辑地址转换为物理地址,在系统进行读请求时,利用地址映射表查找到存储在闪存设备中的数据,在系统进行写请求时在闪存设备上查找空闲位置存储数据,更新地址映射表,记录数据的新存储位置,同时将旧数据标记为无效。
在本文中为每个数据块设定状态位来标记该块当前的访问模式,将每个数据块访问模式分为顺序写和随机写。在进行写请求时,首先计算出数据所属的逻辑块和块内偏移地址,判断数据所在块的访问模式,如果所在块是顺序写,利用块映射表,将数据写到顺序日记块中。如果所在块为随机写,将更新数据写到数据组的随机日记块中。访问模式主要是根据过去的数据存储访问行为进行判断的,如果对某一逻辑地址在短时间内进行了多次更新,认为系统对该地址进行的是随机写,对其所属块将采用混合映射方法进行存储管理,以优化小数据频繁更新导致的性能问题。访问模式的判断是通过内存中的双链表来实现的,如图3所示。在内存中构建两定长的地址链表,一个链表为顺序链表,另一个链表为随机链表。顺序链表中保存最近进行顺序写的数据块,而随机链表中保留最近进行随机写的数据组。两链表都根据最后一次访问时间进行排序,将链表分为最近最少访问端(LRU)和最近最多访问端(MRU),在每次进行更新操作时,将更新数据所在的块或组提升到链表的最近最多访问端。当对数据块首次进行更新操作时,判断该数据块进行的是顺序写,标记该块的访问状态为顺序写,并将该数据块添加到顺序链表中。如果数据块内已更新过的数据在短时间内再一次被更新,即顺序日记块内对应的存储空间已填充数据,判断该数据块的访问模式为随机写,将其从顺序链表中删除,标记该块的访问状态为随机写,同时添加该块所在的数据组到随机链表中,以后对该块的更新数据将存储到随机日记块中,直到该数据组从随机链表中删除。