Почему по мере заполнения SSD падает скорость записи в RAID

Эта проблема наиболее актуальна для аппаратных RAID или firmware RAID (таких как Intel RST RAID 1/10/5/6) с непромышленными SSD.Особенность SSDSSD пишут и читают данные страницами, записать можно только на очищенные страницы, а очистить страницы можно только большими блоками. Например, у диска размер страницы 8 КБ, в блоке находится 128 страниц, таким образом, размер блока — 1024 КБ (здесь и далее, если не указано иного, КБ и МБ двоичные).Например, если изменить 40 КБ в одном файле, то на физическом уровне это будет выглядеть так:

4ba5a2a952a843bc8a643d03b39cda18.pngНа логическом уровне всё выглядит как обычно — данные будут перезаписаны поверх в соответствующих секторах. Как только в блоке 1 останутся исключительно пустые и готовые для очистки страницы, этот блок стирается и становится пустым целиком.

Чтобы скрыть физическую реализацию, диск поддерживает карту соответствия логических и физических номеров страниц (Flash Translation Layer).

Пока мы видим только один путь, которым физическая страница сможет стать снова очищенной — если на её логический адрес запишут новые данные. Дело в том, что контроллер диска работает на уровне страниц и не знает ничего о файловой системе, а операционная система никак не извещает диск об удалённых файлах, какие секторы могут быть очищены. Несложно видеть, что рано или поздно каждая страница диска будет занята и ему будет некуда писать данные.

Чтобы решить это проблему, была добавлена команда ATA TRIM (wiki). Операционная система посылает её диску с указанием секторов, которые могут быть очищены. Аналоги этой команды — SCSI UNMAP и CF ERASE. К сожалению, в некоторых случаях нет возможности послать её диску: — если диск находится в RAID с аппаратным контроллером (LSI, Adaptec и т. п.), — если диски находится в firmware-RAID, в частности, Intel RST RAID 1/10/5/6, — если диск подключен по USB (ограничение протокола), — если диск зашифрован программно через TrueCrypt, dm-crypt, GELI и т.п. (по соображениям безопасности).

Если в результате тестирования выясняется, что диск не получает команду TRIM, то вскоре для записи может остаться совсем мало свободных страниц. Но они будут: каждый диск содержит некоторую зарезервированную область, которая служит как запас свободных страниц и запас блоков на замену полностью изношенным. Чтобы узнать размер этой области нужно посмотреть, какой физический объём памяти установлен на диске и сколько LBA указано в документации.

Например, Samsung SSD 840 Pro 512 GB имеет 512 ГБ памяти, при этом доступно 1000215216 LBA секторов. Резерв составляет: 512 × 1024 × 1024 × 1024 — 1000215216 × 512 = 35 ГБ или 6,85%. Доступная ёмкость диска при этом составляет (512 — 35) × 1024 × 1024 × 1024 = 512 × 10^9 = 512 ГБ, уже десятичных. Samsung SSD 850 Pro 128 ГБ имеет на борту 129 ГБ, пользователю доступно 128 ГБ десятичных, резерв — 7,6%.

Итак, если мы заполним весь диск, потом удалим все файлы, то без поддержки TRIM диск сможет писать только на какую-то часть от 6,85% объёма диска. Часть, потому что этот резервный объём будет частично состоять из не полностью пустых блоков из-за фрагментации. Наличие этой области позволяет хоть как-то продолжать перезапись файлов на диске.

Пример худшей ситуации: писать некуда, хотя объём занятых страниц не превышает доступный пользователю без резерва.

e5358d4dbfde46e2b70e1b5bfd980a85.png

В этом случае одновременно с записью работает сборщик мусора, который будет читать блок в оперативную память, стирать блок на диске (долгая операция, стирание занимает 3000 мкс в сравнении с 900 мкс записи в пустую страницу) и записывать блок из оперативной памяти. Задержка происходит также из-за роста Write Amplification — на одну логическую операцию записи приходится 5–10 физических операций записи.

Поэтому чем больше у диска есть свободного места для манёвров, тем выше скорость записи. Сборщик мусора в фоне занимается не только очисткой и дефрагментацией блоков, но и равномерным распределением циклов записи/очистки (P/E) по блокам, чтобы они изнашивались одинаково.

Есть популярный миф, что у современных дисков настолько хороший сборщик мусора, что им не нужен TRIM. Это совершенно не так, сборщик мусора и TRIM решают разные задачи.

Промышленные диски часто имеют 50% и больше резервной области, поэтому для них отсутствие TRIM не критично. Остальные диски чаще всего вообще не имеют явно заявленной резервной области, или она недостаточна. Тесты показывают, что хороший эффект имеет объём over-provisioning 25–29% от общего объёма физической памяти (включая резервную область). Поэтому если у диска недостаточный объём резервной области, то нужно сделать over-provisioning самостоятельно.

