В прошлых частях цикла мы рассказывали про историю накопителей, о применяемых интерфейсах и форм-факторах, а также про организацию на физическом уровне. Пятая же часть посвящена «мозгу» современного твердотельного накопителя.

Контроллер современного накопителя — маленький компьютер, который принимает стандартизированные команды и выполняет соответствующие действия с подконтрольным ему хранилищем. При этом внутреннее устройство контроллера может быть любым.
У Intel есть накопитель P4618 6.4 TB, который представляется системе как два накопителя по 3.2 TB. Аналогичное встречается и среди жестких дисков. Накопители Seagate с технологией MACH.2 — это два диска, «заключенные» в одном корпусе и объединенные единым контроллером.
Контроллер — достаточно сложное устройство, которое в зависимости от предназначения диска выполняет различные задачи по управлению данными. Например, базы данных часто требуют от накопителя запись непосредственно в энергонезависимую память, минуя кэш, и в этом случае серверный SATA SSD будет быстрее, чем пользовательский NVMe. Из-за большой вариативности контроллеров не будем вдаваться в детали конкретных устройств, а поговорим об общих принципах работы современного твердотельного накопителя.

Особенности записи


Блоки и страницы в NAND-памяти. Источник
Хранилище твердотельного накопителя состоит из множества полевых транзисторов, соединенных друг с другом. При таком подходе чтение и запись выполняются страницами данных, размер которых обычно 4 КиБ. Таким образом, изменение одного бита на диске приводит к необходимости перезаписать всю страницу данных. Эта проблема называется усилением записи (Write Amplification).

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

  1. Чтение данных из страницы в буфер.
  2. Изменение данных в странице.
  3. Очистка страницы данных.
  4. Запись обновленных данных из буфера.

Контроллер умеет записывать страницы данных, а стирать только блоки — последовательность страниц. Обычно блок состоит из 64 страниц данных. В поставленных условиях и при конечном ресурсе перезаписи ячеек накопителя контроллеру нужно проводить операции записи и стирания аккуратно.

Износостойкость


Выравнивание износа. Источник
Современные накопители построены на базе ячеек TLC, ресурс которых в разы меньше, чем у накопителей с ячейками SLC и MLC. Если какая-то программа в ОС будет постоянно перезаписывать маленький файл, а контроллер будет «наивно» обновлять одну страницу данных, то вскоре блок с этой страницей исчерпает ресурс. Исчерпание ресурса будет отображено в показателях накопителя, что неизбежно приведет к беспокойству системного администратора.

Во избежание сильного износа единичных блоков накопителя применяются технологии выравнивания износа (Wear Leveling). При этом обновление данных выполняется без очистки страницы накопителя и выглядит так:

  1. Чтение данных из страницы в буфер.
  2. Изменение данных в странице.
  3. Запись обновленных данных из буфера в «чистую» страницу.
  4. Старая страница помечается как «грязная».

Очистка блока происходит после того, как все страницы отмечены «грязными». Возникает закономерный вопрос: как поведет себя накопитель, когда не останется «чистых» страницы и не будет блоков, готовых к очистке? Ответ прост: избыточность (over provisioning) и сборка мусора (garbage collection).

Балансировка износа


В каком-то смысле производитель накопителей обманывает нас дважды. Первый раз использует десятичные приставки вместо двоичных: 480 ГБ — это 447 ГиБ. А второй раз, когда фактический объем накопителя больше, чем доступно пользователю. Часть объема зарезервирована производителем для внутренних нужд контроллера. Такой резерв называется запасной областью (spare).

Таким образом, у контроллера всегда есть немного свободного пространства, которое может быть использовано для внутренних процессов. Хотя точных данных нет, в различных источниках утверждается, что для контроллера резервируется от 7 до 28 % объема накопителя.

Увеличение объема зарезервированной области уменьшает доступный объем, но чаще всего повышает производительность диска. Для увеличения spare-области достаточно оставить часть накопителя неразмеченным. Однако если хочется экстрима и сделать все «по уму», то можно уменьшить объем видимого пользователю пространства через ключ -N утилиты hdparm.

Как бы то ни было, вернуть зарезервированную производителем область в собственное пользование не получится.

Процесс «сбора мусора». Источник
Помимо балансирования износа, в контроллерах в фоновом режиме часто проходит процесс «?сбора мусора» (garbage collection). В ходе него с нескольких блоков собираются актуальные страницы и помещаются в один блок. Затем исходные блоки очищаются, так как в них не осталось страниц с данным.

Важно отметить, что сборщик мусора занимается перекладыванием данных в хранилище, чтобы было как можно больше чистых блоков. При этом он не может понять, что на файловой системе какой-то файл отмечен удаленным, так как контроллер накопителя не умеет работать в терминах файловых систем.

Для решения этой проблемы в каждом из протоколов есть команда, позволяющая уведомить контроллер об удалении файла. Для NVMe — это deallocate, для SATA — TRIM, а для SCSI — unmap. Суть каждой их этих команд одинакова: пометить страницы с удаленным файлом как «грязные».

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

