Lihat lagi pertanyaan "Apakah saya perlu defragmentasi untuk SSD"

Tidak diragukan lagi, pertanyaan yang diajukan dalam judul artikel itu bukanlah hal baru, telah diajukan lebih dari satu kali dan sebuah konsensus telah dicapai mengenai hal itu “tidak benar-benar dibutuhkan, dan bahkan dapat berbahaya”.
Namun, diskusi baru - baru ini di komentar membuat saya berpikir lagi.


Seiring waktu, setiap SSD akan tetap terpecah-pecah (secara internal, dalam FTL) ... SSD yang baru direkam dengan pembacaan linear akan memberikan kecepatan tinggi, tetapi jika sudah bekerja, itu akan jauh lebih rendah, karena itu akan linier hanya untuk Anda.

Ya, biasanya ini tidak boleh terjadi: kita menulis "sedikit demi sedikit" dalam file kecil / blok kecil meta-informasi FS (kecepatan membaca linier yang tidak kita pedulikan), atau kita menulis "banyak" dalam file besar dan semuanya akan baik-baik saja. Itu juga terjadi bahwa Anda menambahkan blok kecil ke file besar - log, misalnya, tetapi mereka relatif singkat dan saya tidak melihat masalah tertentu di sini.
Tapi mudah untuk membayangkan skenario yang sangat nyata, di mana semua fragmentasi internal yang sama dari SSD dapat terjadi: file database di mana ada rekaman acak yang cukup aktif. Seiring waktu, itu (tetap tidak terfragmentasi pada tingkat sistem operasi) akan secara fisik sangat terfragmentasi, yang secara signifikan dapat mengurangi kecepatan pemindaian seq, cadangan, dll.


Untuk verifikasi, saya menulis skrip dan menjalankan tes.


Spoiler: masalahnya ada (secara signifikan mempengaruhi kinerja) hanya pada salah satu model yang hadir (dan diposisikan oleh pabrikan bukan sebagai pusat data, tetapi sebagai desktop / laptop).


Tentang apa semua ini? Apa lagi fragmentasi di dalam SSD?

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


, FTL, , , , . , .
.


Gagasan skrip: kita membuat file beberapa gigabyte, diisi dengan data acak, mengukur kecepatan membaca berurutan.
Selanjutnya, menggunakan akses acak, kami menulis ulang bagian dari file tes dan mengukur kecepatan membaca linear. Jika kecurigaan kami benar, maka sekarang membaca dari file akan menjadi lebih lambat.
Setelah masing-masing menulis, kami melakukan tiga operasi baca dengan penundaan di antara mereka dalam kasus beberapa drive di latar belakang melakukan defragmentasi dan kemudian kecepatan baca meningkat.


, 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, , ).
, « » .


Ringkasan: Defragmentasi mungkin berguna untuk beberapa SSD, tetapi tidak persis sama (tidak sama sekali?) Seperti untuk HDD. Penting bagi kita tidak hanya bahwa file tersebut berada dalam rantai sektor yang berkesinambungan, tetapi juga bahwa rekaman di sektor-sektor ini berurutan.


PS Saya akan berterima kasih jika pembaca menjalankan script di tempat mereka dan memberikan angka untuk SSD mereka, karena pilihan drive saya agak sepihak.


All Articles