مما لا شك فيه أن السؤال المطروح في عنوان المقال ليس جديداً ، فقد أثيرت أكثر من مرة وتم التوصل إلى إجماع عليه "لا حاجة إليه حقاً ، ويمكن أن يكون ضاراً".
ومع ذلك ، فإن المناقشة الأخيرة في التعليقات جعلتني أفكر مرة أخرى.
بمرور الوقت ، ستظل أي 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 -
psfio
; 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 :
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 الخاصة بهم ، نظرًا لأن اختياري من محركات الأقراص هو من جانب واحد.