Это легко подтверждается с помощью эксперимента. Проводим Secure Erase для накопителя и запускаем тесты на случайное чтение с глубиной очереди 64. Затем «забиваем» накопитель с помощью последовательной записи, желательно дважды. И повторяем тесты.
Размер блока Чистый Забитый
4M 3400 MiB/s 3376 MiB/s
8M 3399 MiB/s 3336 MiB/s
В наших тестах использовался SSD-накопитель Micron 7300 1.92 TB, подключенный по PCIe 3.0 x4. Третья версия PCI Express по четырем линиям способна пропускать 3940 МБ/с или 3757 МиБ/с. Мы, конечно, не достигли предела, но надо полагать, это из-за накладных расходов на протокол NVMe. Тем не менее, видно, что чтение с диска без данных «упирается» в предел 3400 МиБ/с. После заполнения диска на 15% результаты тестов стали хуже.

Несмотря на то, что контроллер накопителя всегда пытается сделать как лучше, иногда системному администратору стоит взглянуть на показатели диска своими глазами.

Показатели


Вне зависимости от интерфейса накопителя SSD имеют набор показателей состояния, которые могут быть считаны системным администратором. Для SATA-накопителей используются показатели S.M.A.R.T., которые не стандартизированы. Отсутствие стандарта приводит к появлению различных трактовок одного показателя.

Рассмотрим вывод утилиты smartctl на примере Intel S4510.

# smartctl -iA /dev/sda
smartctl 7.3 (build date Jan  1 2021) [x86_64-linux-4.15.0-51-generic] (local build)
Copyright (C) 2002-21, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Family:     Intel S4510/S4610/S4500/S4600 Series SSDs
Device Model:     INTEL SSDSC2KB480G8
Serial Number:    ThereIsNoSerialHere
LU WWN Device Id: 5 5cd2e4 14fd823b7
Firmware Version: XCV10100
User Capacity:    480,103,981,056 bytes [480 GB]
Sector Sizes:     512 bytes logical, 4096 bytes physical
Rotation Rate:    Solid State Device
Form Factor:      2.5 inches
TRIM Command:     Available, deterministic, zeroed
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   ACS-3 T13/2161-D revision 5
SATA Version is:  SATA 3.2, 6.0 Gb/s (current: 6.0 Gb/s)
Local Time is:    Mon Jul  5 14:30:43 2021 MSK
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART Attributes Data Structure revision number: 1
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  5 Reallocated_Sector_Ct   0x0032   100   100   000    Old_age   Always       -       0
  9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       21345
 12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       76
170 Available_Reservd_Space 0x0033   100   100   010    Pre-fail  Always       -       0
171 Program_Fail_Count      0x0032   100   100   000    Old_age   Always       -       0
172 Erase_Fail_Count        0x0032   100   100   000    Old_age   Always       -       0
174 Unsafe_Shutdown_Count   0x0032   100   100   000    Old_age   Always       -       48
175 Power_Loss_Cap_Test     0x0033   100   100   010    Pre-fail  Always       -       2625 (76 65535)
183 SATA_Downshift_Count    0x0032   100   100   000    Old_age   Always       -       0
184 End-to-End_Error_Count  0x0033   100   100   090    Pre-fail  Always       -       0
187 Uncorrectable_Error_Cnt 0x0032   100   100   000    Old_age   Always       -       0
190 Drive_Temperature       0x0022   080   080   000    Old_age   Always       -       20 (Min/Max 11/21)
192 Unsafe_Shutdown_Count   0x0032   100   100   000    Old_age   Always       -       48
194 Temperature_Celsius     0x0022   100   100   000    Old_age   Always       -       20
197 Pending_Sector_Count    0x0012   100   100   000    Old_age   Always       -       0
199 CRC_Error_Count         0x003e   100   100   000    Old_age   Always       -       0
225 Host_Writes_32MiB       0x0032   100   100   000    Old_age   Always       -       67625
226 Workld_Media_Wear_Indic 0x0032   100   100   000    Old_age   Always       -       276
227 Workld_Host_Reads_Perc  0x0032   100   100   000    Old_age   Always       -       84
228 Workload_Minutes        0x0032   100   100   000    Old_age   Always       -       1280413
232 Available_Reservd_Space 0x0033   100   100   010    Pre-fail  Always       -       0
233 Media_Wearout_Indicator 0x0032   100   100   000    Old_age   Always       -       0
234 Thermal_Throttle_Status 0x0032   100   100   000    Old_age   Always       -       0/0
235 Power_Loss_Cap_Test     0x0033   100   100   010    Pre-fail  Always       -       2625 (76 65535)
241 Host_Writes_32MiB       0x0032   100   100   000    Old_age   Always       -       67625
242 Host_Reads_32MiB        0x0032   100   100   000    Old_age   Always       -       359222
243 NAND_Writes_32MiB       0x0032   100   100   000    Old_age   Always       -       477803

