Нужно предложение для очереди ASP.Net в памяти - PullRequest
1 голос
/ 29 декабря 2008

У меня есть требование создать HttpHandler, который будет обслуживать файл изображения (простой статический файл), а также вставлять запись в таблицу SQL Server. (например, http://site/some.img,, где some.img является HttpHandler) Мне нужен объект в памяти (например, объект общего списка), к которому я могу добавлять элементы при каждом запросе (я также должен рассмотреть несколько сотен или тысяч запросов в секунду), и я должен иметь возможность выгрузить этот объект в памяти в таблицу SQL с помощью SqlBulkCopy.

Список -> Таблица данных -> SqlBulkCopy

Я думал об использовании объекта Cache. Создайте объект общего списка и сохраните его в HttpContext.Cache и вставляйте каждый раз новый элемент в него. Это НЕ будет работать, так как CacheItemRemovedCallback сработает сразу, когда HttpHandler попытается добавить новый элемент. Я не могу использовать объект Cache в качестве очереди в памяти.

Кто-нибудь может предложить что-нибудь? Смогу ли я масштабироваться в будущем, если нагрузка будет больше?

Ответы [ 5 ]

1 голос
/ 29 декабря 2008

Почему CacheItemRemovedCalledback срабатывает при добавлении чего-либо в очередь? Это не имеет смысла для меня ... Даже если это срабатывает, нет необходимости делать что-либо здесь. Возможно, я неправильно понимаю ваши требования?

Я довольно успешно использовал объект Cache именно таким образом. Это то, для чего он предназначен, и он очень хорошо масштабируется. Я сохранил Hashtable, к которому обращались при каждом запросе страницы приложения и обновлял / очищал по мере необходимости.

Вариант второй ... тебе действительно нужна очередь? SQL Server будет очень хорошо масштабироваться, даже если вы просто хотите писать прямо в БД. Используйте общий объект соединения и / или пул соединений.

0 голосов
/ 12 января 2009

Чтобы расширить мой предыдущий комментарий ... Я понял, что вы неправильно думаете о кеше. Если у вас есть объект, хранящийся в Cache, например, Hashtable, любое обновление / хранение в этом Hashtable будет сохранено без явного изменения содержимого Cache. Вам нужно добавить Hashtable в Cache только один раз, либо при запуске приложения, либо по первому запросу.

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

0 голосов
/ 30 декабря 2008

Вы можете создать условное требование в обратном вызове, чтобы убедиться, что вы работаете с записью в кеше, которая была удалена по истечении срока действия вместо удаления / замены (в VB, поскольку у меня это было удобно):

Private Shared Sub CacheRemovalCallbackFunction(ByVal cacheKey As String, ByVal cacheObject As Object, ByVal removalReason As Web.Caching.CacheItemRemovedReason)
    Select Case removalReason
        Case Web.Caching.CacheItemRemovedReason.Expired, Web.Caching.CacheItemRemovedReason.DependencyChanged, Web.Caching.CacheItemRemovedReason.Underused
        ' By leaving off Web.Caching.CacheItemRemovedReason.Removed, this will exclude items that are replaced or removed explicitly (Cache.Remove) '
    End Select
End Sub

Редактировать Вот в C #, если вам это нужно:

private static void CacheRemovalCallbackFunction(string cacheKey, object cacheObject, System.Web.Caching.CacheItemRemovedReason removalReason)
{
    switch(removalReason)
    {
        case System.Web.Caching.CacheItemRemovedReason.DependencyChanged:
        case System.Web.Caching.CacheItemRemovedReason.Expired:
        case System.Web.Caching.CacheItemRemovedReason.Underused:
            // This excludes the option System.Web.Caching.CacheItemRemovedReason.Removed, which is triggered when you overwrite a cache item or remove it explicitly (e.g., HttpRuntime.Cache.Remove(key))
            break;
    }
}
0 голосов
/ 29 декабря 2008

Спасибо Alex & Bryan за ваши предложения.

Брайан: Когда я пытаюсь заменить объект List в Cache для второго запроса (теперь количество должно быть 2), CacheItemRemovedCalledback срабатывает, когда я заменяю текущий объект Cache новым. Первоначально я также думал, что это странное поведение, поэтому я должен изучить его глубже. Также, для второго предложения, я попытаюсь вставить запись (с объектом Cached SqlConnection) и посмотреть, какую производительность я получу, когда буду проходить стресс-тест. Я сомневаюсь, что получу фантастические цифры, так как это операция ввода / вывода.

Я буду продолжать копаться на моей стороне, чтобы найти оптимальное решение с вашими предложениями.

0 голосов
/ 29 декабря 2008

Как насчет использования общего списка для хранения запросов и использования другого потока для выполнения SqlBulkCopy?

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

Вы можете даже создать фоновый поток на механизме Cache, выполнив работу над CacheItemRemovedCallback.

Просто вставьте какой-нибудь объект со временем удаления 5 минут и вставьте его снова в конце обработки.

...