Отображенный в памяти MappedByteBuffer или Direct ByteBuffer для реализации БД?

Это выглядит длинным вопросом из-за всего контекста. Ниже в романе есть 2 вопроса. Спасибо, что нашли время, чтобы прочитать это и оказать помощь.

Ситуация

Я работаю над реализацией масштабируемого хранилища данных, которое может поддерживать работу с файлами данных размером от нескольких КБ до ТБ и более в 32-разрядной или 64-разрядной системе.

Хранилище данных использует дизайн «Копирование при записи»; всегда добавлять новые или измененные данные в конец файла данных и никогда не редактировать существующие данные на месте.

В системе может размещаться 1 или несколько баз данных; каждый представлен файлом на диске.

Детали реализации не важны; единственная важная деталь заключается в том, что мне нужно постоянно добавлять в файл и увеличивать его от КБ до МБ, от ГБ до ТБ, в то же время случайным образом пропуская файл для операций чтения, чтобы отвечать на запросы клиентов.

Первые мысли

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

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

Дизайн

Поскольку отдельные файлы данных могут расти за пределы 2 ГБ ограничения MappedByteBuffer, я ожидаю, что мой дизайн должен будет включать уровень абстракции, который принимает смещение записи и преобразует его в смещение внутри определенного Сегмент 2 ГБ.

Пока все хорошо ...

Проблемы

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

Изучив 20 или около того вопросов, связанных с «отображением памяти» здесь, на SO, кажется, что вызовы mmap чувствительны к желанию непрерывных прогонов памяти при выделении. Так, например, в 32-битной ОС хоста, если я попытался отобразить файл размером 2 ГБ из-за фрагментации памяти, мои шансы на то, что сопоставление будет успешным, невелики, и вместо этого я должен использовать что-то вроде серии сопоставлений 128 МБ, чтобы вытащить весь файл в формате.

Когда я думаю об этом дизайне, даже с использованием размера mmap 1024 МБ, для СУБД, содержащей несколько огромных баз данных, каждая из которых представлена, скажем, файлами размером 1 ТБ, у меня теперь есть тысячи отображенных в память областей в памяти. и в моем собственном тестировании в Windows 7, пытаясь создать несколько сотен mmaps в файле размером с несколько ГБ, я не просто столкнулся с исключениями, я фактически заставлял JVM segfault каждый раз, когда я пытался выделить слишком много, и в одном случае получил видео на моем компьютере с Windows 7, чтобы вырезать и повторно инициализировать всплывающее окно с ошибкой ОС, которое я никогда раньше не видел.

Независимо от аргумента «вы никогда не будете обрабатывать такие большие файлы» или «это надуманный пример», тот факт, что я мог закодировать что-то подобное с такими побочными эффектами, поднял мою внутреннюю тревогу -alert и заставил рассмотреть альтернативу impl (ниже).

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

Я могу бороться с этим до некоторой степени, увеличивая файл кусками (скажем, 8 МБ за раз) и воссоздавая сопоставление только каждые 8 ​​МБ, но необходимость постоянно воссоздавать эти сопоставления заставляет меня нервничать, особенно без явная функция отмены отображения , поддерживаемая в Java .

Вопрос №1 из 2

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

Но затем я оглядываюсь на окружающий меня ландшафт с такими решениями, как MongoDB, охватывающими файлы с отображением памяти повсюду, и я чувствую, что мне здесь не хватает какого-то основного компонента (я знаю, что он выделяет что-то вроде экстентов 2 ГБ на время,поэтому я предполагаю, что они работают над стоимостью повторного сопоставления с этой логикой И помогают поддерживать последовательные запуски на диске).

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

Альтернативный дизайн

Альтернативный вариант схемы с отображением в память, предложенный выше, который я выберу, если мое понимание mmap верное, выглядит следующим образом:

Определите прямой ByteBuffer объекта разумно настраиваемый размер (примерно 2, 4, 8, 16, 32, 64, 128 КБ), что делает его легко совместимым с любой хост-платформой (не нужно беспокоиться о самой СУБД, вызывающей сценарии сбоя) и используя исходный FileChannel, выполните с определенным смещением читает из 1 фрагмента буферной емкости файла за раз, полностью игнорируя файлы с отображением в память.

Обратной стороной является то, что теперь мой код должен беспокоиться о таких вещах, как «достаточно ли я прочитал из файла, чтобы загрузить полную запись?»

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

Вопрос № 2 из 2

Я надеялся получить подтверждение моего понимания всего этого.

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

Или, может быть, мое понимание чувствительных требований к файлам с отображением в память (непрерывная память) неверно, и я могу все это игнорировать.

21
задан Peter Lawrey 10 April 2016 в 13:36
поделиться