Для нашего диска интересны следующие параметры:

  • 5 Reallocated_Sector_Ct — количество секторов с нулевым ресурсом.
  • 187 Uncorrectable_Error_Cnt — количество ошибок, которые не удалось исправить при помощи кодов коррекции.
  • 233 Media_Wearout_Indicator — процент износа диска.
  • 243 NAND_Writes_32MiB — объем данных, который был записан на диск за все время.

Уже в этом списке видны проблемы отсутствия стандартов. Так, параметр Host_Writes_32MiB встречается дважды: под номером 225 и под номером 241.

С точки зрения износа исправного диска интересен показатель 233 Media_Wearout_Indicator, так как при достижении числа 1023 накопитель программно заблокируется и будет доступен в режиме только для чтения.

Показатели S.M.A.R.T — это особенность протокола SATA. Для NVMe-накопителей есть NVMe log, который также считывается программой smartctl. Аналогичный вывод можно получить с помощью команды nvme smart-log.

# smartctl -iA /dev/nvme0n1
smartctl 7.3 (build date Jan  1 2021) [x86_64-linux-4.15.0-51-generic] (local build)
Copyright (C) 2002-21, Bruce Allen, Christian Franke, www.smartmontools.org

=== START OF INFORMATION SECTION ===
Model Number:                       INTEL SSDPF2NV153TZ
Serial Number:                      ThereIsNoSerialToo
Firmware Version:                   ACV10024
PCI Vendor/Subsystem ID:            0x8086
IEEE OUI Identifier:                0x5cd2e4
Total NVM Capacity:                 15,362,991,415,296 [15.3 TB]
Unallocated NVM Capacity:           0
Controller ID:                      0
NVMe Version:                       1.3
Number of Namespaces:               128
Namespace 1 Size/Capacity:          15,362,991,415,296 [15.3 TB]
Namespace 1 Formatted LBA Size:     512
Namespace 1 IEEE EUI-64:            5cd2e4 71434b0400
Local Time is:                      Mon Jul  5 14:31:34 2021 MSK

=== START OF SMART DATA SECTION ===
SMART/Health Information (NVMe Log 0x02)
Critical Warning:                   0x00
Temperature:                        28 Celsius
Available Spare:                    100%
Available Spare Threshold:          10%
Percentage Used:                    0%
Data Units Read:                    77,871,643 [39.8 TB]
Data Units Written:                 148,394,810 [75.9 TB]
Host Read Commands:                 5,737,206,704
Host Write Commands:                1,802,643,030
Controller Busy Time:               81
Power Cycles:                       5
Power On Hours:                     146
Unsafe Shutdowns:                   1
Media and Data Integrity Errors:    0
Error Information Log Entries:      0
Warning  Comp. Temperature Time:    0
Critical Comp. Temperature Time:    0
# nvme smart-log /dev/nvme0n1
Smart Log for NVME device:nvme0n1 namespace-id:ffffffff
critical_warning                    : 0
temperature                         : 29 C
available_spare                     : 100%
available_spare_threshold           : 10%
percentage_used                     : 0%
data_units_read                     : 77,871,643
data_units_written                  : 148,394,810
host_read_commands                  : 5,737,206,704
host_write_commands                 : 1,802,643,030
controller_busy_time                : 81
power_cycles                        : 5
power_on_hours                      : 148
unsafe_shutdowns                    : 1
media_errors                        : 0
num_err_log_entries                 : 0
Warning Temperature Time            : 0
Critical Composite Temperature Time : 0
Thermal Management T1 Trans Count   : 0
Thermal Management T2 Trans Count   : 0
Thermal Management T1 Total Time    : 0
Thermal Management T2 Total Time    : 0

В выводе NVMe накопителя меньше непонятных показателей, но все равно есть место разночтениям. Легко предположить, что параметр percentage_used отвечает за объем занятого пользователем пространства на диске, но это не так. Этот параметр эквивалентен Media_Wearout_Indicator и обозначает износ накопителя.

Не стоит забывать, что предоставляемые показатели и поведение контроллера реализуется прошивкой, которая может быть обновлена.

Перепрошивка


О прошивке твердотельных накопителей задумываются нечасто. В лучшем случае после покупки «накатывают» свежую версию и забывают до конца жизни накопителя.

Как бы то ни было, обновления прошивки редко приносят какие-то значительные и заметные для пользователя нововведения. Прошивка, как и любое другое программное обеспечение, может содержать ошибки, в том числе критические. К счастью, это происходит редко, а потому нет надобности постоянно поддерживать актуальность прошивок на всех используемых накопителях.

Хотя NVMe можно перепрошить через команды fw-download и fw-commit, чаще всего обновление прошивки производится через утилиты, предоставляемые производителем накопителя. Во избежание потенциально деструктивных действий мы не будем публиковать точные команды, а порекомендуем обратиться к официальной инструкции от производителя.

Заключение


Контроллеры накопителей — сложные устройства, которые управляют не менее сложными процессами, которые проходят внутри твердотельных накопителей. Мы рассмотрели только самые интересные процессы в общих чертах.

Если вам хочется больше погрузиться в особенности работы с NVMe, рекомендуем статью про пространства имен NVMe.