Управление кешированием - PullRequest
15 голосов
/ 10 ноября 2009

Просто интересно, как вы, ребята, справляетесь с недействительными кеша. Учитывая, что в кэше могут находиться объекты (сотни и тысячи), которые могут запускаться различными алгоритмами или правилами. Как вы все это отслеживаете?

Можно ли в любом случае ссылаться на отношения из таблицы в базе данных и как-то применять ее?

Терпите меня, потому что я никогда раньше не занимался кешированием.

Ответы [ 7 ]

12 голосов
/ 16 ноября 2009

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

Для этого у вас есть два решения:

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

Первый довольно редкий, но с ним довольно легко справиться: просто регулярно обновляйте кеш.

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

  • Добавление нового объекта в кэш сразу после его успешного добавления в базу данных.
  • Обновите объект в вашем кэше сразу после того, как вы успешно обновили его в своей базе данных.
  • Удалить объект из вашего кэша сразу после того, как вы успешно удалили его в своей базе данных.

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

10 голосов
/ 20 ноября 2009

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

Самый простой способ сделать это - связать все связанные объекты. Ранее я использовал концепцию кеш групп . Продолжая мой пример новостей, в группе cache 'news' будет; новости, различные списки новостей и все остальное, что содержит новости.

Когда я редактирую новость, система распознает, что ей нужно обновить группу кэша 'news', и проходит следующий процесс ...

  1. получить каждый объект перед сохранением обновлений
  2. сохранить
  3. получить объект снова, если это другое обновление, различные кэши

Это очень простой пример, конечно. Гораздо более аккуратный способ сделать это - написать свой код, чтобы всегда поддерживать объект таким, каким он был бы в кеше.

Если вы добавите тег в новостную статью, то код, который вы написали, может просто записать эти изменения в базу данных, но если вместо этого вы обновите объект новостной статьи и соответствующий объект тега, оба эти объекта могут «узнать», что они изменились (так просто в качестве настройки hasChanged = true), а затем вы можете обновить кэш и автоматически сохранить его в базе данных.

3 голосов
/ 08 октября 2012

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

Если obj B является внешним ключом obj A и некоторые свойства A изменяются, вам также необходимо обновить кэш B.

В древовидной структуре, если выявлено изменение в "ветви", обновите кэш всех "листьев". Или, если «корень» обновлен, обновите кеш всех «веток» + «уйдет» полностью вниз. Подумайте об иерархии.

3 голосов
/ 18 ноября 2009

Если вы используете SQL Server 2005 или более позднюю версию и .NET, вы можете захотеть использовать SQLDependency класс . Этот класс использует SQL Server Service Broker, чтобы уведомить вас, когда в ваших данных произошли определенные изменения. Вы можете использовать это как триггер для аннулирования вашего кэша. Опять же, это применимо, только если вы используете эти технологии.

2 голосов
/ 11 ноября 2009

См. Эту статью и связанные с ней Вопрос переполнения стека .

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

0 голосов
/ 20 ноября 2009

Просто интересно, как вы, ребята, справляетесь с недействительными кеша. Учитывая, что в кэше могут находиться объекты (сотни и тысячи), которые могут запускаться различными алгоритмами или правилами. Как вы все это отслеживаете?

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

Можно ли в любом случае ссылаться на отношения из таблицы в базе данных и как-то применять ее?

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

Терпите меня, потому что я никогда раньше не занимался кешированием.

В зависимости от сложности ваших потребностей, это может быть непростой задачей. Может быть, вы должны использовать или посмотреть на существующие решения. В мире Java EHCache , OSCache , SwarmCache , JBoss Cache 2 делают недействительными кэши (или поддерживают Это). Это всего лишь предложение, поскольку вы не упомянули ни одного языка.

0 голосов
/ 16 ноября 2009

Общие решения вы можете посмотреть по ссылке, предоставленной Juha.

Но, следуя вашему вопросу, я бы хотел рассказать, как это делается в нашем проекте.
Мы не используем какое-либо общее решение для кэшей. Наш кеш со временем вырос. Изначально мы не собирались использовать кеш вообще. Но позже кеш родился. Поскольку кеш был добавлен в систему в последнее время, он не знает ни о какой «базе данных» или других «умных вещах». Вместо этого мы тщательно проверяем, меняет ли кто-нибудь кеш. Итак, я бы назвал наш кэш «управляемым алгоритмом».

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

Я знаю, описывать такие основные функции может показаться глупым. Можно сказать, что «в первую очередь нам пришлось использовать обычный кеш». Но вы знаете, что на самом деле иногда некоторые вещи просто находятся вне вашего контроля, и вы просто должны делать все, что можете.

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

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