Nie, odpowiedzią na moje drugie pytanie nie jest zima.
Przedmowa:
Ostatnio dużo badałem Entity Framework i coś, co mnie niepokoi, to jego wydajność, gdy zapytania nie są rozgrzane, tak zwane zimne zapytania.
Zapoznałem się z artykułem dotyczącym wydajności dla Entity Framework 5.0. Autorzy przedstawili koncepcję zapytań Warm and Cold i ich różnice, co również zauważyłem, nie wiedząc o ich istnieniu. W tym miejscu chyba warto wspomnieć, że mam za plecami zaledwie pół roku doświadczenia.
Teraz wiem, jakie tematy mogę dodatkowo zbadać, jeśli chcę lepiej zrozumieć ramy pod kątem wydajności. Niestety większość informacji w Internecie jest nieaktualna lub nadęta z subiektywnością, stąd nie mogę znaleźć żadnych dodatkowych informacji na temat zapytań Warm vs Cold .
Zasadniczo zauważyłem do tej pory, że za każdym razem, gdy muszę ponownie skompilować lub odzyskać trafienia, moje początkowe zapytania stają się bardzo wolne. Każdy kolejny odczyt danych jest szybki ( subiektywny ), zgodnie z oczekiwaniami.
Będziemy migrować do Windows Server 2012, IIS8 i SQL Server 2012 i jako Junior faktycznie zyskałem możliwość przetestowania ich przed resztą. Bardzo się cieszę, że wprowadzili moduł rozgrzewający, który przygotuje moją aplikację na to pierwsze żądanie. Jednak nie jestem pewien, jak kontynuować rozgrzewanie mojego Entity Framework.
Co już wiem, warto zrobić:
- Wygeneruj moje widoki z wyprzedzeniem, zgodnie z sugestią.
- W końcu przenieś moje modele do oddzielnego zespołu.
To, co uważam za zrobienie, kierując się zdrowym rozsądkiem, prawdopodobnie jest złym podejściem :
- Wykonywanie fikcyjnych odczytów danych podczas uruchamiania aplikacji w celu rozgrzania, wygenerowania i zweryfikowania modeli.
Pytania:
- Jakie byłoby najlepsze podejście do zapewnienia wysokiej dostępności w mojej Entity Framework w dowolnym momencie?
- W jakich przypadkach Entity Framework znów się „stygnie”? (Rekompilacja, recykling, ponowne uruchomienie usług IIS itp.)
Odpowiedzi:
Możesz wybrać połączenie wstępnie wygenerowanych widoków i statycznych skompilowanych zapytań.
Statyczne CompiledQuerys są dobre, ponieważ są szybkie i łatwe do napisania i pomagają zwiększyć wydajność. Jednak w przypadku EF5 nie jest konieczne kompilowanie wszystkich zapytań, ponieważ EF sam skompiluje zapytania. Jedynym problemem jest to, że te zapytania mogą zostać utracone, gdy pamięć podręczna zostanie wyczyszczona. Dlatego nadal chcesz przechowywać odwołania do własnych skompilowanych zapytań dla tych, które występują bardzo rzadko, ale są drogie. Jeśli umieścisz te zapytania w klasach statycznych, zostaną one skompilowane, gdy będą wymagane. W przypadku niektórych zapytań może być za późno, dlatego warto wymusić kompilację tych zapytań podczas uruchamiania aplikacji.
Inną możliwością, o której wspomniałeś, jest pregenerowanie widoków. Szczególnie w przypadku zapytań, których kompilacja zajmuje bardzo dużo czasu i które się nie zmieniają. W ten sposób przenosisz narzut wydajności z czasu wykonywania na czas kompilacji. Nie spowoduje to również żadnego opóźnienia. Ale oczywiście ta zmiana przechodzi do bazy danych, więc nie jest to łatwe. Kod jest bardziej elastyczny.
Nie używaj dużo dziedziczenia TPT (jest to ogólny problem z wydajnością w EF). Nie buduj swojej hierarchii dziedziczenia zbyt głębokiej ani zbyt szerokiej. Tylko 2-3 właściwości specyficzne dla niektórych klas mogą nie wystarczyć, aby wymagać własnego typu, ale mogą być obsługiwane jako właściwości opcjonalne (dopuszczające wartość null) dla istniejącego typu.
Nie trzymaj się jednego kontekstu przez długi czas. Każda instancja kontekstu ma własną pamięć podręczną pierwszego poziomu, która spowalnia wydajność, gdy rośnie. Tworzenie kontekstu jest tanie, ale zarządzanie stanem wewnątrz buforowanych jednostek kontekstu może stać się kosztowne. Inne pamięci podręczne (plan kwerend i metadane) są współdzielone między kontekstami i znikną wraz z domeną AppDomain.
Podsumowując, należy często alokować konteksty i używać ich tylko przez krótki czas, aby można było szybko uruchomić aplikację, kompilować rzadko używane zapytania i udostępniać wstępnie wygenerowane widoki dla zapytań, które są krytyczne dla wydajności i często używane.
Zasadniczo za każdym razem, gdy tracisz AppDomain. Usługi IIS są uruchamiane ponownie co 29 godzin , więc nigdy nie możesz zagwarantować, że będziesz mieć swoje wystąpienia w pobliżu. Również po pewnym czasie braku aktywności AppDomain jest wyłączany. Powinieneś spróbować szybko podnieść się. Może możesz wykonać część inicjalizacji asynchronicznie (ale uważaj na problemy z wielowątkowością). Możesz używać zaplanowanych zadań, które wywołują fałszywe strony w aplikacji w czasie, gdy nie ma żądań, aby zapobiec śmierci AppDomain, ale w końcu tak się stanie.
Zakładam również, że gdy zmienisz plik konfiguracyjny lub zmienisz zestawy, nastąpi ponowne uruchomienie.
źródło
Jeśli szukasz maksymalnej wydajności we wszystkich wywołaniach, powinieneś dokładnie rozważyć swoją architekturę. Na przykład sensowne może być wstępne buforowanie często używanych wyszukiwań w pamięci RAM serwera podczas ładowania aplikacji zamiast używania wywołań bazy danych przy każdym żądaniu. Ta technika zapewni minimalne czasy odpowiedzi aplikacji w przypadku powszechnie używanych danych. Musisz jednak mieć pewność, że masz dobrze działające zasady wygasania lub zawsze czyść pamięć podręczną po wprowadzeniu zmian, które mają wpływ na dane w pamięci podręcznej, aby uniknąć problemów ze współbieżnością.
Ogólnie rzecz biorąc, należy dążyć do projektowania rozproszonych architektur tak, aby wymagały żądań danych opartych na we / wy tylko wtedy, gdy informacje przechowywane lokalnie w pamięci podręcznej stają się nieaktualne lub muszą być transakcyjne. Każde żądanie danych „over the wire” trwa zwykle 10–1000 razy dłużej niż pobieranie danych lokalnych w pamięci podręcznej. Już sam ten fakt sprawia, że dyskusje na temat „danych zimnych i ciepłych” są nieistotne w porównaniu z kwestią danych „lokalnych i zdalnych”.
źródło
Ogólne wskazówki.
Teraz wyjaśnij, dlaczego fałszywe żądania nie są złym podejściem .
Wyjaśnienie, kiedy pamięć podręczna staje się „zimna”.
Dzieje się tak na każdej warstwie twojego frameworka, która stosuje pamięć podręczną. Dobry opis znajduje się na górze strony wydajności .
Inne rzeczy, o których wspomniałeś, w szczególności ponowna kompilacja i ponowne uruchomienie usług IIS, powodują wyczyszczenie części lub wszystkich pamięci podręcznych.
źródło
Jak już powiedziałeś, użyj „wstępnie wygenerowanych widoków”, to naprawdę wszystko, co musisz zrobić.
Wyodrębniono z linku : „Kiedy generowane są widoki, są one również weryfikowane. Z punktu widzenia wydajności ogromna większość kosztów generowania widoku to w rzeczywistości walidacja widoków”
Oznacza to, że podczas budowania złożenia modelu nastąpi spadek wydajności. Twój obiekt kontekstu pominie wtedy „zimne zapytanie” i pozostanie responsywny przez czas trwania cyklu życia obiektu kontekstu, jak również przez kolejne nowe konteksty obiektu.
Wykonywanie nieistotnych zapytań nie będzie służyło żadnym innym celom poza zużywaniem zasobów systemowych.
Skrót ...
źródło
Nie mam doświadczenia w tych ramach. Ale w innych kontekstach, np. W Solr, całkowicie fałszywe odczyty nie będą zbyt użyteczne, chyba że możesz buforować całą bazę danych (lub indeks).
Lepszym podejściem byłoby rejestrowanie zapytań, wyodrębnianie najczęstszych z dzienników i używanie ich do rozgrzewki. Tylko pamiętaj, aby nie rejestrować zapytań rozgrzewkowych ani nie usuwać ich z dzienników przed kontynuowaniem.
źródło