Пейджинг, распечатка и группировка запросов с AppFabric Cache - PullRequest
1 голос
/ 26 января 2011

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

У меня есть 4 таблицы:

Product (1 миллион строк), ProductProperty (25 миллионов строк), Property (100 строк), PropertyOption (300 строк)

  • Я отображаю постраничные результаты поиска, запрашивая некоторые фильтры для таблиц Product и ProductProperty.
  • Я создаю критерии, установленные для найденного набора результатов. Например (4 товара, 34 товара, 26 книг и т. Д.)
  • Я запрашиваю группировку по таблице Product со столбцами IsNew, CategoryId, PriceType и т. Д.
    а также другой запрос для группировки по таблице ProductProperty со столбцами PropertyId и PropertyOptionId, чтобы узнать, какое свойство имеет сколько элементов

Поэтому для отображения результатов поиска я делаю один запрос для результата поиска и 2 для создания списка критериев (с подсчетами)

Запрос результатов поиска занял 0,7 секунды, а 2 запроса на группировку - 1,5 секунды. Когда я запускаю нагрузочный тест, я достигаю 7 запросов в секунду и% 10 сбрасывается IIS, потому что db не может дать ответ.

Вот почему я хочу кэшировать записи о товарах и свойствах.

Если я буду следовать пунктам ниже (в AppFabric);

  • Создать именованный кеш
  • Создание региона для данных каталога продуктов (таблица с 1 миллионом строк и таблица свойств с 25 миллионами строк)
  • Пометка элемента для запроса данных и группировки.

Могу ли я сделать запрос с некоторыми тегами и получить 1-ю или 2-ю страницу результатов? Могу ли я сделать запрос с некоторыми тегами и получить результаты некоторых группировок. (отображение параметров фильтра со счетчиком) И нужно ли мне 3 сервера? Могу ли я предоставить решение только с одним сервером appfabric (и, конечно, я знаю риск). Знаете ли вы какую-либо статью или какой-либо документ, объясняющий эти сценарии?

Спасибо.

Примечание:

Некоторые дополнительные тесты: Я добавил около 30 000 элементов в кеш, а его размер составляет 900 МБ. Когда я запускаю метод getObjectsInRegion, он занимает около 2 минут. "IList> dataList = this.DataCache.GetObjectsInRegion (region) .ToList ();" Проблема в конвертации в IList. Если я использую IEnumerable, он работает очень быстро. Но как я могу получить результаты подкачки или группировки без преобразования их в мой тип?

Еще один тест:

Я пытался получить счетчик группировок с 30 000 единиц товара, и получение результата для группировки заняло 4 секунды. Например, GetObjectByTag ("IsNew"). Count () и другие почти 50 подобных запросов.

1 Ответ

2 голосов
/ 22 февраля 2011

К сожалению, API-интерфейс подкачки для AppFabric в V1 отсутствует. Любой из массовых API, например GetObjectsByTag, будет выполнять запрос на сервере и передавать обратно все соответствующие записи в кэш-памяти клиенту. Оттуда вы, очевидно, можете использовать любые операторы LINQ, которые вам нужны на IEnumerable (например, Skip/Take/Count), но имейте в виду, что вы всегда извлекаете полный набор результатов с сервера.

Лично я надеюсь, что AppFabric V2 предоставит поддержку через IQueryable вместо IEnumerable, что даст возможность удаленно отправить полный запрос на сервер, чтобы он мог публиковать там результаты перед возвратом к клиенту, так же как LINQ2SQL или ADO .NET EF.

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

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

private static string BuildPageListCacheKey(string entityTypeName, int pageSize, int pageNumber, string sortByPropertyName, string sortDirection)
{
   return string.Format("PageList<{0}>[pageSize={1};pageNumber={2};sortedBy={3};sortDirection={4}]", entityTypeName, pageSize, pageNumber, sortByPropertyName, sortDirection);
}

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

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

...