Как "разогревать" Entity Framework? Когда он становится "холодным"?

Нет, ответ на мой второй вопрос - не зима.

Предисловие:

Недавно я много изучал Entity Framework, и что-то, что меня беспокоит, - это его производительность, когда запросы не разогреваются, так называемые холодные запросы.

Я рассмотрел статью по соображениям производительности для Entity Framework 5.0. Авторы ввели понятие теплых и холодных запросов и то, как они отличаются, и я также заметил себя, не зная о своем существовании. Здесь, наверное, стоит упомянуть, что у меня есть только шесть месяцев опыта за моей спиной.

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

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

Мы перейдем на Windows Server 2012, IIS8 и SQL Server 2012, а в качестве Junior я действительно получил возможность проверить их перед остальными. Я очень рад, что они представили модуль разминки, который подготовит мое приложение для этого первого запроса. Тем не менее, я не уверен, как продолжить разминку моей Entity Framework.

То, что я уже знаю, стоит делать:

  • Создайте мои представления заранее, как было предложено.
  • В конечном итоге переместите мои модели в отдельную сборку.

То, что я считаю делать, исходя из здравого смысла, возможно, ошибочного подхода:

  • Выполнение фиктивных данных читается в приложении Start, чтобы разогревать, генерировать и проверять модели.

Вопросы:

  • Каким будет наилучший подход к обеспечению высокой доступности моей Entity Framework в любое время?
  • В каких случаях система Entity Framework снова становится "холодной"? (Перекомпиляция, переработка, перезапуск IIS и т.д.)

Ответ 1

  • Каким будет наилучший подход к обеспечению высокой доступности моей Entity Framework в любое время?

Вы можете выбрать сочетание предварительно сгенерированных представлений и статических скомпилированных запросов.

Static CompiledQuery - это хорошо, потому что они быстро и легко писать и помогают повысить производительность. Однако с EF5 нет необходимости компилировать все ваши запросы, поскольку EF будет автоматически компилировать запросы самостоятельно. Единственная проблема заключается в том, что эти запросы могут потеряться, когда кэш будет охвачен. Таким образом, вы все еще хотите хранить ссылки на свои собственные скомпилированные запросы для тех, которые встречаются только очень редко, но это дорого. Если вы поместите эти запросы в статические классы, они будут скомпилированы, когда они будут сначала необходимы. Это может быть слишком поздно для некоторых запросов, поэтому вам может потребоваться принудительная компиляция этих запросов во время запуска приложения.

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

Не используйте много наследования TPT (это общая проблема с производительностью в EF). Не стройте иерархию наследования слишком глубоко или слишком широко. Только 2-3 свойства, специфичные для какого-либо класса, могут быть недостаточными, чтобы требовать собственный тип, но могут быть обработаны как необязательные (обнуляемые) свойства для существующего типа.

Не держитесь за один контекст в течение длительного времени. Каждый экземпляр контекста имеет свой кеш первого уровня, который замедляет производительность по мере роста. Контекстное создание дешево, но управление государством внутри кэшированных объектов контекста может стать дорогостоящим. Другие кеши (план запроса и метаданные) разделяются между контекстами и будут умирать вместе с AppDomain.

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

  • В каких случаях система Entity Framework снова становится "холодной"? (Перекомпиляция, переработка, перезапуск IIS и т.д.)

В принципе, каждый раз, когда вы теряете свой AppDomain. IIS выполняет перезагрузки каждые 29 часов, поэтому вы никогда не сможете гарантировать, что у вас будут свои экземпляры. Также через некоторое время без активности AppDomain также отключается. Вы должны попытаться быстро подняться. Возможно, вы можете выполнить некоторую инициализацию асинхронно (но остерегайтесь многопоточных проблем). Вы можете использовать запланированные задачи, которые вызывают фиктивные страницы в вашем приложении в те времена, когда нет запросов на предотвращение смерти AppDomain, но в конце концов.

Я также предполагаю, что когда вы меняете свой файл конфигурации или меняете сборки, там будет перезапуск.

Ответ 2

Если вы ищете максимальную производительность во всех вызовах, вы должны тщательно изучить свою архитектуру. Например, имеет смысл предварительно кэшировать часто используемые образы в ОЗУ сервера, когда приложение загружается, а не использует вызовы базы данных по каждому запросу. Этот метод обеспечит минимальное время отклика приложений для часто используемых данных. Тем не менее, вы должны быть уверены в правильности политики истечения срока действия или всегда очищать свой кеш при внесении изменений, которые влияют на кешированные данные, чтобы избежать проблем с concurrency.

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

Ответ 3

Общие советы.

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

Теперь, чтобы объяснить, почему фиктивные запросы - неправильный подход.

  • Меньше сложность - вы разогреваете приложение таким образом, чтобы он работал независимо от изменений в структуре, и вам не нужно определять, возможно, фанковые API/внутренние структуры, чтобы сделать это правильно.
  • Greater Coverage - вы разогреваете все уровни кеширования сразу, связанные с медленным запросом.

Чтобы объяснить, когда кеш получает "Холодный".

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

  • Когда когда-либо кеш должен быть проверен после потенциального изменения, которое делает кеш устаревшим, это может быть тайм-аут или более интеллектуальный (т.е. изменение кэшированного элемента).
  • Когда элемент кэша выдворен, алгоритм для этого описан в разделе "Алгоритм выключения кэша" в статье о производительности, которую вы связали, но вкратце.
    • Кэш LFRU (наименее часто - недавно использованный) при подсчете количества попаданий и возраста с лимитом в 800 единиц.

Другие вещи, которые вы упомянули, в частности, перекомпилирование и перезапуск IIS, очищают либо части, либо все кэши памяти.

Ответ 4

Как вы уже сказали, используйте "предварительно созданные представления", которые действительно все, что вам нужно сделать.

Извлечен из ссылка: "Когда генерируются представления, они также проверяются. С точки зрения производительности подавляющая часть стоимости генерации представлений на самом деле является валидацией представлений"

Это означает, что стук производительности будет выполняться при сборке модели. Затем ваш объект контекста пропустит "холодный запрос" и будет реагировать на продолжительность жизненного цикла объекта контекста, а также на последующие новые объектные контексты.

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

Ярлык...

  • Пропустить всю дополнительную работу с предварительно созданными представлениями
  • Создание контекста объекта
  • Скройте этот сладкий нерелевантный запрос
  • Затем просто держите ссылку на свой контекст объекта в течение всего процесса. (не рекомендуется).

Ответ 5

У меня нет опыта в этой области. Но в других контекстах, например. Solr, полностью фиктивные чтения не будут иметь большого смысла, если вы не можете кэшировать всю БД (или индекс).

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