نظرة أخرى على السؤال "هل أحتاج إلى إلغاء تجزئة SSD"

مما لا شك فيه أن السؤال المطروح في عنوان المقال ليس جديداً ، فقد أثيرت أكثر من مرة وتم التوصل إلى إجماع عليه "لا حاجة إليه حقاً ، ويمكن أن يكون ضاراً".
ومع ذلك ، فإن المناقشة الأخيرة في التعليقات جعلتني أفكر مرة أخرى.


بمرور الوقت ، ستظل أي SSD مجزأة بقوة (داخليًا في FTL) ... سيعطي SSD المسجل حديثًا مع القراءة الخطية سرعة عالية ، ولكن إذا نجح بالفعل ، فسيكون أقل بكثير ، لأنه سيكون خطيًا لك فقط.

نعم ، عادةً لا يجب أن يحدث هذا: إما أن نكتب "شيئًا فشيئًا" إلى الملفات الصغيرة / مجموعات صغيرة من المعلومات الوصفية FS (سرعة القراءة الخطية التي لا نهتم بها حقًا) ، أو نكتب "الكثير" إلى الملفات الكبيرة وكل شيء سيكون على ما يرام. يحدث أيضًا أن تضيف كتلًا صغيرة إلى الملفات الكبيرة - السجلات ، على سبيل المثال ، لكنها قصيرة العمر نسبيًا ولا أرى أي مشاكل معينة هنا.
ولكن كان من السهل تخيل سيناريو حقيقي للغاية ، والذي قد يحدث فيه كل التجزئة الداخلية لمحرك SSD: ملف قاعدة بيانات يوجد فيه تسجيل عشوائي نشط إلى حد ما. بمرور الوقت ، ستظل (مجزأة على مستوى نظام التشغيل) مجزأة ماديًا جدًا ، مما يمكن أن يقلل بشكل كبير من سرعة المسح الضوئي والنسخ الاحتياطي وما إلى ذلك.


للتحقق ، قمت بكتابة برنامج نصي وأجريت الاختبارات.


المفسد: المشكلة موجودة (تؤثر بشكل كبير على الأداء) على واحد فقط من النماذج التي تم توفيرها (ويتم وضعها من قبل الشركة المصنعة ليس كمركز بيانات ، ولكن كمكتب / كمبيوتر محمول).


ما هو كل شيء؟ ماذا تجزئة أخرى داخل SSD؟

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


, FTL, , , , . , .
.


فكرة النص: نقوم بإنشاء ملف يحتوي على عدة غيغابايت ، مليئة ببيانات عشوائية ، نقيس سرعة القراءات التسلسلية.
بعد ذلك ، باستخدام الوصول العشوائي ، نعيد كتابة جزء من ملف الاختبار ونقيس مرة أخرى سرعة القراءة الخطية. إذا كانت شكوكنا صحيحة ، فإن القراءة الآن من الملف ستتباطأ.
بعد كل عملية كتابة ، نقوم بإجراء ثلاث عمليات قراءة مع تأخير بينها في حالة قيام بعض محركات الأقراص في الخلفية بإجراء عملية إلغاء التجزئة ثم تحسين سرعة القراءة.


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


ملخّص: قد يكون إلغاء التجزئة مفيدًا لبعض محركات الأقراص ذات الحالة الثابتة ، ولكنه ليس متشابهًا تمامًا (على الإطلاق؟) بالنسبة لمحركات الأقراص الثابتة . من المهم بالنسبة لنا ليس فقط أن الملف موجود في سلسلة مستمرة من القطاعات ، ولكن أيضًا أن التسجيل في هذه القطاعات كان متسلسلاً.


PS سأكون ممتنًا إذا قام القراء بتشغيل النص البرمجي في مكانهم وإعطاء أرقام لأقراص SSD الخاصة بهم ، نظرًا لأن اختياري من محركات الأقراص هو من جانب واحد.


All Articles