Linux 环境 SSD(固态硬盘)使用指南

原文链接:http://www.jinbuguo.com/storage/ssd_usage.html

前言

因为SSD有着诸多与传统机械式硬盘不同的特点,而且这些特点导致了SSD在实际使用中的性能和寿命与其使用方法紧密相关。所以并不是说买来一块非
常牛X的SSD就万事大吉了。另一方面,SSD的性能并不像机械式硬盘那样比较稳定(浮动范围小),而是呈现出一种离散的特点(浮动范围大),最佳状态与
最差状态相差甚远(上百倍),所以如何避免最差状态比如何发挥最佳状态更重要。

分区对齐

如果要对一块SSD进行分区,然后再使用,就会遇到这个问题。当然,也可以不对它进行分区以避免这个问题。对于Linux来说,不分区直接使用就是
直接格式化 /dev/sdx 设备(比如:mkfs.xfs /dev/sdx),然后再 mount /dev/sdx /mnt/point

考虑到使用习惯、预留空间(见下文)的问题,以及安装引导程序(如:grub)的要求,不做分区直接使用并不是个好主意。幸运的是,分区对齐问题是可以得到完美解决的。

害处

如果SSD上的分区分割点处于未对齐SSD block
size倍数的状态,SSD效能就不能完全发挥,系统可能会有卡顿的感觉,另外,未对齐的分割点还会造成SSD在连续写入小文件时,增加无谓的SSD额外
写入/擦除动作从而大幅影响SSD的寿命,而这偏偏是SSD使用中最该避免的。

分区不对齐,对4KB随机写入的影响最大,实际测试表明,在其他因素相同的情况下,分区不对其导致的性能差距最大可达10倍

CHS、LBA、block(块)

在了解事情的来龙去脉之前,先得把传统硬盘的几个概念拿出来复习一下。

CHS(Cylinder-head-sector)是最早用于访问硬盘的寻址方式。虽然CHS的值现在早已不再与实际的物理值相对应(只是个逻辑值),但是依然有许多磁盘管理程序(比如fdisk/cfdisk)使用CHS的方式来理解硬盘。

side/head

硬盘一般是由一片或几片圆形薄膜叠加而成。每个圆形薄膜都有两个"面"(Side),这两个面都是用来存储数据的。盘面由上而下从"0"开始编号,
依次称为0面、1面、2面……由于每个面都专有一个读写磁头,也常用0头(head)、1头……称之。硬盘面数(或头数),少的只有2面,多的可达数十
面。

按照CHS规范,head使用8bit编址,因此最多可以有256个磁头(0-255)。但是由于某些古董程序只能最大支持到255个磁头,出于兼容性考虑,绝大多数场合的默认值依然是255个磁头。

track

读写硬盘时,磁头不动,磁盘是旋转的,则连续写入的数据是排列在一个圆周上的。我们称这样的圆周为一个磁道(Track)。

磁头不动,就是在一个磁道上读写;磁头移动,就会在不同磁道上读写。

按照CHS寻址规范,由外向内从"0"开始顺序编号。不过其编址时使用的位宽并不是一个定值(取决于不同的规范),我们姑且可以认为其足够大。

cylinder

各面上磁道号相同的磁道合起来,称为一个柱面(cylinder)。也就是距轴的距离相同的一组track所形成的圆筒。

按照CHS寻址规范,cylinder和track一样,也由外向内从"0"开始顺序编号。并且其编址位宽足够大。

cylinder也是磁盘分区时的最小单位,分区是按磁道和柱面连续分布的(即每个分区,都是粗细连续的一组筒子)。

下面是一个fdisk的输出,主意最后一行:

Sector

一个track上可以容纳"较多"的数据,而主机读写时往往并不需要一次读写那么多,于是,磁道又被按512或4096字节划分成若干段,每段称为一个扇区(Sector)。一个扇区的大小是固定的512或4096字节。

计算机对硬盘的读写,是以扇区为最小单位。即使只读某一个字节,也必须一次把这个字节所在的扇区中的512或4096字节全部读入内存。

