Содержание


Ускорение работы Web-приложений с помощью кэширования

Кэширование часто просматриваемых данных с помощью системы Java Caching System

Comments

Многие Web-приложения создаются путем переписывания приложений для настольных ПК; в идеальном случае Web-приложения должны быть столь же быстрыми и масштабируемыми, как и их «десктопные» версии (для настольных ПК). Скорость работы почти каждого Web-приложения может быть существенно повышена. Кэширование часто просматриваемых данных, которые изменяются достаточно редко, является мощным способом для уменьшения времени ожидания пользователей. Весьма полезным инструментом для достижения этой цели может оказаться утилита, способная легко справляться с кэшированием данных и обладающая простым, неинтрузивным API-интерфейсом. Одним из таких инструментов является система кэширования с открытым исходным кодом JCS, созданная в рамках проекта Apache Jakarta. В данной статье объясняется, как конфигурировать и применять систему JCS для кэширования данных в интересах ваших Web-приложений.

Обзор системы JCS

JCS – это написанная на языке Java система кэширования, которую вы сможете использовать при создании настольных и Web-приложений на Java. Она предоставляет удобные механизмы для хранения данных в кэше, для получения данных из кэша, для удаления данных из кэша и для выполнения многих других задач.

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

Зона в оперативной памяти

Зона кэширования этого типа полностью размещается в оперативной памяти и использует алгоритм замещения LRU (замещение наиболее давнего по использованию элемента). Когда зона кэширования в оперативной памяти заполняется, алгоритм LRU сначала удаляет самые старые кэшированные данные. Этот тип зоны данных демонстрирует хорошую производительность, поэтому большинство пользователей JCS назначает ее в качестве зоны кэширования по умолчанию, которая должна использоваться в первую очередь.

Зона на диске

Зона кэширования этого типа представляет собой зону для хранения кэшированных данных на файловом диске Web-сервера. Для повышения производительности система JCS хранит ключи кэшированных данных в оперативной памяти, а сами кэшированные данные хранит на указанном файловом диске. Если в типичной конфигурации JCS (в которой в первую очередь используется зона в оперативной памяти) какие-либо данные не могут быть размещены в зоне памяти, то они записываются в дисковую зону.

Распределенная зона

Зона кэширования этого типа представляет собой настраиваемый способ для распределения кэшированных данных между несколькими серверами. На каждом из указанных серверов для кэшированных данных должен быть открыт порт для непрерывного прослушивания. Кроме того, с каждым из указанных серверов должно поддерживаться socket-соединение. Применение зоны этого типа может привести к определенной проблеме, поскольку при этом не гарантируется согласованность данных между кэшами. Тем не менее, если эта зона будет использоваться надлежащим образом, то возникновение этой проблемы маловероятно.

Удаленная зона

Удаленная зона кэширования основана на применении программного интерфейса RMI (Remote Method Invocation). При использовании зоны этого типа кэшированные данные хранятся на удаленном сервере. Этот удаленный сервер кэширования может использоваться несколькими приложениями – клиентами системы JCS – для хранения кэшированных данных. Для сбора запросов от клиентов и от серверов задаются так называемые «слушатели» (listener). Удаленная зона кэширования помогает снизить накладные расходы на сериализацию и на поддержание нескольких соединений.

Конфигурирование системы JCS

Для конфигурирования системы JCS достаточно создать и наполнить файл cache.ccf. Этот файл определяет, какие зоны должен использовать ваш кэш, а также атрибуты или опции этих зон. Адаптация этого файла к потребностям вашего приложения представляет собой удобный способ для быстрого масштабирования вашего кэша. Следующие примеры сделаны максимально простыми, чтобы наглядно продемонстрировать важнейшие моменты конфигурирования. Для приведения конфигурации в точное соответствие со своими потребностями вы можете специфицировать ряд опций и атрибутов.

В листинге 1 показан наиболее «базисный» вариант файла cache.ccf – для конфигурации с кэшированием только в оперативной памяти.

Листинг 1. Базовая конфигурация JCS
jcs.default=jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=
 org.apache.jcs.engine.memory.lru.LRUMemoryCache

Как можно увидеть в последней строке конфигурационного файла в листинге 1, кэш в оперативной памяти специфицируется как LRUMemoryCache. Вы также можете увидеть, что в качестве максимального числа объектов, сохраняемых в памяти, указано значение 1000.

Для большинства приложений потребуется более сложная конфигурация системы кэширования, чем показанная в листинге 1. В конфигурации, показанной в листинге 2, я использовал зону в оперативной памяти и дисковую зону, а также задал свою собственную зону (OUR_REGION):

