Ein weiterer Blick auf die Frage "Brauche ich eine Defragmentierung für SSD?"

Zweifellos ist die im Titel des Artikels gestellte Frage nicht neu, sie wurde mehr als einmal aufgeworfen und es wurde ein Konsens darüber erzielt, „nicht wirklich benötigt und kann sogar schädlich sein“.
Die jüngste Diskussion in den Kommentaren hat mich jedoch zum Nachdenken gebracht.


Im Laufe der Zeit wird jede SSD immer noch stark fragmentiert (intern in FTL) ... Eine frisch aufgenommene SSD mit linearem Messwert liefert eine hohe Geschwindigkeit, aber wenn sie bereits funktioniert hat, ist sie viel niedriger, da sie nur für Sie linear ist.

Ja, normalerweise sollte dies nicht passieren: Entweder schreiben wir "Stück für Stück" in kleine Dateien / kleine Blöcke von Metainformationen des FS (deren lineare Lesegeschwindigkeit uns nicht wirklich wichtig ist), oder wir schreiben "viel" in große Dateien, und alles wird gut. Es kommt auch vor, dass Sie großen Dateien kleine Blöcke hinzufügen, z. B. Protokolle. Diese sind jedoch relativ kurzlebig und ich sehe hier keine besonderen Probleme.
Man konnte sich jedoch leicht ein sehr reales Szenario vorstellen, in dem dieselbe interne Fragmentierung der SSD auftreten kann: eine Datenbankdatei, in der eine ziemlich aktive Zufallsaufzeichnung vorliegt. Im Laufe der Zeit wird es (auf Betriebssystemebene unfragmentiert) physisch sehr fragmentiert sein, was die Geschwindigkeit von Seq-Scan, Backup usw. erheblich verringern kann.


Zur Überprüfung habe ich ein Skript geschrieben und Tests durchgeführt.


Spoiler: Das Problem ist nur bei einem der Modelle vorhanden (beeinträchtigt die Leistung erheblich) (und es wird vom Hersteller nicht als Rechenzentrum, sondern als Desktop / Laptop positioniert).


Worum geht es? Welche weitere Fragmentierung innerhalb der SSD?

, SSD . NAND flash ( ) . SSD 512- ( 4096-) , .
- , , FTL (flash translation layer): flash- , ( ) , , - log- .
, , , , — .


, FTL, , , , . , .
.


Die Idee des Skripts: Wir erstellen eine Datei mit mehreren Gigabyte, die mit zufälligen Daten gefüllt ist, und messen die Geschwindigkeit sequentieller Lesevorgänge.
Schreiben Sie anschließend mit wahlfreiem Zugriff einen Teil der Testdatei neu und messen Sie erneut die Geschwindigkeit des linearen Lesens. Wenn unser Verdacht wahr ist, wird das Lesen aus der Datei jetzt langsamer.
Nach jedem Schreibvorgang führen wir drei Lesevorgänge mit einer Verzögerung zwischen ihnen aus, falls ein Laufwerk im Hintergrund eine Defragmentierung durchführt und sich dann die Lesegeschwindigkeit verbessert.


, SSD

, , - , , . - , , , , , .
TRIM: SSD «», , FTL. NAND flash, . , , . SSD , .


, , , .


, SSD ( linux /dev/urandom).


.


linux c dash, coreutils fio debian buster, , freebsd «».


echo preparing...
dd if=/dev/urandom of=testfile bs=1M count=4096 status=none
sync
for A in 1 2 3; do
    sleep 10
    dd if=testfile of=/dev/null bs=1M iflag=direct
done

for A in 50 200 800 4000; do
    echo fio: write ${A}M...
    fio --name=test1 --filename=testfile --bs=4k --iodepth=1 --numjobs=1  --rw=randwrite  --io_size=${A}M --randrepeat=0 --direct=1 --size=4096M > /dev/null
    sync

    for B in 1 2 3; do
        echo sleep ${B}0
        sleep ${B}0
        dd if=testfile of=/dev/null bs=1M iflag=direct
    done