Есть три способа: — разметить диск таким образом, чтобы оставить некоторую часть неразмеченной области, — использовать команду ATA для создания Host protected area (howto), — настроить RAID контроллер, чтобы он использовал только часть объёма диска.

Прежде чем выделить свободную область, нужно дать знать диску, что эта область ничем не занята, одним из двух способов: — подключить диск с другому контроллеру и послать команду ATA TRIM (или при помощи O&O Defrag — есть cli интерфейс, Windows 8 встроенный оптимизатор дисков или Anvil’s Storage Utilities), — сделать полную очистку таблицы FTL, послав команду ATA Secure Erase.

Есть версия, что также можно заставить диск понять, что блоки не используются, если туда записать 0×00 или 0×01 (так называемый метод «Tony TRIM»). Возможно, для каких-то контроллеров это работает, но мои тесты не показали изменений.

На практике У меня есть два диска Samsung SSD 540 Pro 512 GB в Intel RST RAID 1, на которых установлена Windows 8.1. После года работы я измерил производительность и был неприятно удивлён. После проверки TRIM я увидел, что он не работает. Я решил создать неразмеченный раздел диска для over-provisioning.1. При помощи Acronis Backup я снял образ диска. Также сохранил таблицу разделов (важно иметь первый сектор, последний сектор, GPT тип раздела, GPT уникальный идентификатор, имя раздела).

2. Перезагрузился в BIOS и сделал SSD Secure Erase. Если этого пункта нет в BIOS, то можно выполнить команду при помощи hdparam (или здесь и здесь, есть под Windows), HDDErase или HDAT2.

3. Собрал RAID 1 на двух дисках.

Здесь нужно сделать важное замечание: при инициализации массива RAID-контроллер считывает каждый сектор с одного диска и записывает его на второй. Теоретически это должно помешать всей нашей затее, и на одном диске не будет over-provisioning. Но тесты показали, что этот метод почему-то работает. У меня этому нет объяснений.

4. Загрузился с LiveCD и при помощи GPT fdisk создал нужную таблицу разделов: последний раздел на 104 ГБ меньше, чем раньше. Разделы нужно выравнивать (partition align) по размеру страницы диска, а не по размеру блока.

5. Восстановил из резервной копии каждый раздел.

После этого я полностью заполнил диск и запустил тесты. Это должно показать худший случай. Кеш Windows включён, регулярная запись кеша выключена, Inter RST write-back выключен, все тесты используют область диска фиксированного размера в 40 ГБ. Тестировать диски непросто, поскольку показатели могут меняться во времени. Ниже сведены показатели установившегося состояния.

Я сравню три состояния: — Один диск без RAID, полностью заполненный, стандартная скрытая резервная область 6,58%.— Один диск без RAID, после запуска на нём TRIM свободного места.— Два диска в RAID 1, полностью заполненные, стандартная скрытая резервная область 6,58%.— Два диска в RAID 1, полностью заполненные, over-provisioning 27,24% (включая скрытую резервную область).

fd3b916664a0461480ccfe21f5c4a16e.png

Латентность и стандартное отклонение 51e45d074a164a20bed2d71aeb654887.png Таблица 7c1f35df56794f06aa2148ec29416675.png Анализ результатов: — чтение с RAID 1 оказывается быстрее, чем с одного диска, невзирая на то, что у нас всего лишь firmware RAID.— запись тем быстрее, чем больше нераспределенного пространства: на первом месте TRIM, на втором — наш самодельный over-provisioning.Установившееся состояние не всегда достигается быстро. Посмотрим тест последней конфигурации (over-provisioning 27,24%) в динамике и увидим худший случай:

bbadcffdfe34400099e929c92c27c266.png

351093c317314a8ca249b15ed8983ba5.png

Любопытный процесс идёт первые 400 секунд, после чего производительность возрастает и стабилизируется. Я думаю, параллельно с записью работает сборщик мусора, который дефрагментирует блоки и подготавливает их для записи. Такое поведение наблюдается не каждый раз, а время от времени. Видно, что последовательная запись проседает до 70 МБ/с, случайная запись — до 18000 IOPS. Эти показатели всё равно в два раза лучше, чем без over-provisioning (32 МБ/с и 7139 IOPS соответственно). Чтобы убедиться, что установившееся состояние на самом деле имеет такую высокую производительность, я также выполнил тест в течении 30 минут, при этом было записано на диск 490 ГБ со средним 69721 IOPS.

Можно сравнить наши результаты с коллегами и выбрать оптимальный размер over-provisioning:

Кратко  — Если диск получает ATA TRIM от ОС, то беспокоиться не о чем, достаточно оставлять часть места на диске свободным.— Если используются дорогие промышленные диски, то проверьте объём встроенной резервной области, если он достаточен, то проблем с записью не будет.— В остальных случаях нужно оставить не размеченную область, чем больше её размер, тем меньше будет стандартное отклонение латентности записи.— Иногда сборщик мусора не успевает подготовить чистые блоки и скорость записи может просесть и быть непостоянной.Ещё почитать.

© Habrahabr.ru