Листинг 2. Задание зон в конфигурации системы JCS
jcs.default=DISK_REGION
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=
  org.apache.jcs.engine.memory.lru.LRUMemoryCache

jcs.region.OUR_REGION=DISK_REGION
jcs.region.OUR_REGION.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.region.OUR_REGION.cacheattributes.MaxObjects=1000
jcs.region.OUR_REGION.cacheattributes.MemoryCacheName=
  org.apache.jcs.engine.memory.lru.LRUMemoryCache
jcs.region.OUR_REGION.cacheattributes.UseMemoryShrinker=true
jcs.region.OUR_REGION.cacheattributes.MaxMemoryIdleTimeSeconds=3600
jcs.region.OUR_REGION.cacheattributes.ShrinkerIntervalSeconds=60
jcs.region.OUR_REGION.cacheattributes.MaxSpoolPerRun=500
jcs.region.OUR_REGION.elementattributes=org.apache.jcs.engine.ElementAttributes
jcs.region.OUR_REGION.elementattributes.IsEternal=false

jcs.auxiliary.DISK_REGION=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory
jcs.auxiliary.DISK_REGION.attributes=
  org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes
jcs.auxiliary.DISK_REGION.attributes.DiskPath=c:/jcs/disk_region
jcs.auxiliary.DISK_REGION.attributes.maxKeySize=100000

Первая строка в листинге 2 показывает, что в этой конфигурации по умолчанию используется дисковая зона DISK_REGION. Зона DISK_REGION имеет тип IndexedDiskCacheFactory, а соответствующий файл на диске специфицирован как c:\jcs\disk_region. Вторая конфигурационная группа в листинге 2 определяет мою собственную зону, для которой я добавил некоторые опции. Этот тип конфигурации – с использованием зоны в оперативной памяти, дисковой зоны и определенной пользователем зоны – является достаточно распространенным. Третья конфигурационная группа в листинге 2 определена как auxiliary region (вспомогательная зона).

Система JCS имеет две зависимости: concurrent и commons-logging. (До появления версии JCS 1.2.7.0 существовали две дополнительные зависимости: commons-collections и commons-lang.)

Основные сведения по применению системы JCS

Хороший способ для изучения основ системы JCS состоит в рассмотрении методов, которые чаще всего используются в ее API-интерфейсе. И наилучшее место для начала такого изучения – инициализация самой зоны кэширования. Инициализация объекта «зона кэширования JCS» позволяет ознакомиться почти со всеми распространенными методами, которые вам понадобятся в дальнейшем. В листинге 3 производится инициализация объекта JCS и получение экземпляра зоны кэширования «по умолчанию».

Листинг 3. Получение зоны кэширования по умолчанию
// Initialize the JCS object and get an instance of the default cache region
JCS cache = JCS.getInstance("default");

После получения экземпляра JCS вы можете вызвать методы, которые необходимы в первую очередь. Метод put помещает новый объект в кэш. Достаточно указать два параметра: key (первый параметр) и value (второй параметр). В листинге 4 показан базовый пример.

Листинг 4. Настройка кэшированного объекта
// Set up
String key = "key0";
String value = "value0";

// Place a new object in the cache
cache.put(key, value);

В этом примере (см. листинг 4) для параметров используются строковые значения, однако вы можете использовать любой объект.

Извлечение кэшированного объекта осуществляется с помощью метода get, предоставленного системой JCS. В листинге 5 показан простой пример, в котором снова использован строковый параметр, однако вы можете использовать любой объект.

Листинг 5. Извлечение кэшированного объекта
// Retrieve a cached object
String cachedData = (String)cache.get(key);

Тестирование кэшированных данных на валидность – это дополнительный метод, который может вам потребоваться при работе с системой кэширования. В системе JCS не определен какой-либо метод тестирования кэша, который позволял бы достаточно просто проверить кэш на существование в нем определенного кэшированного объекта. Однако для решения этой задачи может быть использовано значение, возвращаемое методом get. В листинге 6 показан способ реализации этой необходимой функциональности.

Листинг 6. Тестирование кэшированного объекта на валидность
// Retrieve a cached object
String cachedData = (String)cache.get(key);

// Check if the retrieval worked
if (cachedData != null) {
  // The cachedData is valid and can be used
  System.out.println("Valid cached Data: " + cachedData);
}

Последние из часто используемых утилит кэширования, которые могут вам потребоваться – это утилиты для очистки системы JCS, а именно для удаления кэшированных объектов и для очистки зоны кэша после того как вы закончили работать с этими объектами. JCS предоставляет метод clear для удаления всех кэшированных данных из определенной зоны кэша и метод remove для удаления определенного кэшированного объекта. Кроме того, имеется метод dispose, позволяющий избавиться от определенной зоны JCS, которая была инициализирована ранее. В листинге 7 иллюстрируется использование указанных методов.

