Что является лучшим вариантом для многоуровневого внутрипроцессного кэша?
В моем весеннем загрузочном приложении мне нужно реализовать внутриуровневый многоуровневый кеш. Вот пример данных, которые необходимо кэшировать:
имя клиента (ключ, строка) - имя объекта данных (ключ, строка) --config-1 (значение, JSONObject) --config-2 (значение, JSONObject)
Я планирую иметь несколько сотен записей о клиентах, каждая из которых имеет до ста "конфиг" JSONObjects
Я сейчас смотрю на ehcache:
Cache cache = manager.getCache("sampleCache1");
Element element = new Element("key1", "value1");
cache.put(element);
В этом контексте я бы использовал "Customer_Name" вместо "key1" и "My Customer" вместо "value1", но из них мне нужно было бы построить иерархию:
customer
-data entity
-config
Я не уверен, как это сделать с ehcache. Я также не уверен, есть ли лучший выбор для того, что я пытаюсь сделать.
Кто-нибудь реализовал такой многоуровневый иерархический кеш с помощью ehcache или любой другой библиотеки?
1 ответ
Для обозначения я использую кэш, похожий на карту: value = Cache.get(key)
что более распространено, чем EHCache2 Element
Вариант 1. Построить составной ключевой объект
class CustomerConfigurationKey {
String customerKey;
String dataEntityKey;
// equals() and hashCode()
}
Это довольно стандартные хранилища ключей / значений, включая простые карты. Я сделал это в cache2k Quick Start.
Вариант 2: использовать несколько уровней кэшей
Поместите кеш в кеш и получите доступ к: data.get(customerKey).get(dataEntityKey)
,
Вы можете найти примеры "составного ключа" и "многоуровневого кэша" в тестах cache2k DateFormattingBenchmark
Это хорошо работает, только если у вас есть небольшой сет на первом уровне. В вашем случае у вас будет отдельный кеш для каждого клиента, который будет дорогостоящим. Таким образом, это только для полноты, никакой реальной опции в вашем сценарии.
Вариант 3: использовать карту для второго уровня
Создайте один кеш с Cache<String, Map<String, JSONObject>
,
Если обычно все данные клиента используются за короткий промежуток времени, не имеет смысла кэшировать на более тонком уровне, так как все данные клиента в любом случае обычно находятся в памяти. Другой пример: когда клиент больше не активен, срок действия кэша истекает, и все данные клиента могут быть удалены из памяти.
При обновлении отдельных записей карты будут возникать проблемы с параллелизмом, которые необходимо правильно решить, например, путем копирования и помещения только неизменяемой карты в кэш или использования ConcurrentHashMap
,