Целесообразно ли использовать HashSet в качестве статического глобала на веб-сервере? - PullRequest
2 голосов
/ 18 сентября 2009

Я хочу создать «временный поиск в кэше», чтобы ускорить поиск файлов на моем веб-сервере.

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

Проблема в том, что много запросов одновременно приводят к зависанию File.Exists (). Я хотел бы сохранить быстрый и грязный HashSet имен файлов, которые, как известно, находятся в локальной папке, так что, если пользователь запрашивает файл, и он существует в HashSet, просто перенаправьте его без выполнения File.Exists (), если он не существует в HashSet, выполните File.Exists (), затем добавьте его.

Я знаю, что HashSet будет взорван, если сервер будет перезапущен, но я не беспокоюсь об этом, потому что он быстро "перестроит" себя с наиболее запрашиваемыми изображениями, используя описанный выше сценарий.

Основной вопрос заключается в том, что, поскольку этот объект будет вызываться от нескольких пользователей, а различные запросы будут добавлять элементы в набор, это вызовет проблему? До сих пор все, что я использовал в статическом глобальном смысле на веб-серверах, это строки подключения к БД или адрес электронной почты для отправки предупреждений и т. Д.

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

Ответы [ 2 ]

4 голосов
/ 18 сентября 2009

Помимо проблем, связанных с состоянием гонки, о которых вы упоминали, вы задаете ряд других проблем.

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

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

Это, конечно, решаемые проблемы; вопрос не в том, являются ли они разрешимыми, а в том, окупятся ли затраты на их решение за счет увеличения производительности, которую вы получаете.

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

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

Это имеет смысл. Тем не менее, убедитесь, что вы позаботились о возможных условиях гонки. Вы можете использовать ReaderWriterLockSlim класс для управления доступом к объекту из разных потоков.

UPDATE:

Вам абсолютно необходимо правильно заблокировать объект, так как метод Add не является атомарной операцией. Вы даже можете оставить объект в противоречивом состоянии, если добавите две вещи одновременно.

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