Твердотельный накопитель воспринимается операционной системой как обычный блочный диск, но внутри устроен радикально иначе: флеш-память NAND не умеет перезаписывать данные "по месту", изнашивается с каждым циклом стирания и живёт под управлением сложной прошивки, главная задача которой - равномерно распределить этот неизбежный износ по всему массиву ячеек. Именно этим занимается wear leveling, и понимание его работы объясняет почти все особенности SSD: рейтинги TBW, запасные области, коэффициент усиления записи, поведение при отказе и даже странности утилит оптимизации в Windows.

Ресурс ячеек NAND и иерархия страниц и блоков

Каждая ячейка NAND хранит заряд в изолированном плавающем затворе, и каждая операция записи или стирания гонит электроны сквозь туннельный оксид, постепенно деградируя его. У деградации есть счётчик - циклы программирования и стирания, P/E cycles. Чем больше бит хранит одна ячейка, тем тоньше необходимые различия уровней заряда и тем быстрее шум изношенного оксида съедает весь запас надёжности. Ориентировочные типовые значения выглядят так: SLC держит порядка ста тысяч циклов, MLC - около десяти тысяч, TLC - примерно три тысячи, QLC - около одной тысячи. Промышленные pSLC-режимы и современные 3D-процессы сдвигают цифры, но порядок величин и лестница сохраняются.

Вторая фундаментальная асимметрия - гранулярность операций. Запись в NAND выполняется страницами размером от четырёх до шестнадцати килобайт, а стирание - только целыми блоками, в которых сотни страниц. Перезаписать одну страницу на месте невозможно вообще: прошивка обязана записать новую версию данных в свободную страницу, пометить старую как недействительную, а когда в блоке накопится много "мусора", выполнить сборку - перенести все ещё живые страницы блока в свежий блок и стереть старый целиком. Отсюда вытекает патологическая стоимость обновления: одна перезапись четырёх килобайт от хоста способна обернуться переносом сотен килобайт внутри накопителя, если контроллеру не повезло с выбором блока-жертвы.

Стоит добавить, что деградация оксида не двоична: ячейка не ломается в одном цикле, а постепенно "плывёт" по пороговым напряжениям. Контроллер компенсирует это подстройкой опорных уровней чтения и коррекцией ошибок ECC, и износ проявляется сначала как рост числа исправляемых бит, потом как рост задержек чтения из-за повторных попыток, и лишь в конце - как неисправимые ошибки. Хорошая прошивка использует рост счётчика исправлений ECC как ранний индикатор и выводит деградирующий блок из ротации заблаговременно, пока данные ещё читаются без потерь.

Трансляция адресов и внутренняя география FTL

Чтобы скрыть эту асимметрию от хоста, каждый SSD несёт на борту Flash Translation Layer - отображение логических адресов LBA на физические страницы. Таблица отображения хранится в оперативной памяти контроллера и периодически сбрасывается во флеш; её размер у современных дисков измеряется мегабайтами, и дешёвые модели без DRAM вынуждены держать часть таблицы во флеше, что искусственно замедляет случайные записи.

FTL - это сердце всех алгоритмов износа. Поскольку любой логический адрес может жить в любой физической странице, контроллер свободен решать, куда физически ляжет очередная запись. Именно эта свобода превращается в инструмент: прошивка ведёт счётчики стираний для каждого блока и выбирает место записи так, чтобы ни один блок не выбегал вперёд по счётчику слишком сильно. Заодно FTL решает задачи плохих блоков с завода, резервных замен и выравнивания температурной нагрузки между кристаллами.

Динамический и статический wear leveling

Различают два уровня алгоритма. Динамический wear leveling пассивен и работает бесплатно: когда хост перезаписывает активно меняющиеся данные, контроллер просто берёт свежие блоки из пула с наименьшим числом стираний. Горячие данные сами "ездят" по диску, и их износ растекается равномерно без лишней работы.

