找回密码
 注册
查看: 525|回复: 0

SSD的TRIM原理和实践

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2022-10-15 11:00:03 | 显示全部楼层 |阅读模式
一、原理
0 v! c! ?/ F  u9 o3 H$ n# `/ G0 J3 t' v2 r9 m9 k
TRIM指令是微软联合各大SSD厂商所开发的一项技术,属于ATA8-ACS规范的技术指令。) G4 e$ \3 k8 B6 P8 b$ M4 m

4 Q" o- k: }) x- vTRIM是告诉NAND闪存固态存储设备要擦除哪些数据的SATA接口指令。当相关页面的数据可以被覆盖时,操作系统会发给SSD一个TRIM指令。SSD控制器等到主机开始删除和再次写入操作的时候,执行安全擦除操作。因为在写入操作过程中不用花时间去擦除原本的数据,写入速度要快得多。
& R  I3 @) U+ @$ r
; b7 V, }4 E4 [% m0 Y! J* UTrim指令也叫disable delete notify(禁用删除通知),当我们在操作系统中删除一个文件时,系统并没有真正删掉这个文件的数据,它只是把这些数据占用的地址标记为‘空’,即可以覆盖使用。但这只是在文件系统层面的操作,硬盘本身并不知道那些地址的数据已经‘无效’,除非系统通知它要在这些地址写入新的数据。, u" X" U& K& ~  b
/ C4 c! Y2 Z% s  F
在HDD上本无任何问题,因为HDD允许覆盖写入,但到SSD上问题就来了,我们都已知道闪存不允许覆盖,只能先擦除再写入,要得到‘空闲’的闪存空间来进行写入,SSD就必须进行GC(垃圾回收)操作。在没有Trim的情况下,SSD无法事先知道那些被‘删除’的数据页已经是‘无效’的,必须到系统要求在相同的地方写入数据时才知道那些数据可以被擦除,这样就无法在最适当的时机做出最好的优化,既影响GC的效率(间接影响性能),又影响SSD的寿命。
% D( _& N2 f5 v& Y( ]8 k
6 m. |3 ~4 p+ C而当Windows识别到SSD并确认SSD支持Trim后,在删除数据时,会不向硬盘通知删除指令,只使用Volume Bitmap来记住这里的数据已经删除。Volume Bitmap只是一个磁盘快照,其建立速度比直接读写硬盘去标记删除区域要快得多。这一步就已经省下一大笔时间了。然后再是写入数据的时候,由于NAND闪存保存数据是纯粹的数字形式,因此可以直接根据Volume Bitmap的情况,向快照中已删除的区块写入新的数据,而不用花时间去擦除原本的数据。如果SSD组RAID0后,将失去Trim功能。
8 @* z) R9 l1 z* Q0 r
$ d% e/ Q  e3 a5 z( e+ ]
" G' \/ }8 w  f9 a9 F4 q0 L: H; o! X+ P& V1 u7 d$ f2 t/ n, D: B2 _
SSD Read 和 Write 都以 page 为单位,而清除数据(Erase) 是以 block 为单位的。不过 SSD 的 Write 只能写到空的 page 上,不能像传统机械磁盘那样直接覆盖,修改数据时,操作流程为 read-modify-write:读取原有 page 的内容,在 cache 中修改,写入新的空的 page 中,修改逻辑地址到新的 page ,原有 page 标记为 ‘stale’,并没有清零。
! g9 Y' R6 _- H$ _" {* E5 n7 ]# i& U2 q
Linux 文件系统对于删除操作,只标记为未使用,实际并没有清零,底层存储如 SSD 和传统机械磁盘并不知道哪些数据块可用,哪些数据块可以 Erase。所以对于非空的 page,SSD 在写入前必须先进行一次 Erase,则写入过程为 read-erase-modify-write: 将整个 block 的内容读取到 cache 中,整个 block 从 SSD 中 Erase, 要覆写的 page 写入到 cache 的 block 中,将 cache 中更新的 block 写入闪存介质,这个现象称之为写入放大( write amplification)。& K" q; A3 h6 S% j
' I4 X* d1 T  F* l0 d& T! I
为了解决这个问题,SSD 开始支持 TRIM,TRIM 功能使操作系统得以通知 SSD 哪些页不再包含有效的数据。TRIM 功能有助于延长 SSD 的长期性能和使用寿命。如果要启用 TRIM, 需要确认 SSD 、操作系统、文件系统都支持 TRIM。
- o  w$ x: {, g1 o
+ z8 q% y0 R: U& K根据 RedHat 的 SOLID-STATE DISK DEPLOYMENT GUIDELINES 介绍:随着所使用的 block 接近磁盘容量, SSD 的性能会开始降低,性能影响程度因供应商而异,但是所有设备都会遇到一些性能下降。为了解决性能退化问题,Linux 操作系统支持发送 discard 请求来通知存储器哪些 block 不再使用。# Q, D* y2 |9 u

) M4 D9 K$ x. y3 A& |: J# s! {TRIM 功能使操作系统得以通知 SSD 哪些页不再包含有效的数据。TRIM 功能有助于延长 SSD 的长期性能和使用寿命。如果要启用 TRIM, 需要确认 SSD 、操作系统、文件系统都支持 TRIM。$ d; l3 J: R3 `; v* ~3 t
固态硬盘(或固态硬盘),能够实现更快的读取和相比传统硬盘数据的写入速度。但是你可能不知道的是,随着时间的推移,当磁盘写满时,SSD可能会失去某些速度。如果出于速度考虑在服务器中运行SSD,请按照以下方法使用TRIM使SSD保持最佳状态。
) b+ i( ?) L( j  C5 I/ G0 s: ~! [. m+ B& m' K' C
为什么SSD会变慢?9 z  E# ^! I' g0 a6 t
首先让我们看看为什么会出现此问题。这与SSD的写入方式有关数据到存储。SSD将数据存储在固定大小的块(称为页面)中。然后将这些页面按称为块的较大组进行排列。尽管SSD可以单独读取和写入页面,但它们只能擦除数据块,而不能擦除单个页面。与可以覆盖数据块没有任何问题的硬盘驱动器不同,SSD需要先擦除块中的数据,然后才能将新数据写入内部页面。这在设计操作系统和文件系统时就成为问题,如果删除了文件,则将使用的文件块标记为可写入文件系统,但是这些块中的数据将保留到新数据为止。写在顶部。这是取消删除和文件恢复工具利用此原理从磁盘中恢复已删除文件的原理。
* R/ `3 u, B$ e; y0 s% [7 B9 x. G0 B. b* B( p: p1 G
二、检测ssd是否支持
' ]) l# d* X5 w) _: `
* f, p+ U) K9 j* r$ V一)、linux系统
$ W; k! ]) |' k; o; I7 {- U# q# Y+ I$ m* Y1 X! ?# e1 |% C
方法1:# V; \% ^0 T' d
可以通过 /sys/block 下的信息来判断 SSD 支持 TRIM, discard_granularity 非 0 表示支持。: q1 C8 D, I* i; H2 a

