Поддержка

Получите ответы на ваши вопросы о программировании постоянной памяти.

Форум

Концепции

Что такое модель программирования SNIA NVM*?

Эта спецификация SNIA (Storage Networking Industry Association)* определяет рекомендуемое взаимодействие между различными пространствами пользователя и компонентами ядра операционной системы, поддерживающими энергонезависимую память (NVM). Данная спецификация не описывает конкретный прикладной программный интерфейс. Вместо этого ее назначение заключается в активации общих действий NVM для работы с несколькими интерфейсами операционных систем. Некоторые методы, используемые в этой модели, представлены назначенными файлами памяти, прямым доступом (DAX) и т.д. Для получения дополнительной информации см. раздел Модель программирования SNIA NVM.

Что такое DAX?

Функция DAX обеспечивает прямой доступ к файлам в постоянной памяти или на блоковом устройстве. Без поддержки DAX в файловой системе, страница кэша, как правило, используется для буфферизации запросов на чтение и запись файлов и требует выполнения дополнительной операции копирования.

Функция DAX исключает лишнюю операцию копирования, выполняя чтение и запись непосредственно на устройстве хранения данных. Она также используется для представления страниц, которые назначаются в пользовательском пространстве посредством вызова в mmap. Для получения дополнительной информации см. раздел Прямой доступ к файлам.

Для чего используется файловая система с поддержкой постоянной памяти?

Файловая система с поддержкой постоянной памяти может идентифицировать поддержку ядром функции DAX. Если она есть, то когда приложение открывает назначенный файл памяти в этой файловой системе, она получает прямой доступ к региону постоянной памяти. К файловым системам с поддержкой постоянной памяти можно отнести EXT4, XFS в ОС Linux*, а также NTFS в ОС Microsoft Windows Server*.

Для получения поддержки функции DAX файловая система должна быть смонтирована с параметром dax. Например, в файловой системе EXT4 вы можете сделать следующее:

mkfs –t ext4 /dev/pmem0
 mount –o dax /dev/pmem0 /dev/pmem

Чем назначение памяти для файлов отличается от постоянной памяти с байтовой адресацией?

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

Когда вы используете назначение памяти для файла, вы требуете от операционной системы назначения файла в памяти с последующим выделением данного региона памяти в виртуальном адресном пространстве приложения.

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

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

Что такое атомарность?

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

Для чего нужна таблица блочного преобразования (BTT) для управления атомарностью секторов?

Таблица преобразования блоков (BTT) обеспечивает семантику атомарности обновления секторов для устройств постоянной памяти. Она предотвращает появление ошибок записи в приложениях, которые используют записи секторов данных. Сами манифесты BTT представляют собой соединенные блоковые устройства и оставляет часть устройства хранения для записи метаданных. Это "непрямая" таблица, которая переопределяет назначение всех блоков на томе. Таблицу BTT можно рассматривать как очень простую файловую систему, единственным назначением которой является обеспечение обновлений атомарных секторов.

Какие возможны проблемы адаптации программного обеспечения для поддержки постоянной памяти?

К основным проблемам реализации поддержки постоянной памяти относится следующее:

  • Обеспечение постоянства и соответствия данных
  • Обнаружение и обработка ошибок постоянной памяти
В чем заключается важность очистки (+fence)?

Когда приложение выполняет запись в постоянную память, ее постоянство не гарантируется, пока не будет обеспечена защита от сбоев питания. Для обеспечения того, что запись защищена от ошибок, необходимо выполнять очистку (+fence) после записи.

Как осуществляется очистка кэша процессора из пространства пользователя?

Это можно сделать тремя способами:

  • Используйте команду  CLFLUSH для очистки одной строки кэша в данный момент времени. CLFLUSH — это последовательная команда, которая используется для очистки диапазона постоянной памяти. Выполнение циклов и использование команды CLFLUSH  означает, что очистки выполняются последовательно, одна после другой.
  • Используйте команду CLFLUSHOPT  для параллельной очистки нескольких строк кэша. Выполняйте эту команду вместе с командой  SFENCE, так как порядок выполнения недостаточно строг. Для получения дополнительной информации о командах выполните поиск темы "CLFLUSH — Очистка строки кэша" в документации Архитектуры Intel® 64 и IA-32 - Руководство разработчика программного обеспечения - Объединенные тома.
  • Используйте также команду CLWB, которая работает подобно CLFLUSHOPT, за исключением того, что строка кэша может оставаться действительной в кэш-памяти.
