Шаблон наблюдателя для операций, выполняемых на карте хроники

Я с нетерпением жду возможности использовать Chronicle Map в качестве хранилища данных/кеша данных и намереваюсь поделиться им с другими процессами JVM, работающими в том же блоке, чтобы уменьшить объем памяти, занимаемой каждым из других процессов JVM, иначе каждый процесс JVM будет загружать одни и те же данные. Можно ли получать уведомления о каждом процессе JVM всякий раз, когда запись добавляется или удаляется из хранилища данных? Действительно ли это уменьшит объем памяти? Потому что каждый процесс JVM в любом случае будет создавать какие-то объекты предметной области.

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

Если я на правильном пути, то я предполагаю, что mapMethods/remoteOperations нужно предоставлять только на стороне наблюдателя, а не в основном хранилище данных. Я прав?


person chauhraj    schedule 08.06.2016    source источник


Ответы (1)


Действительно ли это уменьшит объем памяти? Потому что каждый процесс JVM в любом случае будет создавать какие-то объекты предметной области.

Да, это так. Прежде всего, вы можете использовать шаблон легковеса, чтобы избежать фактической сериализации/десериализации и получить прямой доступ к памяти вне кучи, см. of-boxed-primitives" rel="nofollow">пример в учебнике по карте хроники и Значения хроники .

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

Но даже если вы не можете повторно использовать объекты-значения, например. грамм. поскольку они неизменяемы, как String, вполне вероятно, что объекты, созданные при десериализации памяти вне кучи, будут недолговечными и не будут продвигаться из молодого поколения, а GC будет эффективно собирать их, и вы будете эффективно повторно использовать память. В то время как если у вас есть карты для каждой JVM, каждая копия постоянно находится в памяти, которая не используется повторно.

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

Можно ли получать уведомления о каждом процессе JVM всякий раз, когда запись добавляется или удаляется из хранилища данных?

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

РЕДАКТИРОВАТЬ Обратите внимание, что в зависимости от ваших требований к пропускной способности и частоте обновлений вы можете относительно легко реализовать это самостоятельно, скопировав обновления, которые вы вносите в Chronicle Map, в многоадресный IPC, например Chronicle Queue или Aeron IPC, а затем читать их в других JVM. Вы можете копировать только обновленные ключи, без значений.

Это решение может быть хуже (или даже неработоспособным), чем то, что Chronicle Map может предоставить «изначально», если частота обновления вашей карты настолько высока (сотни тысяч обновлений в секунду и выше), что вы не можете обрабатывать все обновления и хотите чтобы естественным образом регулировать события, забывая об устаревших обновлениях некоторых ключей, когда более новые обновления того же ключа уже были сделаны. Но в вашем случае это может быть вообще не нужно.

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

MapMethods нацелен на узкую цель - переопределение реализации по умолчанию методов Map с использованием контекстов Chroncile Map и операций более низкого уровня. Это не имеет ничего общего с дистанционным общением, событиями и прослушиванием. Вы можете переопределить MapMethods.put() e. грамм. чтобы добавить ведение журнала или уведомление о событии, но вы можете сделать это, регистрируя или уведомляя после каждого вызова chronicleMap.put() с почти такими же результатами.

RemoteOperations позволяют переопределить действие, которое должно произойти, когда запись помещается/удаляется/обновляется на каком-то узле, и это событие поступает на другой узел. По умолчанию событие воспроизводится повторно на узле-получателе, если его временная метка позже, чем временная метка последнего обновления для записи с ключом события в узле-получателе, т.е. е. "Последняя запись побеждает". Но его можно переопределить, чтобы определить разные стратегии, т.е. е. если значение содержит некоторое количество, записывается значение с наибольшим количеством.

person leventov    schedule 08.06.2016
comment
Один из моих коллег написал прототип и обнаружил, что в настоящее время мой вариант использования не поддерживается «из коробки». Однако у меня возникла та же идея, что и вы предложили, - использовать ChronicleQueue (CQ) для публикации обновлений для других процессов JVM. Кажется, что я могу использовать entryOperations для публикации событий в CQ, а процессы JVM могут читать из CQ. - person chauhraj; 09.06.2016
comment
Да, входные операции подходят для этого вполне. - person leventov; 09.06.2016