9 A8 f; h' Q  R% Q- ]# cat /sys/block/sdm/queue/discard_granularity
) X, U  b8 G' w( \) z5122 q: Y% ?/ Q! j+ ^) e7 `* X

2 T9 o1 m4 Y, {1 T+ V也可以直接使用 lsblk 来检测,DISC-GRAN (discard granularity) 和 DISC-MAX (discard max bytes) 列非 0 表示该 SSD 支持 TRIM 功能。
, Q* G. G6 O. S. V1 d! H( @% u/ L# T' f% b% S. g
# lsblk --discard. t# y3 G, L+ L7 S0 C
NAME                DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
& N6 M9 E" f: ^$ ]$ z0 S+ l# J2 N4 Hsda                        0        0B       0B         0- H+ [5 M: f/ M8 c" H
├─sda1                     0        0B       0B         0
) f) u) ?9 J6 r& k. n├─sda2                     0        0B       0B         0
) X* k6 o4 h- G2 Z├─sda3                     0        0B       0B         0# o8 ]4 D. n8 f( z* q' Z, I
└─sda4                     0        0B       0B         0$ A$ `2 ~1 i! m% [
sdb                        0      512B       600G         1; ]* }9 n) @3 _& D7 D( S
+ {0 g! A' d3 I7 E
; L$ T# B( J' H8 _* G# G
方法2:
% j8 L( h, l5 I/ o1 n# o7 R. ?) g0 ?. V  H) v! h
# yum install hdparm -y
: p* E6 c7 Y  z: y2 U0 F+ ^7 R% c# hdparm -I  /dev/sdb | grep -i trim* i; k  n5 N# B! R' x, x1 M
           *    Data Set Management TRIM supported (limit 8 blocks)6 Q" m; h/ J2 F1 Y8 ?+ Q
           *    Deterministic read ZEROs after TRIM
" e2 c8 ~- {9 b, Z& k" c% r- g2 _4 z% R$ g7 X
二)、windows系统
, l" ?& i. R$ q( ~0 `. a, y- u& A' _3 U" W) H, f3 b9 p8 Q
在CMD中查询7 X  e7 P4 M% J' c- |: G