Почему важны транзакции?

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

Могут ли команды Intel® Transactional Synchronization Extensions (Intel® TSX) использоваться для постоянной памяти?

Нет. С точки зрения использования процессора, постоянная память представляет собой обычную память, и процессор может выполнять на ней любой тип команд. Проблема заключается в атомарности. Применение Intel® TSX реализовано на уровне кэша, поэтому любая очистка кэша просто остановит транзакцию. Если очистка не произойдет после успешного завершения транзакции, значит отказоустойчивость и доступность атомарности не синхронизированы.

 
Обзор комплекта PMDK

Что такое PMDK?

Комплект Persistent Memory Development Kit (PMDK), который ранее назывался NVML (Non-Volatile Memory Library), представляет собой коллекцию библиотек и инструментальных средств, предназначенных для разработки приложений с поддержкой энергонезависимой памяти.  Проект PMDK с открытым исходным кодом в настоящее время поддерживает десять библиотек, которые предназначены для различного использования постоянной памяти и языков программирования C, C++, Java и Python*. Комплект PMDK также содержит инструментальные средства, такие как плагин pmemcheck для инструментария с открытым исходным кодом, valgrind, а также расширяемый комплект документации, примеры кода, учебные руководства и публикации блога. Все его библиотеки подготовлены и проверены для обеспечения производственного качества, а также лицензируются для использования в разработках с открытым и закрытым исходным кодом. Проект продолжает расширяться с добавлением новых примеров использования.

Почему нужно использовать PMDK?

Комплект PMDK предназначен для разрешения проблем постоянной памяти и содействия развитию программирования для постоянной памяти. Он предлагает разработчикам хорошо протестированные, готовые к использованию библиотеки и инструментальные средства в рамках полнофункциональной модели программирования SNIA NVM (Storage Networking Industry Association Non-Volatile Memory).

В чем различие комплектов SPDK (Storage Performance Development Kit) и PMDK?

Комплект PMDK предназначен и оптимизирован для использования постоянной памяти с байтовой адресацией. Эти библиотеки могут использоваться с двойными последовательными энергонезависимыми модулями памяти (NVDIMM), такими как NVDIMM-N, в дополнение к модулям памяти Intel® Optane™ DC.

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

Все библиотеки реализованы для языка C, а также имеют специальные привязки библиотеки libpmemobj на языке C++.

Входит ли в состав PMDK библиотека, которая может использоваться для доступа к постоянной памяти?

Да. Libpmem — это простая библиотека, которая определяет типы команд очистки, поддерживаемых процессором. Она использует лучшие команды для взаимодействия с платформой и создания оптимизированных процедур копирования диапазонов постоянной памяти.

Существуют ли библиотеки, поддерживающие транзакции?

Да. Три библиотеки: libpmemobj, libpmemblk и libpmemlog.

  • Libpmemobj предлагает для использования хранилище объектов транзакций, обеспечивая выделение памяти, транзакции и общие ресурсы для программирования постоянной памяти.
  • Libpmemlog обеспечивает работу функции резидентного журнала постоянной памяти (pmem-resident). Это полезно для программ, таких как базы данных, которые часто обновляют записи файла журнала.
  • Libpmemblk поддерживает массивы резидентных блоков постоянной памяти одного размера с обновлением атомарности. Например, эта библиотека может оказаться полезной для программы поддержания объектов кэша фиксированного размера в постоянной памяти.
Могу ли я использовать функцию malloc для выделения постоянной памяти?

Нет. Комплект PMDK содержит интерфейс для выделения и управления постоянной памятью.

Как тестировались библиотеки PMDK?

Функциональность библиотек была протестирована с помощью эмуляций постоянной памяти и DRAM. В настоящее время выполняется тестирование на аппаратных компонентах.

Существуют ли примеры реальных приложений, использующих PMDK?

Да. Например, мы добавили поддержку постоянной памяти для среды Redis*, которая позволяет использовать дополнительные параметры конфигурации для управления постоянством. В частности, во время работы Redis в режиме только добавления данных файлов (Append Only File) все команды сохраняются в файле журнала постоянной памяти вместо обычного добавляемого текстового файла, который хранится на обычном жестком диске. Файлы резидентного журнала постоянной памяти создаются с помощью библиотеки libpmemlog.