done

echo sleep 3600
sleep 3600
dd if=testfile of=/dev/null bs=1M iflag=direct

, NVMe- intel windows; , stackexchange -


ps

fio; exe- .


$testfile = "c:\temp\testfile"
$fio = "c:\temp\fio-3.18-x64\fio"

echo "preparing..."

$filestream = New-Object System.IO.FileStream($testfile, "Create")
$binarywriter = New-Object System.IO.BinaryWriter($filestream)
$out = new-object byte[] 1048576

For ($i=1; $i -le 4096; $i++) {
    (new-object Random).NextBytes($out);
    $binarywriter.write($out)
}
$binarywriter.Close()

For ($i=1; $i -le 3; $i++) {
    sleep 10
    $time = Measure-Command {
        Invoke-Expression "$fio --name=test1 --filename=$testfile --bs=1M --iodepth=1 --numjobs=1  --rw=read --direct=1 --size=4096M" *>$null
    }

    $seconds = $time.Minutes*60+$time.Seconds+$time.Milliseconds/1000
    echo "read in $seconds"
}

foreach ($A in 50,200,800,4000) {
    echo "fio: write ${A}M..."
    Invoke-Expression "$fio --name=test1 --filename=$testfile --bs=4k --iodepth=1 --numjobs=1  --rw=randwrite  --io_size=${A}M --randrepeat=0 --direct=1 --size=4096M" *>$null
    For ($i=10; $i -le 30; $i+=10) {
        echo "sleep $i"
        sleep $i
        $time = Measure-Command {
            Invoke-Expression "$fio --name=test1 --filename=$testfile --bs=1M --iodepth=1 --numjobs=1  --rw=read --direct=1 --size=4096M" *>$null
        }

        $seconds = $time.Minutes*60+$time.Seconds+$time.Milliseconds/1000
        echo "read in $seconds"
    }
}

rm $testfile

:


  • : , «» ( ) , ;
  • windows - (, , , );
  • ( ) .

( ) 4 :


50+200+800+4000
intel S3510 SSDSC2BB480G610.710.710.810.810.8
toshiba XG5 KXG50ZNV512G1.92.93.74.86.8
samsung PM963 MZQLW960HMJP2.83.23.53.74.2
samsung PM983 MZQLB960HAJR3.33.63.43.43.4
samsung PM981 MZVLB1T0HALR1.81.82.12.53.5
samsung PM1725b MZPLL1T6HAJQ1.81.92.02.32.9
micron 5200 eco9.39.810.412.210.7
samsung PM883 MZ7LH1T9HMLT7.97.98.18.18.0
intel P3520 (win)5.85.96.06.15.8
intel P4500 (win)4.24.24.34.44.3

DC ( — /); SATA, NVMe, , .


, PM981 ( , , ), — 3.5 , SATA .
, , .


: SSD , , , ( intel, , ; samsung , ).


(, - NAND flash).
XG5: , SMART >>150, ­— 300-400 , flash , SSD.


: mysql 100. , , «» mysql ( 600/), (>2/).


SSD

, : , , . , downtime ( - ). , , .
( ) SSD:


sync
fsfreeze -f /mountpoint
dd  if=/dev/nvme0n1p2 of=/dev/nvme0n1p2 bs=512M iflag=direct oflag=direct status=progress
fsfreeze -u /mountpoint

«» . - , , , -. «»: 100%, SSD « , TRIM» ( , TRIM, , ).
, « » .


Zusammenfassung: Die Defragmentierung kann für einige SSDs nützlich sein , ist jedoch nicht ganz dasselbe (überhaupt nicht?) Wie für die Festplatte. Für uns ist es nicht nur wichtig, dass sich die Datei in einer fortlaufenden Kette von Sektoren befindet, sondern auch, dass die Aufzeichnung in diesen Sektoren sequentiell war.


PS Ich wäre dankbar, wenn die Leser das Skript an ihrer Stelle ausführen und Nummern für ihre SSDs angeben würden, da meine Auswahl an Laufwerken eher einseitig ist.


All Articles