按照CHS寻址规范,Sector的编号始终是从"1"开始的(不是"0")。由于使用6bit编址,所以其最大值是63,也就是说既不存在 sector 0 也不存在 sector 64 。目前所有机械式硬盘在逻辑CHS模式中都使用63这个最大值。

block

Block是文件系统的最小存取空间。一个 Block
最多仅能容纳一个文件(即不存在多个文件同一个block的情况)。如果一个文件比block小,他也会占用一个block,因而block中空余的空间
会浪费掉。而一个大文件,可以占多个甚至数十个成百上千万的block。

sector 和block的差别

  1. sector 是硬盘存取的最小单位,是512B或4096B

  2. block 是文件系统的最小存取单位,可以随意设定,但必须是sector的整数倍。如ext2 fs的block缺省是4k

应该根据自己系统应用的特点,合理规划block size:若block太大,则存取小文件时,有空间浪费的问题;若block太小,则硬盘的
Block 数目会大增,而造成 inode 在指向 block 时候的一些搜寻时间的增加,又会造成大文件读写方面的效率较差。

磁盘容量

先看一个500G的硬盘在 fdisk -l 时显示的信息:

可以看出,磁盘总容量=磁头数*每磁道扇区数*柱面数*扇区大小。当然,这里的磁头数、扇区数、柱面数并不是物理真实值,而是逻辑值。甚至对于4KB扇区的硬盘,扇区大小也可能是逻辑值。

LBA寻址机制

上面说的CHS寻址方式其实在实践中早就被丢进垃圾箱了。目前在实践中真正使用的是48位LBA(Logical Block
Address)寻址方式。LBA是非常单纯的一种寻址模式:从0开始编号来定位区块(扇区),第一区块LBA=0,第二区块LBA=1,依此类推。以每
扇区512字节计算,容量上限可达128PB。LBA寻址模式完全屏蔽了硬盘的物理结构,而将其简单的抽象成一维条带,非常便于操作系统的理解。

原因分析

了解了上面的知识之后,现在知道了机械硬盘从很早前开始,扇区大小就被定义为512字节,而最新的"先进格式"机械盘终于把物理扇区提高到
4KB(4096字节)。机械式硬盘的最小操作单位是扇区,也就是说,无论读取还是写入1个字节、10个字节、500字节,实际的操作都是512字节。当
然,对于4KB扇区的机械式硬盘来说,所有读写操作都会被向上取整到4KB的整数倍。

但SSD的操作方式与此不同。SSD不像HDD那样只有读/写两种操作而且还是统一的,SSD有三种操作:读/写/擦除。闪存的读写单位是4KB或8KB大小的,而且闪存的擦除(又叫编程)操作是按照128或256页大小的来操作的。

传统上,LBA模式的HDD第一个分区的起始点从63逻辑扇区(63x512B=31.5KB)开始,对于扇区大小为512B的HDD来说,这当然
没什么问题。但对于SSD和新式HDD来说,就会造成用户的第一个数据的前4KB会存放在系统"逻辑扇区"的31.5KB~35.5KB间,这样持续下去
会造成后面所有的数据都会卡在2个物理扇区(页)容量之间,我们知道扇区(页)为磁盘写入的最小单位,如果卡在2个扇区(页)之间,写入的时候就需要进行
读-改写操作(对SSD来说读-擦-写),造成性能的下降。

分割点应该放在哪里呢?

简单的说,应该放在SSD最大操作单位"块",也就是block size整数倍的位置。

对于单通道的闪存设备,这很简单,也很好理解。但事实上,几乎所有的SSD都不是单通道的,这时候应该空出多少呢?

多通道的闪存设备也是把数据拆成一个一个的块,然后分别对每个通道进行读写操作,这个块的大小和所使用的闪存芯片的块的大小是一样的。如果多通道
SSD会把数据再进一步拆分然后才写到各个通道的话,情况就会变得复杂了。不过目前的SSD主控似乎还没有这么聪明,目前多通道写入时最小的数据单位依然
是闪存块的大小。因此,在目前的情况下,我们完全可以不考虑设备是几通道的,直接把分区分割点设在block
size整数倍的位置即可。也许未来需要把分割点设置在"通道数*block-size"整数倍的位置?

FDISK

在给出最终解决方案之前,先来了解一下fdisk工具:

