#linq-to-sql #asp.net-mvc-2 #iis-7.5 #web-farm #nlb
#linq-to-sql #asp.net-mvc-2 #iis-7.5 #веб-ферма #nlb
Вопрос:
У нас есть веб-приложение, написанное на MVC2 Linq2SQL MS SQL SERVER 2008, размещенное на веб-ферме. Почти как stackoverflow.com
У нас есть 4 x IIS7 1 SQL SERVER 2008, сбалансированный по нагрузке с MS NLB
Статическое содержимое кэшируется внешним поставщиком кэша — Akamai, что сокращает 86% запросов.
Каждый веб-сервер имеет 32 ГБ оперативной памяти и 4 четырехъядерных процессора, поэтому во внешнем интерфейсе 64 ядра.
Мы сохраняем состояние сеанса в таблицах.
Он отлично работает со средним трафиком (загрузка страницы = 0,2 с), но компания делает телевизионную рекламу, и во время этих объявлений трафик достигает 20 000 пользователей в течение 20-30 секунд.
В этот момент страница замедляется до 8-10 секунд. Однако использование ЦП и памяти даже не достигает 40% ни на одном компьютере.
Пропускная способность центра обработки данных не достигает половины своих пределов.
Медленные страницы генерируют данные из простых выборок максимум из 10 записей только из 1-2 таблиц.
Очевидно, что где-то есть узкое место, и я пытаюсь выяснить, где именно.
У кого-нибудь есть какие-либо советы для меня, где искать проблему?
Комментарии:
1. Я думаю, что слишком много SELECT в этих таблицах вызывает эту проблему. Есть ли у вас правильные индексы и т. Д. В этих таблицах на основе вашего предложения WHERE?
2. Я согласен с Анкуром. Похоже, что в базе данных выполняется чрезмерное количество запросов. Проверьте свои индексы, использование ToList(), Any() и т.д. Это все функции, которые выполняют вызовы к базе данных. Вы также можете использовать такой инструмент, как dotTrace, для профилирования вашего приложения и посмотреть, что произойдет.
3. Я кластеризовал индексы по всем столбцам PK и просмотрел планы выполнения. Я не думаю, что отсутствие дополнительных индексов может вызвать это узкое место. Это, безусловно, помогает, но я бы получил небольшой процент. Я ищу большой выигрыш. Поэтому я также думал о дисковом вводе-выводе блока SQL server и разделении базы данных на несколько разных файлов, размещенных на нескольких разных дисках, чтобы улучшить параллелизм дискового ввода-вывода. Как сказано здесь: tinyurl.com/6xfxuso
Ответ №1:
Я обнаружил проблему некоторое время назад, но у меня не было времени опубликовать ее здесь. Я перепробовал почти все, что мог придумать: индексы, оптимизацию sql, мониторинг дискового ввода-вывода, пересмотр кода. Ничто из вышеперечисленного не решило мою проблему. Я запускаю веб-стресс-тест с 2 рабочих станций в нашей локальной сети, и я могу заморозить всю страницу за считанные секунды! Во время выполнения тестов я заметил что-то странное. Я создал отдельный контроллер для тестирования и поставил 2 метода. Оба делают одно и то же: запрашивают одни и те же данные на нашем сервере базы данных.
Действие А)
public ActionResult Index(){
var model = new SomeModel();
// Get data
....
return View(model);
}
Действие B)
public ActionResult Index() {
var model = new SomeModel();
// Get data
....
return View("Index",model);
}
Разница в загрузке страницы:
A) ~ 297 мс
Б) ~ 39,47 с
Это происходит только при высоком уровне параллелизма, в противном случае все в порядке. Похоже, что поиск представления по умолчанию в библиотеке MVC2 вызывает проблему, поскольку после его указания все работает отлично.
Я описал это в своем блоге:
Я опубликовал это в журнале отслеживания проблем asp.net на codeplex, но никто еще не прокомментировал / не ответил на него.
Ответ №2:
Для некоторых меньших преимуществ в производительности вы можете попробовать некоторые из настроек, о которых упоминает Рико Мариани в http://blogs.msdn.com/b/ricom/archive/2007/06/22/dlinq-linq-to-sql-performance-part-1.aspx . В частности, попробуйте использовать CompiledQuery и отключить отслеживание изменений для объектов только для отображения.