# U0 f0 }6 g& P' \  e4 j/ n- y7 A. rfsutil behavior query disabledeletenotify
+ `6 M/ k9 n' a& @2 v15 j& C9 E; B! l! v# b$ K& ]
如果你的电脑 DisableDeleteNotify = 0,则说明你的电脑系统已开启TRIM功能,如果DisableDeleteNotify = 1,则说明没开启。
2 n0 Y/ q  t3 L! X5 _# S5 K# d' Y& W1 ]: i
二、启用 TRIM
2 U; j! Z4 z) I: N6 Q. T) \" c
, b+ _/ @! ]8 }# ZTRIM是内置于ATA命令中的SSD命令,它是磁盘与计算机交互方式的一部分。操作系统能够将TRIM命令发送到磁盘,以使其知道哪些块是已删除文件的一部分,并允许SSD在需要写入之前先擦除这些块。虽然操作系统能够在每次驱动器删除文件系统上的文件时向驱动器发送信号以擦除这些部分,但这也会影响性能并减慢运行速度。因此,建议按计划运行TRIM以间歇性地清除块。
6 I8 h2 Y% B0 L$ ?
! ^* [8 L; h% C) G& }一)、Linux系统4 k7 {7 B3 _: D( O7 j& e; H

  l( f4 X( U4 V* h3 T方法1:9 r0 D; g: I- c! M
修改/etc/fstab中的记录,加入discard选项。此方法弊端是降低磁盘的性能。
8 ^/ X# I1 P1 g( f, `3 U- P5 p
" D2 r9 y( y  [- c1 G5 x& P/ p5 w+ ~/dev/sdb1  /data       xfs   defaults,noatime,discard   0  0
: C0 ]1 [: Z5 d! d# y$ a1
7 R- s0 X0 [; ?: _, U6 d6 T方法2:% F  l& w5 G" J5 K3 Q

3 C- d; R7 d- E* W+ l- j2 }  r5 n手动执行! A/ f! o4 i) A& u
) S& M0 |6 v+ H# G5 ?; s
# fstrim -a -v) _$ M0 n( F- ?/ }; j% Y
14 a& y8 H# x7 M8 `! W1 `- `* V
-a标志告诉fstrim检查所有可用的有效分区,-v标志提供详细的输出,向您显示fstrim已完成的操作。您应该看到命令的输出,以查看运行情况,如果输出为正,则可以将命令添加到crontab条目中。
6 q! P8 {/ N/ l% A; }
; ]. f6 E% R, P4 Q  y9 ]: ^方法3:
, |, k  p" O4 I! _+ G3 E8 C$ q7 {! ~7 p5 P
在 CentOS 7 中,已经自带了 /usr/lib/systemd/system/fstrim.timer 和 /usr/lib/systemd/system/fstrim.service5 C: I: x2 s3 d. U) h
5 x, h* N$ {' F+ N6 t& j0 q
/usr/lib/systemd/system/fstrim.timer:
0 c( D8 j+ }! `% c0 O  n[Unit]; k9 N: a# t' x! V: f% Z6 K( d( e
Description=Discard unused blocks once a week# y% u3 }- n/ U: R, Y! D  M6 J: w
Documentation=man:fstrim* D2 z2 a! w- w" Z8 p
5 g$ s% B* }( o! l! l  C
[Timer]9 {8 v1 p& C0 D9 u! w
OnCalendar=weekly
5 E' \/ h6 Y+ m& F* k. C1 GAccuracySec=1h
: ]2 a& ~4 r! x+ Y- X8 H. ]/ jPersistent=true
& F0 P) Y1 Q6 q0 |6 a" P9 o& Q3 _
[Install]' R3 w. W) J: i8 n
WantedBy=multi-user.target
% w; W/ p4 f2 \/ A- V/usr/lib/systemd/system/fstrim.service:
2 \% J: w/ G' S3 `; L8 ~7 Y[Unit]5 p( r  j- h- L, R. W0 N  }
Description=Discard unused blocks
+ W, C+ `1 C3 k" [  m. t% l2 ^; O/ \
[Service]. o4 O) r. E- z7 {$ G! `6 g" d
Type=oneshot
, A  N# k" R0 i8 E; SExecStart=/usr/sbin/fstrim -a: ^. e) A' N9 ^1 ^2 w: U. H
& d/ K* v; b5 f9 m/ c9 k+ S. l- v
只需开启即可:& N; ?, ]4 ~' v' v( h4 T
, f% N7 P; D5 R8 w9 }
# systemctl enable fstrim.timer
4 w% p9 U; q+ q/ a' B# t0 H, ~2 y! W& L# systemctl start fstrim.timer9 ^0 l) u' ?7 W8 o
# systemctl status fstrim.timer
! N1 b. ]7 T* `: R9 d: |8 u5 p# r" L- ~6 u# }) ~) l& o
二)、windows系统, P: \/ k9 F* |2 I

# {+ N/ }5 v2 v/ D开启:
; ?) b( b' o. |: X8 i9 T7 a- c8 ]$ Y+ Y* I3 D/ g
fsutil behavior set disabledeletenotify 0/ l, B7 p" V2 n4 U: f7 l( `8 z
; e; L) `" \4 [' B. h1 |
4 g# }# u, V, \4 r! e" ]5 l7 m
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-11 23:50 , Processed in 0.018905 second(s), 22 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表