我们通常并不使用任何选项,但是为了强制分割点的位置对齐,就必须强制指定如下三个参数:

  1. -b

  2. 指定扇区的大小,只能取 512/1024/2048/4096 之一。
    注意,经过本人实测,使用大于512的其他值(假定是N),会导致fdisk只能使用到真实容量的512/N。所以最好不要使用该选项。

  3. -H

  4. 指定磁头数,只能取 1-256 之间的整数。

  5. -S

  6. 指定每磁道扇区数,只能取 1-63 之间的整数。

这三个参数值的乘积就是一个逻辑柱面的总大小,也就是最小分割单位了。

解决方案

经过前面的讲解,现在知道,只要把"块"作为SSD的最小单位来划分磁盘就能完美解决分区对齐的问题。

现在假定我们拿到一块SSD的参数是这样的:每个页的大小是8KB、每256个页组成一个块,那么也就是说我们必须以
256*8KB=2097152B=2048KB=2MB为最小单位对其进行分区。也就是说,我们可以通过强制指定fdisk的命令行参数,使每个柱面
(cylinder)的大小为2MB即可达到目的(假定每扇区512字节):

如果觉得每个柱面(cylinder)的大小为2MB还是不够大,那么可以加大到4MB(假定每扇区512字节):

此外,还需要注意一个细节,那就是第一个分区的起点不能从默认的第一个柱面开始,而是要从第2个柱面开始,否则第一个分区有可能依然不会对齐。如下图所示:

注意 First cylinder 那一行,那里的默认值是1,但是不能用它,要手动修改为2。

导致这个问题的原因,据Google说是fdisk会对从 cylinder 1 开始的扇区特殊对待,自作主张的向前平移分区起点。不过,既然新版本的fdisk已经修正了这个bug,我们就不必再去考古了。

对齐检查

如何检查分区是否确实已经对齐呢?方法是使用"fdisk -u=sectors -l /dev/sdx"查看。例如:

首先看 Sector size 的大小,有logical/physical两个值,都是512字节。

sda1分区的Start=63,那么就表示sda1分区的起始扇区头距离LBA0的距离是63*512B=31.5KB,显然是未对齐的。

sda2分区的Start=40960,表示sda2分区的起始扇区头距离LBA0的距离是40960*512B=20MB=5*2*2MB,显然
既在2MB大小的块边缘对齐,也在4MB大小的块边缘对齐;再看sda2分区的End=79871,表示sda2分区的终止扇区尾距离LBA0的距离是
(79871+1)*512B=39MB,显然只能在1MB大小的块边缘对齐,但是不能在2MB/4MB块的边缘对齐。

sda3分区的Start=81920,表示sda3分区的起始扇区头距离LBA0的距离是81920*512B=40MB=5*4*2MB,显然
既在2MB大小的块边缘对齐,也在4MB大小的块边缘对齐,甚至对于8MB大小的块也是对齐的;再看sda3分区的End=163839,表示sda3分
区的终止扇区尾距离LBA0的距离是(163839+1)*512B=80MB=5*2*2*2*2MB,显然可以在2MB/4MB/8MB/16MB块
的边缘对齐。

可见sda3是对齐最完美的分区,而sda1则是最糟糕的。

文件系统

现在SSD已经被完美的分区了,接下来就是创建文件系统了,那么哪个文件系统才是最适合SSD的呢?因为Linux系统有如此多的文件系
统:etx2/ext3/ext4/reiser3/reiser4/JFS/XFS/Btrfs/NILFS2……在HDD的时代,选择合适的文件系统
就一直是个令人头痛的问题。直到目前为止,不得不说,没有任何一个文件系统和SSD是绝配。

未完待续。。。

原创文章,作者:追马,如若转载,请注明出处:/2886

联系我们

400-080-6560

在线咨询:点击这里给我发消息

邮件:1823388528@qq.com

工作时间:周一至周五,9:30-18:30,节假日同时也值班

友情链接:guoqibee.com  guoqibee.com  万达开户  万达娱乐注册  万达主管QQ  万达娱乐注册  万达开户  万达娱乐招商QQ  万达娱乐登录  万达注册