Для получения информации о среде Redis и инструкций сборки см. документацию Libraries.io.

 
PMDK — libpmem

Когда необходимо использовать libpmem, а не libpmemobj?

Библиотека libpmem предоставляет низкоуровневую поддержку постоянной памяти. Используйте libpmen, если вы планируете самостоятельно выполнять выделение и проверку целостности постоянной памяти.

Большинство разработчиков используют библиотеку libpmemobj, которая обеспечивает:

  • Хранилище транзакционных объектов
  • Выделение памяти
  • Транзакции
  • Общую инфраструктуру для программирования постоянной памяти

Используйте libpmem для реализации libpmemobj.

Каково различие между pmem_memcpy_persist и pmem_persist?

Различие заключается в том, что pmem_persist ничего не копирует, а только очищает данные в постоянной памяти (из кэша ЦП). Другими словами:

pmem_memcpy_persist(dst, src, len) == memcpy(dst, src, len) + pmem_persist(dst, len)

 
PMDK — libpmemobj

Что означают термины "хранилище объектов", "пул памяти" и "схема"?
  • Хранилище объектов: используется для обработки двоичных объектов постоянства в качестве объектов различного размера (в отличие от файлов или блоков)
  • Пул памяти: назначенные файлы используемой памяти
  • Схема: строка на ваш выбор, которая идентифицирует пул
Что приводит к медленной работе libpmemobj на твердотельных накопителях?

Комплект PMDK предназначен и оптимизирован для использования постоянной памяти с байтовой адресацией, а твердотельные накопители являются блоковыми устройствами. Для работы libpmemobj на твердотельных накопителях требуется преобразование блоковой адресации в байтовую. Это добавляет дополнительное время для выполнения транзакции. Кроме того, это требует перемещения целых блоков из твердотельного накопителя в память и обратно для чтения и очистки операций записи.

Как приложение находит объекты в назначенном файле памяти, когда выполняется перезагрузка после сбоя?

Библиотека libpmemobj определяет назначенные регионы памяти в виде пулов, и они идентифицируются схемой. Каждый пул имеет известное местоположение, называемое корнем (root), и все структуры данных имеют привязку к этому корню. Когда приложение восстановится после сбоя, оно запрашивает данные о корневом объекте, из которого затем могут быть восстановлены остальные данные.

Поддерживает ли libpmemobj локальную и удаленную репликации?

Да, библиотека libpmemobj поддерживает как локальную, так и удаленную репликации с помощью параметра sync команды pmempool или прикладного интерфейса pmempool_sync() из библиотеки libpmempool(3).

Какая поддержка доступна для транзакций, охватывающих несколько разных пулов памяти?

Не существует поддержки транзакций, охватывающих несколько пулов памяти, где каждый пул имеет такой же или другой тип.

Как в libpmemobj обеспечивается параллельная обработка?

Библиотека libpmemobj обрабатывает номер поколения, который наращивается после каждого открытия пула pmemobj. Когда установлена блокировка постоянной памяти (pmem), например, такая как PMEM mutex, блокировка сверяется с текущим номером поколения для того, чтобы определить, является ли это первым использованием после открытия пула. Если это так, то устанавливается блокировка. Таким образом, если вы используете тысячу блокировок, и произойдет сбой компьютера, все эти блокировки будут сброшены, так как номер поколения будет увеличен после открытия пула и уменьшен после закрытия. Это позволяет избежать необходимости перебора всех блокировок.

 
Безопасность потоковой обработки

Безопасны ли функции управления потоковой обработкой?

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

Безопасна ли обработка потоков pmem_persist?

Нет. Роль pmem_persis предназначена для гарантированного вывода переданного региона памяти из кэша процессора независимо от находящейся в регионе информации. Хранение и очистка являются раздельными операциями. Для надежного атомарного хранения и использования выполняйте ручную блокировку обеих операций.

 
PMDK — Управление пулами

Как определить размер пула pmemobj, если нужно выделить N объектов конкретного размера?

Библиотека libpmemobj использует около четырех килобайт на каждый пул плюс 512 килобайт на 16 гигабайт статических метаданных. Например, пул размером 100 гигабайт потребует выделения 3588 килобайт статических метаданных. Кроме того, каждый блок памяти (256 килобайт), используемый для небольших выделений (меньше или равно двум мегабайтам), использует 320 байт метаданных. Также каждый выделенный объект имеет заголовок размером 64 байта.

