Podstawy optymalizacji działającej aplikacji

0
1468
Podstawy optymalizacji

Potrzebowałem porad dotyczących wydajności aplikacji. W związku z tym postanowiłem poradzić się bardziej doświadczonych kolegów i wywołałem dyskusję na Twitterze. Aby usystematyzować otrzymane informacje, zapisuję je tutaj – Twitter jest dla mnie bardzo mało przejrzysty i nieintuicyjny, a być może komuś jeszcze się to przyda.

Od kilku miesięcy pracuję nad aplikacją z branży energetycznej. Ma ona za zadanie zbieranie dużej ilości wiadomości z systemów zewnętrznych, przetwarzanie ich, tworzenie na ich podstawie obiektów, statystyk, raportów wspomagających operatorów sieci energetycznej. Wiadomości pochodzą pośrednio z liczników elektrycznych, więc zazwyczaj jest ich dużo, a czasami, podczas awarii sieci, przychodzi ich o rzędy wielkości więcej. Napisanie takiej aplikacji żeby działała, nie jest rzeczą łatwą – szczególnie z powodu dość specyficznych wymagań. Napisanie jej dodatkowo tak, żeby działała przyzwoicie szybko jest już – przynajmniej dla mnie – rzeczą bardzo trudną.

Otrzymałem zaskakująco wiele odpowiedzi

Na mojego tweeta

odpowiedzieli m.in. Grzegorz Kotfis, Michał Franc, Adam Sitnik, Szymon Kulec, Łukasz Dziekan, Mariusz Gil. A zaczęło się od Łukasza Skotarka, który po prostu oznaczył Adama, a znów jego odpowiedź wywołała lawinę kolejnych. Fajny efekt, bo zostałem wręcz zalany użytecznymi wiadomościami. Dzięki chłopaki!

Odpowiedzi na Twitterze wydają się być poplątane i mogłem je posegregować albo działami (polecane książki, praktyki etc.) albo po autorach. Wybrałem to drugie – było po prostu łatwiejsze.

Adam Sitnik

Adam Sitnik

Przede wszystkim Adam polecił prace dot. wydajności kodu:

Mariusz Gil

Mariusz Gil

Mariusz wypowiedział parę zaklęć, z których niewiele od razu zrozumiałem 🙂 Jednak po wnikliwej analizie wyłuskałem z jego wypowiedzi bardzo interesujące zalecenia (o ile dobrze zrozumiałem):

Do diagnostyki wydajności systemu (aplikacji i infrastruktury) bardzo dobre wyniki daje monitoring oparty o bazę metryczną (np. InfluxDB, Prometheus, Graphite) z raportowaniem na frontendzie. Mariusz rekomenduje stos Influxa + Grafana lub monitoring typu APM (Aplication Performance Monitoring – np. NewRelic).

W powyższym chodzi o to, aby aplikacja i usługi wysyłały swoje statystyki do bazy metrycznej a następnie dane te można wizualizować w Grafanie (lub dołączyć do nich wykrywanie anomalii). Po czymś takim mamy system, z którego co krótki czas wychodzi kilka tysięcy użytecznych metryk. Mariusz mówi, że ma się wtedy wrażenie, że podpięło się pod układ nerwowy całego systemu 🙂

Konfiguracja tego wymaga wysiłku, ale mamy wtedy bardzo szczegółowe statystyki działania systemu.

Grzegorz Kotfis

Grzegorz Kotfis

Grzesiek zaleca zasadę „less is bestter”. Zaleca zwrócenie uwagi na kod biznesowy, który często wykonuje zbyt dużo rzeczy – za dużo wywołań bazy danych, WCFa. Można także zejść niżej i optymalizować na poziomie DB, API czy .NET.

Także poleca monitorowanie wydajności, ale z ważnym dodatkiem – monitorowania jej w czasie i wychwycenia momentu, kiedy wydajność maleje po dodaniu jakiegoś kawałka kodu. Umożliwia to szybkie zdiagnozowanie wadliwej części.

