В наших проектах мы использовали ScaleOut StateServer (коммерческий продукт - www.scaleoutsoftware.com ) для выполнения распределенного кэширования / репликации объектов по всей ферме серверов для аналогичных целей. Это было довольно эффективно, хотя использование объектов влечет за собой (де) издержки сериализации, поэтому во многих случаях мы упрощаем то, что храним, до строковых значений, где это возможно.
Мы не полностью оценили Velocity Project, так как наше использование началось до того, как оно существовало, и у нас нет времени или веских причин для рассмотрения вопроса о переходе на этом этапе, но это, очевидно, требует некоторого расследования, если вы только начинаете Теперь.
Редактировать: Я действительно упустил важную часть вопроса - выравнивание ссылок на объекты. Это может быть чрезмерно усложняющим или иметь другие недостатки, но что делать, если вы выбрали более тесную имитацию хранения базы данных в распределенном кеше (сохраняя ее для хранения одной копии каждой отдельной объектной сущности и используя более свободные ссылки для связывания этих сущности вместе)?
Пример: у вас есть класс 'Group', который имеет свойство 'Leader' и коллекцию 'Members', и все они содержат объекты, которые являются экземплярами вашего класса 'Person'. Вы должны будете использовать пользовательскую сериализацию, чтобы выполнить ее, и ничто не сможет волшебным образом решить проблемы параллельного / грязного обновления, но идея в том, что то, что вы поместите в распределенный кеш, на самом деле будут также отдельными экземплярами Person. как поверхностная копия самого экземпляра «Group». Эта поверхностная копия будет сериализовать обычные свойства «Group» (имя и т. Д.), А также уникальные идентификаторы для каждой ссылки «Person», содержащейся в ней (например, исходный идентификатор базы данных, GUID, уникальное имя пользователя или что-то еще, что подходит), а не Человек возражает сам. Таким образом, вместо Leader у вас будет «LeaderID», а коллекция «Члены» будет сериализована в виде списка «MemberID». Каждое упомянутое лицо также сохраняется как отдельный объект; вот где в игру вступает хитрость параллелизма.
При десериализации (или при доступе, в зависимости от моделей использования) поверхностная копия группы будет следовать всем ссылкам на Person ID и повторно гидрировать эти ссылки с реальными объектами Person, которые хранятся отдельно в распределенном кэше. Вам нужно было бы реализовать механизмы блокировки, чтобы убедиться, что обновления этих объектов, которые могут быть использованы многими различными группами, были безопасными. Вам также потребуется механизм контроля версий и «грязная проверка» всякий раз, когда необходимо перечитать / зафиксировать любые изменения объекта Person, сделанные в распределенном кэше.
Это кажется довольно сложным, но это самый общий подход, о котором я мог подумать, не зная специфики вашего варианта использования.