Совет по архитектуре C #: метод для кэширования данных в структуре? - PullRequest
2 голосов
/ 28 октября 2010

Я хотел бы попросить вашего совета специалиста по работоспособной архитектуре в C #.

У меня есть служба C #, которая отвечает на запрос локального пользователя в локальной сети, получает пакеты данных из Интернета.и обрабатывает эти данные для создания массивов данных в структуре.Каждый запрос данных занимает около 2 секунд и возвращает 4000 байтов.Может быть десятки тысяч запросов в день.

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

Ограничения:

  1. Базовые данные никогда не меняются, т.е. мне не нужно беспокоиться о «грязных» данных (отлично!).
  2. Данные, которые я хочу кэшировать, представляют собой довольно сложную структуру, которая содержит вложенные массивы DateTime, удваивается и т. Д. Данные обрабатываются с использованием большого количества математических данных из данных, поступающих из Интернета.
  3. Я не могу использовать более 100 МБ памяти независимо от того, сколько данных кэшируется (т. Е. Размер кэша должен быть ограничен).
  4. Я не могу индексировать данные в кэше с помощьючисловой индекс, я должен индексировать его с помощью комбинации даты ("ГГГГ-ММ-ДД") и уникальной строки идентификатора ("XXXXXXXX").
  5. Это должно быть быстро, то есть он должен служитьбольшинство его ответов из оперативной памяти.
  6. данные в кэше должны сохраняться на диск каждые 24 часа.

Вот мои варианты на данный момент:

  1. Кэшируйте данные в классе сервера, используя частные переменные(то есть личный список или словарь), затем периодически сериализуйте его на диск;
  2. Используйте базу данных;

Меня интересует ваше мнение эксперта.

Ответы [ 4 ]

2 голосов
/ 28 октября 2010

На сегодняшний день самое простое решение - использовать для этого Dictionary<string, ComplexDataStructure>.

Относительно ваших требований:

  1. Срок службы кэша проще всего контролировать, еслифоновый поток, который выполняет сканирование кэша каждые 10 минут или час или около того.С ComplexDataStructure вы сохраняете DateTime при создании кэша и удаляете ключ из словаря по истечении срока его службы;

  2. Поскольку вы храните фактическую структуру данныхсложность не проблема;

  3. Ограничение размера может быть затруднено. sizeof (), эквивалентный для ссылочных типов? может помочь вам рассчитать размер структуры объекта.Эта операция не будет простой, но вы можете сохранить результат с помощью ComplexDataStructure.Затем тот же поток, что и для 1., может удалять записи, когда у вас заканчивается свободное место.Возможно, более простым решением было бы использовать GC.GetTotalMemory() и определить, находится ли общее использование памяти вашим процессом за определенным пределом.Затем просто удалите элемент кэша и при втором запуске, когда вы видите, что все еще используете слишком много памяти, удалите второй;

  4. Просто используйте строку;

  5. Использование Dictionary<,>, вероятно, слишком быстро;

  6. Опять же, используйте поток из 1. и реализуйте такую ​​логику.

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

  1. Блокировка словаря;

  2. Проверка наличия элемента кэша;

  3. Когда элемент кэша не существует:

    1. Создать пустой элемент кэша;

    2. Добавить его в словарь;

    3. Установить блокировку элемента кэша;

    4. Снять блокировку словаря;

    5. Выполнение обработки данных;

    6. Добавление сжатых данных к элементу кэша;

    7. Снятие блокировки с элемента кэша;

  4. Когда элемент кэша уже существует;

    1. Если элемент кэша действительно имеет сжатые данные, вернуть это;

    2. Если элемент кэша не содержит сжатых данных, установите блокировку элемента кэша;

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

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

1 голос
/ 28 октября 2010

Возможно что-то вроде Index4Objects?

(http://www.codeplex.com/i4o) http://staxmanade.blogspot.com/2008/12/i4o-indexspecification-for.html

Также, возможно, прочитайте этот ответ на другой вопрос SO i4o vs. PLINQ .

0 голосов
/ 02 ноября 2010

Мне кажется, я нашел идеальное решение: библиотека журналов PostSharp + Kellerman .NET.PostSharp требует небольшой кривой обучения (около 15 минут), но после того, как вы запуститесь, вы можете аннотировать свой метод с помощью атрибута [Cachable], и ​​система автоматически кеширует результаты этого метода для вас.Это примерно такое чистое решение, какое только возможно.

0 голосов
/ 28 октября 2010

Как насчет: Использовать внутренние методы, предоставляемые IIS?

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