Листинг 7. Очистка зоны кэша
// Dispose of a specific cached item
cache.remove(key);

// Dispose of all cache data
cache.clear();

// Dispose of the cache region
cache.dispose();

Система JCS и Java-объекты

Одно из преимуществ JCS по сравнению с другими системами кэширования (см. Похожие темы) состоит в том, что она хорошо работает с объектами. В большинстве Web-приложений, созданных с помощью технологий Java, используется объектно-ориентированный подход. Кэширование объектов позволяет существенно повысить производительность вашего приложения, например по сравнению с вариантом, когда приложению постоянно приходится извлекать объекты из базы данных по частям.

Первый этап проектирования простого объектно-ориентированного Web-сайта на основе системы JCS начинается с объекта, подлежащего хранению. В следующем примере я разрабатываю базовый сайт блоггинга, поэтому мне придется хранить сам объект blog (блог). В листинге 8 показан класс BlogObject, который я буду использовать.

Листинг 8. Класс BlogObject
package com.ibm.developerWorks.objects;

import java.io.Serializable;
import java.util.Date;

public class BlogObject implements Serializable {
  private static final long serialVersionUID = 6392376146163510046L;
  private int blogId;
  private String author;
  private Date date;
  private String title;
  private String content;

  public BlogObject(int blogId, String author, Date date, String title, String content) {
    this.blogId = blogId;
    this.author = author;
    this.date = date;
    this.title = title;
    this.content = content;
  }

  public int getBlogId() {
    return this.blogId;
  }

  public String getAuthor() {
    return this.author;
  }

  public Date getDate() {
    return this.date;
  }

  public String getTitle() {
    return this.title;
  }

  public String getContent() {
    return this.content;
  }
}

После того как вы представили свой объект в виде класса, вам нужен класс для управления им (так называемый «менеджер»). Этот менеджер оперирует всеми административными аспектами и функциями кэширования, связанными с объектами типа blog. В этом примере менеджер выполняет три основных задания:

  • извлечение объектов blog;
  • настройка объектов blog в кэше;
  • очистка кэша от объектов blog.

Метод getBlog, показанный в листинге 9, извлекает объект blog. Сначала этот метод пытается получить объект blog из кэша. Если этот объект отсутствует в кэше, то описываемый метод получит указанный объект с помощью другого механизма.

Листинг 9. Извлечение объекта blog с помощью менеджера блогов
public BlogObject getBlog(int id) {
  BlogObject blog = null;

  try {
    blogCache = JCS.getInstance(blogCacheRegion);
    blog = (BlogObject)blogCache.get(id);
  } catch (CacheException ce) {
    blog = null;
  }

  if (blog == null) {
    blog = DatabaseManager.getBlog(id);
    this.setBlog(
      blog.getBlogId(),
      blog.getAuthor(),
      blog.getDate(),
      blog.getTitle(),
      blog.getContent()
    );
  }

  return blog;
}

В листинге 9 демонстрируется использование базы данных в качестве альтернативного механизма для извлечения объекта. Если вы извлекаете объект с помощью другого механизма, вам следует поместить этот объект в кэш. Это позволит при следующем извлечении получить данный объект непосредственно из кэша.

Метод setBlog, показанный в листинге 10, помещает объект blog в кэш. Этот метод вполне тривиален – он просто создает новый объект blog с переданной в него информацией и затем помещает этот объект в кэш.

Листинг 10. Помещение объекта blog в кэш с помощью менеджера блогов
public boolean setBlog(int bId, String author, Date date, String title, String content) {
  BlogObject blog = new BlogObject(bId, author, date, title, content);

  try {
    blogCache = JCS.getInstance(blogCacheRegion);
    blogCache.put(bId, blog);
    return true;
  } catch (CacheException ce) {
    return false;
  }
}

Метод cleanBlog, показанный в листинге 11, удаляет из кэша один определенный блог или все блоги. Это метод использует методы remove и clear системы JCS для удаления объектов из кэша.

Листинг 11. Удаление объектов blog из кэша с помощью менеджера блогов
public boolean cleanBlog(int blogId) {
  try {
    blogCache = JCS.getInstance(blogCacheRegion);
    blogCache.remove(blogId);
  } catch (CacheException ce) {
    return false;
  }
  return true;
}

