Шаблон наблюдателя для операций, выполняемых на карте хроники
Я с нетерпением жду возможности использовать Chronicle Map в качестве хранилища данных / кеша данных и собираюсь поделиться им с другими процессами JVM, работающими в том же блоке, чтобы уменьшить объем памяти каждого из других процессов JVM, иначе каждый процесс JVM будет загружать одни и те же данные. Можно ли получать уведомления о каждом процессе JVM при добавлении или удалении записи из хранилища данных? Это действительно собирается уменьшить объем памяти? Потому что каждый процесс JVM все равно собирается создать несколько доменных объектов.
Я посмотрел на API и документацию, но мне было не совсем понятно, как реализовать мой вариант использования. MapMethods и remoteOperations были ближе всего к этому и, возможно, путь. Я хочу знать, как правильно получить намеченную функциональность или я ухожу.
Если я на правильном пути, то я предполагаю, что mapMethods / remoteOperations нужно предоставлять только на стороне наблюдателя, а не в главном хранилище данных. Я прав?
1 ответ
Это действительно собирается уменьшить объем памяти? Потому что каждый процесс JVM все равно собирается создать несколько доменных объектов.
Да, это. Прежде всего, вы можете использовать шаблон flyweight, чтобы избежать фактической сериализации / десериализации и получить прямой доступ к памяти вне кучи, см. Пример в руководстве Chronicle Map и Chronicle Values.
Но даже если вы сочтете это невозможным или слишком сложным для реализации, вы можете повторно использовать объекты при десериализации объектов для доступа к ним в JVM через map.getUsing()
или лучше в контекстных разделах, где повторное использование объекта происходит автоматически (если сериализаторы типа значения действительно допускают повторное использование объектов).
Но даже если вы не можете повторно использовать объекты-значения, например, потому что они неизменны, как String
, вполне вероятно, что объекты, созданные при десериализации памяти вне кучи, будут недолговечными и не будут продвигаться из молодого поколения, и GC будет эффективно их собирать, и вы эффективно будете использовать память. Если у вас есть карты для каждой JVM, каждая копия постоянно находится в памяти, которая не используется повторно.
Таким образом, в любом случае, наличие Chronicle Map, совместно используемой JVM, является хорошей вещью для общего использования памяти в машине и, следовательно, для производительности.
Можно ли получать уведомления о каждом процессе JVM при добавлении или удалении записи из хранилища данных?
Это не возможно из коробки в версии с открытым исходным кодом. Можно заказать такую функцию. То же самое касается удаленных операций, которые вы упомянули, эта функция больше не поддерживается открытыми исходными кодами. Однако remoteOperations не совсем то, что вам нужно для вашего случая.
РЕДАКТИРОВАТЬ Обратите внимание, что в зависимости от ваших требований к пропускной способности и частоты обновления вы можете относительно легко реализовать это самостоятельно, скопировав созданные вами изменения в Chronicle Map в многоадресную IPC, такую как Chronicle Queue или Aeron IPC, и затем прочитав их в других JVM. Вы можете скопировать только обновленные ключи, без значений.
Это решение может быть хуже (или даже не работать), чем то, что Chronicle Map может предоставить "изначально", если частота обновлений вашей карты настолько высока (100 тысяч обновлений в секунду и выше), что вы не можете реально обработать все обновления и естественным образом ограничить события, забыв устаревшие обновления некоторых ключей, когда новые обновления для того же ключа уже были сделаны. Но в вашем случае это может быть совсем не нужно.
MapMethods и remoteOperations были ближе всего к этому и, возможно, путь. Я хочу знать, как правильно получить намеченную функциональность или я ухожу.
MapMethods преследует узкую цель - переопределение имплементаций по умолчанию Map
методы, использующие контексты Chroncile Map и операции более низкого уровня. Это не имеет ничего общего с удаленным общением, событиями и прослушиванием. Вы можете переопределить MapMethods.put()
например, добавить запись в журнал или уведомление о событии, но вы можете сделать это, войдя в систему или уведомив после каждого вызова chronicleMap.put()
с почти такими же результатами.
RemoteOperations позволяет переопределить действие, которое должно произойти, когда запись помещается / удаляется / обновляется на каком-либо узле, и это событие поступает на другой узел. По умолчанию событие воспроизводится на узле-получателе, если его отметка времени позже, чем отметка времени последнего обновления записи с ключом события в узле-получателе, то есть "выигрывает последняя запись". Но его можно переопределить, чтобы определить разные стратегии, т. Е. Если значение содержит некоторое количество, записывается значение с наибольшим числом.