Как использовать pmempool во время создания большого пула (более 100 ГБ)?

Один из способов убедиться в том, что у вас есть зарезервированная постоянная память перед использованием pmempool, является использование команды create. Для получения подробной информации используйте команду man pmempool-create.

Создание файла пула 110 ГБ.

$ pmempool create blk --size=110G pool.blk

Создание максимально разрешенного файла журнала пула.

$ pmempool create log -M pool.log
Доступна ли поддержка нескольких пулов в рамках одного файла?

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

Как расширить пул постоянной памяти?

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

Каков допустимый способ расширения пула libpmemobj?

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

Можно ли удалить пул памяти с помощью libpmemobj?

Нет. Функция pmemobj_close() закрывает пул памяти и не удаляет функции его обработки. Сам объект хранится в содержащем его файле и может быть снова открыт позже.

Для удаления пула воспользуйтесь одним из следующих вариантов:

  • Удалите файл из файловой системы, где назначена ваша память (пул объекта).
  • Используйте команду pmempool, rm.

 
PMDK — Аппаратное и программное обеспечение

Работает ли PMDK с другими модулями NVDIMM?

Да. PMDK является платформой, независимой от предоставляемой поставщиками информации, хотя ее библиотеки оптимизированы для наилучшего взаимодействия с энергонезависимой памятью Intel® Optane™ DC.

Требуется ли PMDK для доступа к модулям NVDIMM?

Наличие комплекта PMDK не является обязательным, но его использование способствует программированию постоянной памяти. Вы можете использовать библиотеки PMDK как двоичные файлы, или выбрать рекомендуемый код в библиотеках, если создаете код для использования постоянной памяти "с нуля".

Является ли PMDK частью любой ОС Linux* или Microsoft Windows*?

Да. Библиотеки PMDK (не инструментальные средства) включены в состав ОС Linux, Suse*, Red Hat Enterprise Linux* и Ubuntu*.

Для Microsoft Windows: библиотеки PMDK (не инструментальные средства) включены в состав ОС Windows Server* 2016 и Windows® 10. Для получения дополнительной информации см. в блоге pmem.io раздел PMDK для Windows.

Для получения полной версии комплекта PMDK загрузите его из ресурса PMDK GitHub.

Поддерживает ли комплект PMDK архитектуру ARM64*?

В настоящее время поддерживаются только 64-разрядные ОС Linux* и Windows* на архитектуре x86.

Поддерживают ли библиотеку libpmem блочные устройства для хранения данных на основе технологии Intel® Optane™ (например, память Intel® Optane™ и SSD-накопители Intel® Optane™)?

Нет. Комплект PMDK предназначен и оптимизирован только для устройств, использующих постоянную память с байтовой адресацией.

 
PMOF (Persistent Memory Over Fabric)

Что такое PMOF?

Функция PMOF позволяет выполнять репликацию данных удаленно между компьютерами с постоянной памятью.

Каково назначение librpmem и rpmemd?

Функции librpmem и rpmemd реализуют применение постоянной памяти через высокоскоростное сетевое подключение (PMOF). Librpmem — библиотека комплекта PMDK, которая будет работать на узле инициатора, и rpmemd — это новый удаленный демон PMDK, который будет работать на каждом удаленном компьютере для репликации данных. Данный дизайн позволяет использовать прикладной интерфейс libfabric на уровне приложения, OpenFabrics Alliance (OFA), для сетевой инфраструктуры удаленного прямого доступа к памяти (RDMA).

 
Отладка

Как включить журналы отладки libpmemlog для моего приложения?

Выполните привязку приложения с использованием параметра -lpmemlog. Этот параметр оптимизирован для обеспечения высокой производительности, пропускает проверки, которые снижают эффективность обработки, и никогда не выполняет запись информации трассировки в журналы или анализ во время выполнения.

Имейте в виду следующее:

  • Библиотеки в папке /usr/lib/PMDK_debug, содержащие функции оценки выполнения и точки трассировки
  • Переменная среды LD_LIBRARY_PATH, установленная для /usr/lib/PMDK_debug или /usr/lib64/PMDK_debug, зависит от наличия в системе библиотек отладки.

Точки трассировки в версии библиотеки отладки используются с помощью переменной среды PMEMLOG_LOG_LEVEL.