Предложение магазина с ключом

Мне нужно очень простое хранилище ключей для java. Я начал с HashMap, но кажется, что HashMap несколько неэффективен (я храню ~ 20 миллионов записей и, кажется, требует ~ 6 ГБ ОЗУ).

Карта Map<Integer,String>, и поэтому я рассматриваю использование GNU Trove TIntObjectHashMap<byte[]> и сохранение значения карты как массива байтов ascii, а не String.

В качестве альтернативы этому существует хранилище ключей, которое требует только добавления файлов jar, не удерживает всю карту в ОЗУ сразу и все еще достаточно быстро?

Ответ 1

Используйте Berkeley DB.

Berkeley DB хранит графы объектов, объекты в коллекциях или простые двоичные данные ключа/значения непосредственно в btree на диске. Этот простой, высокоэффективный подход устраняет все лишние накладные расходы в решениях ORM. Использование Direct Persistence Layer (DPL) Java-разработчики аннотируют классы с информацией о хранении, как JPA. Этот подход является знакомым, эффективным и быстрым. DPL уменьшает сложность хранения данных, не жертвуя скоростью.

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

Ответ 2

BabuDB

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

Лицензия: Новая лицензия BSD, Язык: Java

JDBM2

JDBM2 предоставляет HashMap и TreeMap, которые поддерживаются дисковым хранилищем.

Лицензия: Apache License 2.0, язык: Java

Банановая БД

Banana DB - это автономная база данных ключ/значение, реализованная в Java.

Лицензия: Apache License 2.0, язык: Java


Я пробовал BabuDB и JDBM2, и они отлично работают. BabuDB немного сложнее настроить, но потенциально обеспечивает более высокую производительность, чем JDBM2.

Все эти базы данных, которые позволяют сохранять данные на диске. Существуют также решения для хранения большой карты в памяти (ehcache, hazelcast,...).

Ответ 3

http://www.mapdb.org/ - это то, что вы ищете. Это качающаяся быстрая постоянная реализация java.util.Map.

Функции

Параллельное

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

Быстрый

MapDB обладает выдающейся производительностью, конкурирующей только с собственными БД. Это результат более чем десятилетия оптимизации и перезаписывания.

ACID

MapDB дополнительно поддерживает транзакции ACID с полной изоляцией MVCC. MapDB использует журнал записи-записи или хранилище только для добавления для большей долговечности записи.

Гибкая

MapDB может использоваться повсеместно из кэша в памяти в базе данных с несколькими терабайтами. Он также имеет множество возможностей для повышения долговечности торговли для производительности записи. Это упрощает настройку MapDB в соответствии с вашими потребностями.

взломать

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

SQL Like

MapDB был разработан как более быстрая альтернатива SQL-движку. Он имеет множество функций, облегчающих переход от реляционной базы: вторичные индексы/коллекции, автоинкрементный последовательный идентификатор, объединения, триггеры, составные клавиши...

Низкое использование дискового пространства

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

Ответ 4

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

Apache 2, BTree, Apache Directory Project Замена JDBM:

http://directory.apache.org/mavibot/

MPL2/EPL1, RTree, MVStore, H2 Storage Engine:

http://www.h2database.com/html/mvstore.html

Apache 2, среда Xodus, двигатель JetBrains YouTrack и Hub:

https://github.com/JetBrains/xodus

Ответ 5

Карта Map, поэтому я рассматриваю использование GNU Trove TIntObjectHashMap и сохранение значения карты как массива байтов ascii, а не String.

Это не совсем понятно, потому что TIntObjectHashMap не является Map. Однако подход звучит.


Знаете ли вы, какую экономию пространства я могу ожидать от HashMap для Trove?

Лучший ответ - попробовать.

Но вот некоторые приблизительные оценки (предполагая 32-битную JVM):

  • Ключи HashMap должны быть экземплярами Integer. Они будут занимать ~ 18 байт за экземпляр + 4 байта за ссылку. Всего 24 байта.

  • Ключи Trove будут иметь 4 байта int.

  • Значения строк будут 20 байтов + 12 байтов + 2 * число "символов".

  • Значение байтового массива будет 12 байтов + 1 * число "символов".

  • Я не изучил детали соответствующих внутренних структур данных хеш-таблицы.

Это, вероятно, составляет около 50% экономии памяти, хотя это критически зависит от средней длины значения "строки". (Чем дольше они будут, тем больше они будут доминировать в использовании пространства.)

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

Ответ 6

Рассмотрим Коллекции Koloboke, что в 2 раза быстрее, чем Trove в соответствии с различными тестами:

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


Если вы хотите сохранить карту между запусками JVM с очень быстрым бутстрапом, вас также может заинтересовать Chronicle-Map, в котором хранится String в UTF-8 по умолчанию (так что вы не должны беспокоиться о конверсиях Stringbyte[] как в случае с Koloboke/Trove). "Хроника-карта" является сверхбыстрой для сохраненного хранилища ключей, но немного медленнее, чем "Колобок" и даже "Тве".