Это похоже на длинный вопрос из-за всего контекста. В романе есть два вопроса. Спасибо, что нашли время, чтобы прочитать это и оказать помощь.Memory-Mapped MappedByteBuffer или Direct ByteBuffer для реализации БД?
Ситуация
Я работаю на масштабируемой реализации хранилища данных, которая может поддерживать работу с файлами данных от нескольких килобайт до туберкулеза или более размеров в системе 32-разрядной или 64-разрядной.
В хранилище данных используется схема копирования на запись; всегда добавляя новые или измененные данные в конец файла данных и никогда не делая на месте редактирования существующих данных.
В системе может располагаться 1 или более база данных; каждый из которых представлен файлом на диске.
Детали реализации не важны; единственной важной деталью является то, что мне нужно постоянно добавлять файл и расширять его с КБ, до МБ, до ГБ до ТБ и в то же время случайным образом пропускать файл для операций чтения, чтобы отвечать на запросы клиентов.
Первоклассники Мысли
На первый взгляд, я знал, что я хотел бы использовать отображаемые в памяти файлы, так что я мог бы подтолкнуть бремя эффективно управлять государством в памяти данных на хост-ОС и из мой код.
Затем весь мой код должен беспокоиться о том, чтобы сериализовать операции добавления в файл на запись и разрешить любому числу одновременных читателей искать в файле ответы на запросы.
Дизайн
Поскольку отдельные данные-файлы могут расти за пределами 2 Гб в MappedByteBuffer, я ожидаю, что мой проект будет включать уровень абстракции, который принимает смещение от записи, и преобразует его в смещение внутри определенного сегмента 2 ГБ.
До сих пор так хорошо ...
Проблемы
Это где я начал зацикливаться и думать, что происходит с другим дизайном (предложенной ниже) может быть лучшим способом сделать это.
Из приблизительно 20 или около того вопросов, связанных с памятью, здесь, на SO, кажется, что вызовы mmap чувствительны к желанию непрерывных прогонов памяти при распределении. Так, например, на 32-битной ОС хоста, если я попытался создать файл размером 2 ГБ, из-за фрагментации памяти, мои шансы тонкие, что сопоставление будет успешным, и вместо этого я должен использовать что-то вроде серии из 128 МБ-сопоставлений, чтобы вытащить целую файл в.
Когда я думаю, что дизайн, даже сказать, используя размеры 1024MB MMAP для СУБДА хостинг до нескольких огромных баз данных все представленный, скажем, на 1 ТБ файлов, у меня теперь есть тысяч из памяти отображенных областей в памяти и в моем собственном тестировании на Windows 7, пытаясь создать несколько сотен mmaps в файле с несколькими GB, я не просто столкнулся с исключениями, я фактически получил JVM для segfault каждый раз, когда я пытался выделить слишком много и в одном случае получил видео на моей машине Windows 7, чтобы вырезать и повторно инициализировать с помощью всплывающего окна OS-error, которое я никогда раньше не видел.
Независимо от аргумента «вы никогда не будете обрабатывать файлы с большими» или «это надуманный пример», тот факт, что я мог бы что-то кодировать с таким типом побочных эффектов, с высокой готовностью и рассмотрением альтернативных вариантов (ниже).
BESIDES, которые выдают, мое понимание файлов с отображением памяти заключается в том, что я должен повторно создавать сопоставление при каждом росте файла, поэтому в случае этого файла, который добавляется только в дизайне, он буквально постоянно растет.
Я могу в какой-то мере побороть это, увеличив файл в кусках (скажем, 8 Мбайт за раз) и только заново создаст сопоставление каждые 8 МБ, но необходимость постоянно воссоздавать эти сопоставления заставит меня нервничать, особенно с нет явно unmap feature supported in Java.
Вопрос № 1 из 2
Учитывая все мои выводы до этого момента, я уволит памяти файлы, отображенные как хорошее решение для в первую очередь для чтения тяжелых решений или только для чтения решений, но не пишут тяжелые решения, учитывая необходимость постоянно воссоздавать отображение.
Но затем я оглядываюсь вокруг ландшафта вокруг меня с такими решениями, как MongoDB, охватывающие файлы с отображением памяти повсюду, и я чувствую, что у меня отсутствует какой-то основной компонент здесь (я знаю, что он выделяет что-то вроде 2 ГБ экстентов при время, поэтому я предполагаю, что они работают с стоимостью повторной карты с этой логикой и помогают поддерживать последовательные прогоны на диске).
На данный момент я не знаю, является ли проблема отсутствием Java-операции unmap, которая делает это намного более опасным и непригодным для моих целей или если мое понимание неверно, и кто-то может указать мне на север.
Альтернативный дизайн
Альтернативный дизайн отображенного в память предложенному выше, что я пойду с, если мое понимание ттар правильно выглядит следующим образом:
Определение a direct ByteBuffer разумного настраиваемым размером (2, 4, 8, 16, 32, 64, 128 КБ), что делает его легко совместимым с любой платформой хоста (не нужно беспокоиться о том, что сама СУБД вызывает сценарии переполнения) и используя оригинальный FileChannel, выполните specific-offset reads файла 1 объем памяти-буфера одновременно, полностью отменяя файлы с отображением памяти.
Недостатком является то, что теперь мой код должен беспокоиться о таких вещах, как «Я достаточно читал из файла, чтобы загрузить полную запись?»
Другой недостаток заключается в том, что я не могу использовать логику виртуальной памяти ОС, позволяя ей автоматически сохранять более «горячие» данные в памяти; вместо этого мне просто нужно надеяться, что логика кэша файлов, используемая ОС, достаточно велика, чтобы сделать что-то полезное для меня здесь.
Вопрос № 2 из 2
Я надеялся получить подтверждение моего понимания всего этого.
Например, возможно, кеш-файл является фантастическим, что в обоих случаях (отображение в память или прямое чтение) операционная система будет поддерживать как можно больше моих горячих данных, а разница в производительности для больших файлов незначительна.
Возможно, мое понимание чувствительных требований к файлам с отображением памяти (непрерывная память) неверно, и я могу игнорировать все это.
Если вы получили некоторое представление, так как задавать свой вопрос, пожалуйста, напишите их как ответ. Многие люди читали этот вопрос, и они могли использовать проницательность. Там тонна «не исправит» ошибки вокруг mmapping, как http://bugs.sun.com/view_bug.do?bug_id=6893654 (хотя JVM segfault и сбой графического драйвера еще хуже!) Интересно, как просто , элегантная собственная функция становится сложной и уродливой в управляемом мире. –
@AleksandrDubinsky вы совершенно правы (об элегантном становлении inelegant) - мои окончательные результаты заключаются в том, что файлы mmap'ed не могут быть созданы быстро, не введя значительную нестабильность в систему (я не знаю, прояснился ли я в этой теме, но Мне удалось синей экранной машиной windows dev). Эта деталь ALONE заставила меня хотеть придерживаться использования AsyncFileChannel для ввода/вывода файлов и избегать mmap все вместе, хотя Питер (ниже) имел значительный успех в Chronicle. –
@AleksandrDubinsky Как только я смог привести VM и мою машину в колени с очевидным «неправильным использованием» mmapped-файлов, я покончил с этим путем. Они элегантны и предлагают фантастическую производительность, но из большего количества чтения, которое я сделал в AsyncFileChannel, кажется, что вы можете приблизиться к той же производительности (позволяя ОС использовать FS и контроллер диска и порядок ввода-вывода для оптимизации запросов). Если вы действительно хотите спуститься по пути mmap, то здесь Питер. –