Как реализовать кэширование для веб-приложения - PullRequest
6 голосов
/ 05 марта 2011

Каковы различные способы кэширования данных веб-приложения, разработанные с использованием баз данных Java и NoSQL?Базы данных также обеспечивают кэширование, являются ли они единственным и всегда лучшим вариантом для кэширования?

Как еще можно кэшировать мои данные пользователей в приложении.Приложение содержит очень специфичные для пользователя данные, как в социальной сети.Существуют ли простые правила большого пальца того, что нужно кэшировать?

Могу ли я также кэшировать свои данные на сервере приложений с использованием Java?

Ответы [ 2 ]

25 голосов
/ 06 марта 2011

Если вам нужно практическое правило, вот что сказал Майкл Джексон (не , что Майкл Джексон):

  1. Первое правило оптимизации программы: Не делай этого .
  2. Второе правило оптимизации программы (только для экспертов!): Пока не делайте .

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

Что касается вещей, которые вы можете кэшировать, это все что угодно, но я полагаю, вы можете классифицировать их на три группы:

  1. Вещи, которые пришли из базы данных. Их легко кэшировать, потому что в тот момент, когда вы переходите в базу данных, у вас есть идентифицирующая информация, которая вам понадобится для ключа кэша (первичный ключ, параметры запроса и т. Д.). Кэшируя их, вы экономите время, затрачиваемое на их получение из базы данных - это требует ввода-вывода, поэтому оно может быть довольно большим.
  2. Вещи, которые были получены с помощью вычислений в модели предметной области (возможно, новостные ленты в социальном приложении). Это может быть сложнее для кэширования, потому что больше контекстной информации идет на их создание; вам может потребоваться рефакторинг вашего кода, чтобы создать единую точку, в которой вся необходимая информация находится под рукой, чтобы вы могли применить к ней кеширование. Или вы можете обнаружить, что это уже существует. Их кэширование сохранит весь доступ к базе данных, необходимый для получения информации, которая используется для их создания, а также все вычисления; время, затрачиваемое на вычисления, может или не может быть существенным дополнением ко времени, затрачиваемому на ввод-вывод. Отказаться в кэшировании подобных вещей, вероятно, будет гораздо сложнее, чем чистые объекты базы данных.
  3. Вещи, которые отправляются в браузер - страницы или фрагменты страниц. Они могут быть довольно легко кэшироваться, потому что в правильно разработанном приложении они однозначно идентифицируются либо по URL, либо по комбинации URL и пользователя. Кеширование этих данных сохранит все вычисления в вашем приложении; он может даже избежать обслуживания запросов, потому что это может быть сделано с помощью обратного прокси , расположенного перед вашим сервером приложений. Две проблемы. Во-первых, он использует огромный объем памяти: страница, отображаемая из нескольких килобайт объектов, может иметь размер в десятки или сотни килобайт (моя домашняя страница в Facebook имеет размер 50 кБ). Это означает, что вам нужно сохранить огромное количество вычислений, чтобы сделать его более выгодным, чем кэширование на уровнях базы данных или модели предметной области, и просто не так много вычислений между моделью предметной области и HTML в разумно разработанном приложении. Во-вторых, аннулирование еще сложнее, чем в модели предметной области, и, скорее всего, это будет происходить слишком часто - все, что изменяет страницу или фрагмент, должно аннулировать кэш.

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

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

7 голосов
/ 06 марта 2011

Я предполагаю, что вы создаете относительно типичное веб-приложение, которое:

  1. имеет один сервер, используемый для персистентности
  2. несколько веб-серверов
  3. связывает аутентифицированных пользователей с одним сервером через липкие сессии через балансировщик нагрузки

Теперь, с этим заявлено, чтобы ответить на ваши вопросы. Большинство систем хранения данных, баз данных или NoSQL, вероятно, имеют встроенное кеширование, которое позволяет многократно выполнять один и тот же простой запрос (например, поиск по первичному ключу) и кешировать результат. Однако, чем сложнее запрос, тем меньше вероятность его кэширования. Кроме того, если существует только один сервер для постоянства (то есть нет разделения или записи master / read slave), он быстро становится узким местом. Таким образом, кэширование на уровне приложений, которое вы хотите делать, обычно должно происходить на веб-серверах, чтобы уменьшить нагрузку на базу данных.

Что касается того, что следует кэшировать, эвристика - это элементы, к которым часто обращаются и / или которые требуют больших затрат (с точки зрения обработки / памяти базы данных / веб-сервера). Типичными кандидатами являются домашняя страница и любая другая целевая страница сайта - часто лучшим подходом для этого является создание статического файла и его обслуживание. Следующие фрагменты зависят от вашего приложения, но обычно наиболее эффективная стратегия - кэширование как можно ближе к конечному результату - часто к HTML. Для вашей социальной сети это может быть список рекомендуемых обновлений или что-то подобное.

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

Теперь последнее, что нужно рассмотреть, - это недействительность кэша, и это действительно трудная часть всего этого ( именование - другая сложная вещь в информатике ). В этом случае использование чего-то вроде memcached или ehcache, как уже упоминали другие, является правильным подходом. ehcache может легко работать в процессе работы с вашим Java-приложением и хорошо справляется с истечением срока действия, с политиками для наименее недавно использованных и наименее часто используемых и позволяя вам использовать как память, так и диск для кэширования. Вам нужно подумать о ситуациях, когда вам нужно закончить что-то из кэша раньше этого графика, потому что данные изменились. В этом случае вам нужно проработать эти зависимости в архитектуре вашего приложения, чтобы оно считывало / записывало в кеш соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...