Спящий режим кэша второго уровня в приложении Grails
Часть I
В приложении Grails я понимаю, что вы включили кеш второго уровня на класс домена, добавив
static mapping {
cache true
}
По умолчанию кеш второго уровня используется только тогда, когда вызывается get()
, но его также можно использовать для запросов критериев и динамических искателей, добавляя cache true
к запросу.
Однако я все еще не уверен, что понимаю, как работает кеш запросов. Мое лучшее предположение:
- существуют отдельные кеши запросов для каждого класса домена, например. один для книги и другой для автора.
- до того, как будет выполнен запрос типа
Author.findByName('bob', [cache: true])
, будет вычислен ключ кеша, основанный на классе домена (автор), запросе (findByName) и параметрах запроса ( "bob" ). Если этот ключ находится в кэше запросов автора, результаты кэширования возвращаются вместо выполнения запроса
- в любое время, когда Автор сохраняется, удаляется или обновляется, кеш запросов авторизации
Это кажется разумным, пока мы не рассмотрим, что запрос, возвращающий экземпляры Book, может присоединиться к таблице Author. В этом случае необходимо будет очистить кеширование запросов книги и автора, когда автор будет сохранен, удален или обновлен. Это заставляет меня подозревать, что, возможно, есть только один кеш запросов, и он очищается всякий раз, когда сохраняется какой-либо класс кэшированного домена?
Часть II
В документах Grails упоминается, что
Помимо возможности использования кэша второго уровня Hibernate для кэширования экземпляров вы также можете кэшировать коллекции (ассоциации) объектов.
Например:
class Author {
static hasMany = [books: Book]
static mapping = {
cache true // Author uses the 2nd level cache
books cache: true // associated books use the 2nd level cache
}
}
class Book {
static belongsTo = [author: Author]
static mapping = {
cache true // Book uses the 2nd level cache
}
}
Имеет ли смысл конфигурация выше, т.е. если автор и книга сами используют кеш второго уровня, есть ли какая-то польза от того, чтобы ассоциация Author-Book также использовала кеш второго уровня?
Часть III
Наконец, я прочитал этот совет об использовании кэша запросов 2-го уровня, что говорит о том, что его следует использовать только для редко меняющихся классов домена. Существуют ли какие-либо обстоятельства, при которых не следует включать кеш второго уровня для операций get()
, то есть любую причину, по которой нельзя добавить следующее в класс домена
static mapping = {
cache true // Book uses the 2nd level cache
}
Ответы
Ответ 1
Часть 1:
Спящий режим делает правильные вещи. Кэш запросов не относится к сущности. Существует один регион кеша запросов, общий для всех запросов, если вы не задали конкретный регион для запроса. Каждый раз, когда таблица обновляется, ее метка времени в кеше timestamps обновляется. Каждый раз, когда выполняется запрос, метка времени каждой таблицы, в которой выполняется поиск запроса, сравнивается с меткой времени кэшированного результата. И, конечно же, кешированный результат возвращается, только если itstimestamp более поздняя, чем все временные метки таблицы.
Часть 2:
Да, это имеет смысл. Кэш для автора помнит, что автор с идентификатором 456 имеет имя "foo" и дату рождения 1975/07/19. Запомнены только данные, хранящиеся в таблице автора. Итак, кеширование ассоциации также полезно: вместо того, чтобы сделать дополнительный запрос для получения набора книг автора при вызове author.getBooks()
, Hibernate получит идентификаторы книг автора из своего кеша, а затем загрузит каждую книгу из кеша второго уровня. Однако убедитесь, что кешируют книги.
Часть 3:
Я могу представить несколько причин:
- существует так много сущностей, и они настолько меняются, что количество обращений к кешу будет очень низким, и что обработка кэша второго уровня фактически будет потреблять больше времени и памяти, чем решение без кеша
- приложение кластеризовано, а стоимость и сложность распределенного кеша второго уровня слишком велика, для низкого коэффициента усиления
- другие приложения, не связанные с гибернацией, записываются в одну и ту же базу данных, поэтому кэш имеет большой риск возврата устаревших данных, что неприемлемо.
- все идет отлично, без кэша второго уровня, и нет никаких причин сделать приложение более сложным, чем оно есть.