Grzesiek dał też linka do Stackify – aplikacji do monitorowania na żywo. Na blogu aplikacji także znajduje się kilka artykułów, które mogą być przydatne. Przypomina także o Devtalk.pl – tam też pojawiały się odcinki, w której goście opowiadali o wydajności (m.in. #29, #54, #66)

Michał Franc

Michał Franc

Po zapytaniu o sposoby monitorowania, Michał odpowiedział:

W zależności od typu aplikacji można sprawdzać jej wydajność zwykłym profilerem i wykrywać wąskie gardła. Jeżeli chcemy uzyskać naprawdę wyśrubowane wyniki musimy przygotować dedykowane testy obciążeniowe.

Michał przypomniał, że Łukasz Dziekan polecił książkę M. Kleppmanna „Designing Data-Intensive Applications”, zawierającą dużo teorii ukazanej w przystępnej formie. Wg Michała to dobry start i drogowskaz przy rozpoczęciu prac z optymalizacją. Książka zawiera dużo dalszych odnośników do poszerzania wiedzy.

Jeżeli chodzi o .NET to kwestia tego, co chcemy optymalizować – czy wyciskać maksymalne wartości z „cpu bound workloadów” czy zwiększać przepustowość, czy zmniejszać opóźnienie (latency) oplikacji wrażliwej pod kątem I/O.

Do benchmarkowania kodu Michał poleca BenchmarkDotNet, czyli dziecko Adama 🙂 A także jego blog oraz listę zagadnień związanych z wydajnością, którą zarządza.

Michał zalecił także obserwowanie Konrada Kokosy, piszącego obecnie książkę o wydajności.

Jeżeli zaś mówimy o wydajności całego systemu a nie tylko jednego komponentu, warto zapoznać się z inną listą materiałów.

Szymon Kulec

Szymon Kulec

  1. Przy konkretnych wyzwaniach, takich jak działający wolno system, jednym z najprostszych narzędzi jest MiniProfiler. Szczególnie, jeżeli mamy WCF lub abstrakcję na bazę danych. Profiler pozwala na śledzenie całych żądań. Tak wyśledzone żądanie można zapisać (każde lub co któreś) i przeanalizować. Należy pamiętać, że ma tu często zastosowanie zasada Pareto – większa część wydajności aplikacji leży w małym kawałku kodu.
  2. Z innych podejść – Zipkin lub podobne rozwiązanie, które raportuje bez przekazywania kontekstu.
  3. Jeżeli pracujemy nie w środowisku „on-premises”, a chmurze, to można sprawdzić dedykowany system AppInsight, dający bardzo duże możliwości.
  4. Szymon podał także bardzo fajny przykład naukowego podejścia – podlinkował do artykułu dot. Dappera (ale nie tego z C#a Google’owego 🙂 )
  5. Podejście – najpierw zbieraj, później analizuj. Dodatkowo może się przydać pojęcie histogramu, rozkładu zmiennej (percentyle).
  6. „Na deser” gruba rzecz – tzw. coordinated omission, czyli o tym jak mogą nas oszukiwać systemy monitorujące.

Podsumowanie

Dostałem to, czego chciałem. Chłopaki w krótkim czasie dali mi tyle materiałów, że w połączeniu z ciężką pracą naprawdę mogę osiągnąć pożądane rezultaty.

Jeżeli powyższe podsumowanie zawiera błędy, to nie są to błędy moich kolegów, a wyłącznie moje, wynikające z niezrozumienia tematu, za co z góry przepraszam. Jednocześnie chętnych zapraszam do przeczytania całej dyskusji na Twitterze, być może w międzyczasie zostały dodane kolejne, cenne wpisy.

Raz jeszcze dziękuję za pomoc i podzielenie się swoimi doświadczeniami.