Главная » Spring » Кеширование Spring

0

Во многих приложениях данные читаются значительно чаще, чем записываются. В нашем приложении RoadRantz, например, боль- шинство посетителей сайта заинтересованы в получении той или иной информации, чем в написании собственных сообщений. Хотя, безусловно, список сообщений со временем будет расти, но просмат- риваться он будет все же значительно чаще.

Кроме того, данные, представляемые приложением RoadRantz, не так чувствительны ко времени. Если посетитель увидит немного устаревший список сообщений, у него не сложится отрицательного впечатления. В конечном счете они смогут вернуться на сайт позд- нее и увидеть обновленный список сообщений.

Всякий раз, когда запрашивается список сообщений, объект DAO обращается к базе данных и запрашивает последние данные (чаще всего те же, что были на момент последнего обращения).

Операции с базами данных нередко являются наиболее узким местом в приложениях с точки зрения их производительности. Даже самые простые запросы к самым оптимизированным хранилищам данных могут добавить проблем производительности в высокона- груженном приложении.

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

На первый взгляд решение проблемы кеширования данных вы- глядит достаточно просто: после получения некоторой информации сохранить ее, чтобы в дальнейшем было возможно обратиться к ней. Однако реализация кеша может показаться довольно трудоемкой. Например, взгляните на реализацию метода getRantsForDay() класса HibernateRantDao.

public  List<Rant>  getRantsForDay(Date  day)  {

return  getHibernateTemplate().find("from  "  +  RANT  + "  where  postedDate  =  ?",  day);

}

Метод getRantsForDay() является идеальным кандидатом для реа- лизации кеширования в нем, поскольку нет способа вернуться в прошлое и добавить сообщение задним числом. Если запрашива- ется список на текущий день, то он неизменен. Таким образом, не имеет никакого смысла каждый раз обращаться к базе данных за списком сообщений, которые были размещены, скажем, в прошлый вторник. Запрос к базе данных должен выполняться только раз, и тогда мы сможем запомнить данные, чтобы вернуть их, когда они потребуются снова.

Теперь изменим метод getRantsForDay(), добавив в него поддержку доморощенного кеша:

public   List<Rant>   getRantsForDay(Date   day)   { List<Rant>   cachedResult   =

rantCache.lookup("getRantsForDay", day); if(cachedResult  !=  null)  {

return cachedResult;

}

cachedResult  =  getHibernateTemplate().find("from  "  +  RANT  +

" where postedDate = ?", day); rantCache.store("getRantsForDay",  day,  cachedResult);

return  cachedResult

}

Эта версия метода getRantsForDay() выглядит гораздо более не- уклюжей. Главная цель метода getRantsForDay() – в том, чтобы най- ти сообщения, относящиеся к указанному дню, но большая часть метода реализует кеширование. Кроме того, наша реализация не предусматривает решения некоторых проблем, связанных с кеши- рованием, таких как истечение срока хранения информации в кеше, сброс кеша и обработка его переполнения.

К счастью, в Spring доступно гораздо более элегантное решение кеширования. Проект Spring Modules (http://springmodules.dev.java. net) обеспечивает поддержку кеширования через аспекты. Вместо того чтобы предусматривать явную реализацию кеширования в ме- тодах, аспекты кеширования Spring Modules предоставляют возмож- ность применять советы к методам компонентов, обеспечивающие прозрачное кеширование результатов.

Как показано на рис. 6.5, поддержка кеширования в Spring вклю- чает в себя прокси-объект, который перехватывает вызовы к одному или нескольким методам компонентов, управляемых фреймворком Spring. При вызове метода прокси-объекта модуль Spring Modules Cache сначала проверяет, вызывался ли этот метод прежде с теми же аргументами. Если вызывался, то фактический метод не вызывается

Рис. 6.5. Модуль кеширования Spring Modules перехватывает вызовы методов компонента и отыскивает данные,

чем обеспечивает более высокую скорость доступа к данным в сравнении с медленными запросами к базе данных

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

В этом разделе мы добавим поддержку кеширования в слой досту- па к данным для приложения RoadRantz с помощью модуля Spring Modules Cache. Это обеспечит нашему приложению более высокую производительность и даст заслуженный отдых базе данных.

Источник:   Уоллс К., Spring в действии. – М.: ДМК Пресс, 2013. – 752 с.: ил.

По теме:

  • Комментарии