Não, a resposta à minha segunda pergunta não é o inverno.
Prefácio:
Tenho feito muitas pesquisas sobre o Entity Framework recentemente e algo que continua me incomodando é o seu desempenho quando as consultas não são aquecidas, as chamadas consultas frias.
Eu li o artigo de considerações de desempenho para o Entity Framework 5.0. Os autores introduziram o conceito de consultas quentes e frias e como elas diferem, que eu também percebi sem saber de sua existência. Aqui provavelmente vale a pena mencionar que só tenho seis meses de experiência nas minhas costas.
Agora eu sei quais tópicos posso pesquisar adicionalmente, se quiser entender melhor a estrutura em termos de desempenho. Infelizmente, a maioria das informações na Internet está desatualizada ou inchada de subjetividade, daí minha incapacidade de encontrar qualquer informação adicional sobre o tópico de consultas Quentes vs Frias .
Basicamente, o que notei até agora é que sempre que tenho que recompilar ou os resultados de reciclagem, minhas consultas iniciais estão ficando muito lentas. Qualquer leitura de dados subsequente é rápida ( subjetiva ), conforme esperado.
Estaremos migrando para o Windows Server 2012, IIS8 e SQL Server 2012 e, como um Junior, realmente ganhei a oportunidade de testá-los antes do resto. Estou muito feliz por eles introduzirem um módulo de aquecimento que deixará meu aplicativo pronto para a primeira solicitação. No entanto, não tenho certeza de como proceder com o aquecimento do meu Entity Framework.
O que já sei vale a pena fazer:
- Gere minhas visualizações com antecedência, conforme sugerido.
- Por fim, mova meus modelos para uma montagem separada.
O que considero fazer, seguindo o bom senso, provavelmente é uma abordagem errada :
- Fazer leituras de dados fictícios no início do aplicativo para aquecer, gerar e validar os modelos.
Questões:
- Qual seria a melhor abordagem para ter alta disponibilidade em meu Entity Framework a qualquer momento?
- Em quais casos o Entity Framework fica "frio" novamente? (Recompilação, Reciclagem, Reinício IIS etc.)
Respostas:
Você pode escolher uma mistura de visualizações pré-geradas e consultas compiladas estáticas.
Static CompiledQuerys são bons porque são rápidos e fáceis de escrever e ajudam a aumentar o desempenho. No entanto, com o EF5 não é necessário compilar todas as suas consultas, pois o próprio EF irá auto-compilar as consultas. O único problema é que essas consultas podem ser perdidas quando o cache é varrido. Portanto, você ainda deseja manter referências às suas próprias consultas compiladas para aquelas que ocorrem apenas muito raras, mas que são caras. Se você colocar essas consultas em classes estáticas, elas serão compiladas quando forem necessárias pela primeira vez. Isso pode ser muito tarde para algumas consultas, então você pode querer forçar a compilação dessas consultas durante a inicialização do aplicativo.
Visualizações pré-geradas é a outra possibilidade que você mencionou. Especialmente para aquelas consultas que demoram muito para compilar e que não mudam. Dessa forma, você move a sobrecarga de desempenho do tempo de execução para o tempo de compilação. Além disso, isso não apresentará qualquer lag. Mas é claro que essa mudança vai para o banco de dados, então não é tão fácil de lidar. O código é mais flexível.
Não use muita herança TPT (esse é um problema de desempenho geral no EF). Não crie hierarquias de herança muito profundas nem muito largas. Apenas 2 a 3 propriedades específicas para alguma classe podem não ser suficientes para exigir um tipo próprio, mas podem ser tratadas como propriedades opcionais (anuláveis) para um tipo existente.
Não se apegue a um único contexto por muito tempo. Cada instância de contexto tem seu próprio cache de primeiro nível, o que diminui o desempenho à medida que cresce. A criação de contexto é barata, mas o gerenciamento de estado dentro das entidades em cache do contexto pode se tornar caro. Os outros caches (plano de consulta e metadados) são compartilhados entre contextos e morrerão junto com o AppDomain.
Em suma, você deve certificar-se de alocar contextos com frequência e usá-los apenas por um curto período de tempo, de poder iniciar seu aplicativo rapidamente, de compilar consultas que raramente são usadas e fornecer visualizações pré-geradas para consultas que são críticas para o desempenho e frequentemente usadas.
Basicamente, toda vez que você perder seu AppDomain. O IIS reinicia a cada 29 horas , portanto, você nunca pode garantir que terá suas instâncias por perto. Além disso, depois de algum tempo sem atividade, o AppDomain também é encerrado. Você deve tentar subir rapidamente novamente. Talvez você possa fazer parte da inicialização de forma assíncrona (mas cuidado com os problemas de multi-threading). Você pode usar tarefas agendadas que chamam páginas fictícias em seu aplicativo durante os momentos em que não há solicitações para evitar que o AppDomain morra, mas acabará.
Também presumo que quando você altera seu arquivo de configuração ou altera os assemblies, haverá uma reinicialização.
fonte
Se você está procurando desempenho máximo em todas as chamadas, deve considerar sua arquitetura com cuidado. Por exemplo, pode fazer sentido pré-armazenar em cache as pesquisas frequentemente usadas na RAM do servidor quando o aplicativo é carregado em vez de usar chamadas de banco de dados em cada solicitação. Essa técnica garantirá tempos de resposta mínimos do aplicativo para os dados comumente usados. No entanto, você deve ter certeza de ter uma política de expiração bem comportada ou sempre limpar seu cache sempre que forem feitas alterações que afetem os dados em cache para evitar problemas de simultaneidade.
Em geral, você deve se esforçar para projetar arquiteturas distribuídas para exigir apenas solicitações de dados baseadas em E / S quando as informações armazenadas localmente em cache se tornarem obsoletas ou precisarem ser transacionais. Qualquer solicitação de dados "durante a transmissão" normalmente levará de 10 a 1000 vezes mais para ser recuperada do que uma local, na recuperação do cache de memória. Este único fato muitas vezes torna as discussões sobre "dados frios vs. quentes" irrelevantes em comparação com a questão dos dados "locais vs. remotos".
fonte
Dicas gerais.
Agora, para explicar por que solicitações fictícias não são a abordagem errada .
Para explicar quando um cache fica "frio".
Isso acontece em qualquer camada em sua estrutura que aplique um cache. Há uma boa descrição no topo da página de desempenho .
As outras coisas que você mencionou, especificamente a recompilação e a reinicialização do IIS, limpam partes ou todos os caches na memória.
fonte
Como você afirmou, use "visualizações pré-geradas", que é tudo o que você realmente precisa fazer.
Extraído do seu link : "Quando as visualizações são geradas, elas também são validadas. Do ponto de vista do desempenho, a grande maioria do custo da geração de visualizações é na verdade a validação das visualizações"
Isso significa que a batida no desempenho ocorrerá quando você construir a montagem do modelo. Seu objeto de contexto irá então pular a "consulta fria" e permanecer responsivo durante o ciclo de vida do objeto de contexto, bem como novos contextos de objeto subsequentes.
A execução de consultas irrelevantes não terá outra finalidade senão consumir recursos do sistema.
O atalho ...
fonte
Não tenho experiência neste framework. Mas em outros contextos, por exemplo, Solr, leituras completamente fictícias não serão muito úteis, a menos que você possa armazenar em cache todo o banco de dados (ou índice).
Uma abordagem melhor seria registrar as consultas, extrair as mais comuns dos registros e usá-las para o aquecimento. Apenas certifique-se de não registrar as consultas de aquecimento ou removê-las dos registros antes de continuar.
fonte