Проблема - холодные данные. Системные файлы, прошивки, архивы, редко редактируемые документы записываются один раз и занимают свои блоки месяцами. Если бы контроллер выравнивал износ только динамически, блоки с холодными данными остались бы почти свежими, а остальной массив вырабатывал бы ресурс быстрее, теряя фактическую ёмкость задолго до расчётного срока. Поэтому статический wear leveling фоном перетаскивает редко меняющиеся данные из почти нетронутых блоков в изношенные, освобождая свежие блоки под горячую запись. Эта работа стоит дополнительных циклов чтения-записи и поэтому выполняется деликатно, в моменты простоя или по достижении порогов расхождения счётчиков.

Качество реализации сильно различается между вендорами прошивок. Успех алгоритма измеряется разбросом счётчиков стираний по массиву: в хорошо ухоженном диске максимум не далее чем на десятки процентов превышает среднее к концу жизни, тогда как слабая прошивка допускает локальный "перегар" отдельных областей.

Интересная деталь - поведение отображения после отключения питания. Таблица FTL частично живёт в энергозависимой памяти, и при внезапной потере питания контроллер обязан успеть сохранить её или уметь восстановить по журналу и разбросанным по страницам служебным меткам. Корпоративные модели держат для этого танталовые конденсаторы, потребительские полагаются на аккуратные контрольные точки. Сбой восстановления таблицы опаснее износа: диск с половиной ресурса внезапно "теряет" файловую систему именно из-за порчи отображения, и профессиональное восстановление данных в таких случаях сводится к реконструкции FTL на внешнем стенде.

Overprovisioning, сборка мусора и усиление записи

Запасная область - часть физической ёмкости, невидимая хосту. Заводской overprovisioning обычно составляет около семи процентов разницы между гибибайтами и гигабайтами маркетинга, а накопители корпоративного класса отдают под резерв до двадцати восьми процентов флеша. Эти резервные блоки дают сборщику мусора "локомотивное депо": всегда есть куда переложить живые страницы перед стиранием блока-жертвы, не дожидаясь освобождения места логикой хоста.

Эффект измеряется коэффициентом усиления записи - отношением байт, реально записанных во флеш, к байтам, присланным хостом. В идеальных последовательных нагрузках на свежий диск он опускается до значений около 1.1, на насыщенном случайном рабочем сете с маленьким запасом - взлетает к трём и выше. Каждая единица усиления буквально съедает ресурс: при коэффициенте 2.5 рейтинг TBW из даташита превращается в ёмкость, которую хост успеет записать лишь на сорок процентов от номинала. Производители учитывают это при калибровке рейтингов, закладывая типовую смесь рабочих нагрузок по методикам JEDEC.

Дополнительный резерв пользователь способен создать сам, оставив неразмеченное пространство на диске - контроллер утилизирует его так же, как заводской запас, потому что любой стёртый блок для FTL равнозначен свободному.

TBW, реальные темпы записи и срок службы

Рейтинг TBW в даташите - гарантированный объём хостовой записи за гарантийный период. Типичный потребительский диск на один терабайт несёт рейтинг в районе шестисот терабайт, то есть около шестисот полных перезаписей ёмкости. Пересчёт в годы при домашнем сценарии обнадёживает: средний пользовательский ПК записывает от двадцати до сорока гигабайт в сутки с учётом подкачки, кэшей браузера и обновлений системы. Тридцать гигабайт в день дают примерно одиннадцать терабайт в год, и шестисот терабайт рейтинга превращаются в полвека расчётной жизни - механическая усталость разъёма и деградация удержания заряда при простое диска наступят на порядок раньше.

Совсем иная картина у нагрузок с интенсивной записью: видеонаблюдение, базы данных с журналированием, кэширующие узлы. Там дневная запись измеряется терабайтами, рейтинг выбирается за месяцы, и именно для таких ролей выпускаются модели с высоким DWPD - допустимым числом полных перезаписей в день. Практический вывод для инженера прост: подбирать накопитель нужно сначала по профилю записи, и только потом по ёмкости и интерфейсу.

