Проблема разработки: хорошо или плохо, чтобы сделать изменяемые объекты кэшируемыми? - PullRequest
0 голосов
/ 29 сентября 2010

Здесь мне нужно кэшировать некоторые объекты, например, дерево страниц в системе управления контентом (CMS).Система позволяет разработчикам писать плагины, в которых они могут получить доступ к кэшированному дереву страниц.Хорошо это или плохо, чтобы сделать кэшируемое дерево страниц изменчивым (то есть, существуют установщики для объектов узла дерева, и / или мы выставляем метод Add, Remove в коллекции ChildPages. Таким образом, клиентский код может устанавливать свойства дерева страницузлы, и добавлять / удалять узлы дерева свободно)?

Вот мое мнение:

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

(2) Но иногда нам нужно изменить имя страницы.Если дерево страниц является неизменным, мы должны вызвать некоторый метод, например «Refresh ()», чтобы обновить кэш.Это приведет к попаданию в базу данных (таким образом, всего два попадания в базу данных, но мы должны были избежать одного из двух попаданий в базу данных).В этом случае, если дерево страниц является изменяемым, мы можем напрямую изменить имя в дереве страниц, чтобы обновить дерево (поэтому требуется только 1 попадание в базу данных).

Что вы думаете об этом?И что вы будете делать, если столкнетесь с такой ситуацией?

Заранее спасибо!:)

ОБНОВЛЕНИЕ: Дерево страниц выглядит примерно так:

public class PageCacheItem {
    public string Name { get; set; }
    public string PageTitle { get; set; }
    public PageCacheItemCollection Children { get; private set; }
}

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

Мой пролбем:

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

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

UPDATE2

Спасибо, ребята.Но я должен отметить одну вещь: я не собираюсь разрабатывать общую инфраструктуру кэширования, а буду разрабатывать некоторые API поверх существующей инфраструктуры кэширования.Так что мои API - это промежуточный уровень между базовой структурой кэширования и авторами плагинов.Автору плагина не нужно ничего знать о базовой структуре кэширования.Ему нужно только знать, что это дерево страниц извлекается из кеша.И он заставляет использовать API-интерфейсы PageCacheItem со строгим типом, а не «объект» со слабым типом, извлеченный из базовой структуры кэширования.

Таким образом, мои вопросы касаются разработки API для авторов плагинов , то есть, хорошо или плохо сделать изменяемый класс API PageCacheItem (здесь свойства mutable == могут быть установлены вне PageCacheItemкласс)? * * 1042

Ответы [ 2 ]

3 голосов
/ 29 сентября 2010

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

В зависимости от реализации кэша в словаре, он может быть либо:

  • «потерян»
  • в худшем случае потребуется перепрошить весь кэш

Могут быть веские причины, по которым вам нужны «изменяемые хэш-коды», но я не вижу здесь оправдания.(Мне нужно было делать это только один раз за последние 9 лет).

Было бы намного проще просто удалить и заменить запись, которую вы хотите «мутировать».

1 голос
/ 29 сентября 2010

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

Что касается изменяемых значений, здесь нет единственно правильного ответа. Вы нажали на основной за и против в любом случае, и есть несколько вариантов в каждом из двух вариантов, которые вы описываете. Как правило, аннулирование кэша является чрезвычайно сложной проблемой (как в известной цитате Фила Карлтона: «В компьютерных науках есть только две серьезные проблемы: аннулирование кэша и присвоение имен». *)

Некоторые вещи, которые следует учитывать:

  1. Как часто будут вноситься изменения. Если изменения редки, обновления становятся проще - выгрузите существующий кеш и дайте ему перестроиться.
  2. Будет ли CMS находиться на нескольких серверах, или это может произойти в будущем, поскольку это означает, что любая информация о признании недействительной должна быть передана.
  3. Насколько плохи устаревшие данные и как скоро они плохи (могли бы вы с радостью выпустить на сервер устаревшие значения в течение следующего часа или около того, или это катастрофически конфликтовало бы с новыми значениями).
  4. Имеет ли для вас смысл подход повторной проверки, когда через определенное время проверяется кэшированное значение, чтобы убедиться, что оно все еще действует, и обновляется время до следующей проверки (альтернативно, периодически сбрасывайте старые значения и их снова можно получить из свежего источника).
  5. Насколько легко в первую очередь обнаружить устаревание? Если это трудно, это может исключить некоторые подходы.
  6. Сколько реально сохраняет кеш. Не могли бы вы просто избавиться от этого?

Я не упомянул о проблемах с многопоточностью, потому что проблемы с многопоточностью сложны, если вы не однопоточные (а если это CMS, я предполагаю, что это веб, а следовательно, по своей сути многопоточный). Одна вещь, которую я скажу по этому вопросу, заключается в том, что в общем случае сбой кэша не является критическим (по определению, сбой кэша имеет запасной вариант - получите новое значение), по этой причине может оказаться полезным применить подход где вместо бесконечной блокировки на мониторе (что и делает lock внутри) вы используете Montior.TryEnter с таймаутом, и при сбое операции кэширования происходит сбой. Хорошим подходом может быть использование ReaderWriterLockSlim и немного более длительный тайм-аут для записи. Таким образом, если вы столкнулись с острой конкуренцией за блокировку, кеш перестанет работать для некоторых потоков, но эти потоки все равно получат полезные данные. Это снизит производительность для этих потоков, но не так сильно, как конфликт блокировки для всех затронутых потоков, а кеширование - это место, где очень легко внедрить конфликт блокировки в веб-проект, который срабатывает только после того, как вы начали работу. .

* (и, конечно, хорошо известный вариант, «в компьютерных науках есть только две трудные проблемы: аннулирование кэша, присвоение имен и ошибки« один на один »).

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