public boolean cleanBlog() {
  try {
    blogCache = JCS.getInstance(blogCacheRegion);
    blogCache.clear();
  } catch (CacheException ce) {
    return false;
  }
  return true;
}

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

Метаданные кэша

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

  • имя ключа кэширования;
  • время создания кэшированного объекта;
  • максимальное время жизни кэша;
  • интервал времени до истечения срока жизни кэшированного объекта.

В примере, приведенном в листинге 12, демонстрируется извлечение метаданных по кэшированным объектам.

Листинг 12. Извлечение метаданных по кэшированным объектам
try {
  JCSAdminBean admin = new JCSAdminBean();
  LinkedList linkedList = admin.buildElementInfo(regionName);
  ListIterator iterator = linkedList.listIterator();

  while (iterator.hasNext()) {
    CacheElementInfo info = (CacheElementInfo)iterator.next();
    System.out.println("Key: " + info.getKey());
    System.out.println("Creation Time: " + info.getCreateTime());
    System.out.println("Maximum Life (seconds): " + info.getMaxLifeSeconds());
    System.out.println("Expires in (seconds): " + info.getExpiresInSeconds());
  }
} catch (Exception e) {
}

Метаданные по кэшированным объектам весьма полезны, однако не менее полезны и метаданные по каждой зоне кэша. Эта информация позволяет вам узнать, сколько кэшированных данных поступает в каждую зона кэша, включая число «промахов» (miss), «попаданий» (hit) и обновлений кэша. В примере, приведенном в листинге 13, показано, как осуществляется сбор этой информации.

Листинг 13. Извлечение метаданных по зонам кэша
try {
  JCSAdminBean admin = new JCSAdminBean();
  LinkedList linkedList = admin.buildCacheInfo();
  ListIterator iterator = linkedList.listIterator();

  while (iterator.hasNext()) {
    CacheRegionInfo info = (CacheRegionInfo)iterator.next();
    CompositeCache compCache = info.getCache();
    System.out.println("Cache Name: " + compCache.getCacheName());
    System.out.println("Cache Type: " + compCache.getCacheType());
    System.out.println("Cache Misses (not found): " + compCache.getMissCountNotFound());
    System.out.println("Cache Misses (expired): " + compCache.getMissCountExpired());
    System.out.println("Cache Hits (memory): " + compCache.getHitCountRam());
    System.out.println("Cache Updates: " + compCache.getUpdateCount());
  }
} catch (Exception e) {
}

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

Заключение

JCS – это мощная и в то же время простая в использовании система кэширования для Java-разработчиков. Она обеспечивает кэширование данных как для десктопных приложений, так и для Web-приложений. Распространение Web-приложений, подобных десктопным приложениям, обуславливает необходимость в повышении скорости и динамичности Web-приложений. Кэширование данных помогает решить эту задачу. В данной статье было показано, как конфигурировать и применять систему JCS. Кроме того, я рассмотрел такие вопросы как синтаксис необходимых базовых методов кэширования, кэширование объектов в типичном Web-приложении и извлечение метаданных из кэша. Теперь вы располагаете необходимыми начальными знаниями по системе JCS, позволяющими приступить к разработке вашего следующего Web-сайта, который будет работать быстрее благодаря кэшированию данных. Вы также можете изучить несколько дополнительных тем по системе JCS, посвященных ее расширенным функциональным возможностям (доступ на основе HTTP-сервлетов, утилиты JCS, базовая HTTP-аутентификация и дополнительные вспомогательные зоны).


Ресурсы для скачивания


Похожие темы

  • Оригинал статьи: Build faster Web applications with caching (EN).
  • Java Caching System (EN): официальный Web-сайт по системе JCS.
  • Java Caching System API (EN): документация по API-интерфейсу для системы JCS.
  • Ehcache (EN): Ehcache – еще одна система кэширования общего назначения для Java-приложений.
  • OSCache (EN): OSCache – это система кэширования, специально предназначенная для работы с JSP-контентом.
  • cache4j (EN): простая система кэширования для Java-объектов.
  • IBM Cache Advisor (EN): Cache Advisor – это интеллектуальный консультационный инструмент, генерирующий рекомендации по оптимальному кэшированию.
  • JCS (EN): загрузите JCS.
  • Загрузите ознакомительные версии программных продуктов IBM® (EN) и приобретите опыт работы с инструментами разработки и продуктами связующего уровня семейств DB2®, Lotus®, Rational®, Tivoli® и WebSphere®.

Комментарии

Войдите или зарегистрируйтесь для того чтобы оставлять комментарии или подписаться на них.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java, Open source
ArticleID=377899
ArticleTitle=Ускорение работы Web-приложений с помощью кэширования
publish-date=03232009