TRIM, SMART и поведение перед отказом

Команда TRIM сообщает контроллеру, какие логические блоки файловая система больше не считает занятыми. Без неё SSD узнавал об освобождении места только в момент перезаписи, и сборщик мусора физически копировал давно удалённые данные как живые. С TRIM контроллер помечает освобождённые страницы мусором заранее, усиление записи падает, а фоновая сборка работает с меньшим объёмом бесполезного переноса. В современных Windows дефрагментатор для SSD не двигает файлы - он выполняет retrim, повторную рассылку TRIM по всему том, что полезно после сбоев драйверов и накопленных очередей отброшенных команд. Классическая же дефрагментация SSD бессмысленна: флешу безразлично физическое расположение страниц, а лишние перезаписи лишь тратят циклы P/E.

Перед исчерпанием ресурса качественный накопитель ведёт себя предсказуемо. Когда запас резервных блоков подходит к концу, прошивка переводит диск в режим только чтения: данные остаются доступными для эвакуации, запись отклоняется с ошибкой. Это реализовано умышленно - потерять возможность записи несоизмеримо лучше, чем молча потерять уже записанное. Наблюдать за приближением порога позволяют SMART-атрибуты: у NVMe это Percentage Used в процентах от расчётного ресурса и Available Spare, у SATA-дисков - Media Wearout Indicator и смежные поля вроде Total LBAs Written. Регулярный мониторинг этих величин позволяет планировать замену задолго до того, как счётчик достигнет ста процентов.

Практические рекомендации

Собирая инженерный опыт воедино, разумные правила эксплуатации выглядят так:

  1. Оставлять десять-двадцать процентов ёмкости незанятой, чтобы сборщику мусора всегда хватало свободных блоков.
  2. Следить за включённым TRIM и не отключать плановую оптимизацию томов в Windows.
  3. Под интенсивные записи выбирать модели с высоким TBW или DWPD, а не рассчитывать на запас потребительских дисков.
  4. Раз в квартал проверять Percentage Used и Available Spare, настраивая оповещения при ускорении расхода ресурса.
  5. Не выполнять классическую дефрагментацию SSD и не применять "оптимизаторы" с агрессивной перезаписью файлов.

Как читать данные диска честно. SMART SSD стоит учиться читать не в едином балле, а в профиле. Percentage Used или Media Wearout Indicator показывает израсходованную долю ресурса по внутреннему счёту производителя, Available Spare говорит о запасе резервных блоков в процентах, а счётчик переназначенных блоков сигнализирует о выходе ячеек из строя после фатальной ошибки записи. Суды по этим значениям коротки: если Percentage Used подбирается к сотне раньше жизненного цикла изделия, значит нагрузка выше расчётной, и причина ищется в write amplification профиле работы, а не в самом пресловутом показателе. Дешёвые диски с маленьким overprovisioning ведут себя особенно остро при заполнении свыше 80 процентов: мусорки негде работать, сборка затяжна, latency выстреливает независимо от износа. Поэтому рекомендация «держать десяток процентов свободными» носит не мистический, а сугубо инженерный смысл - мусорный сборщик нуждается во флипчарт мест для манёвров.

Отчёт о смерти имеет вид журнала. Показателен случай, когда диск уходит в защищённое чтение: контроллер охраняет данные последним ресурсом, включает read-only режим и ждёт изъятия. Пользователь слышит в эту минуту не зловещий щелчок, а тишину: файлы читаются, система грузится медленно, при попытке записи - отказ. Именно в этой форме отказ flash-накопителя выигрывает у отказа дискового: никаких стуков, только математика, которая предупреждала заранее кто-бы слушал.

Wear leveling не делает флеш вечной, но превращает конечный ресурс ячеек из лотереи в управляемую величину. Диск, у которого износ распределён равномерно, доживает до своего паспортного TBW и уходит в защитное чтение по расписанию инженера прошивки, а не по прихоти статистики - и это, пожалуй, лучшая форма отказа, которую можно пожелать накопителю.