fbpx
Select Page

autoscaling-temp

Autoscaling na chmurze. Jakie problemy rozwiązuje, a jakie stwarza?

Tomek-Sapalski-Picture

TOMEK SAPALSKI

Autoscaling jest to temat, który bardzo mocno zyskał na popularności po powstaniu chmur. Zanim mieliśmy do nich dostęp, najczęściej po prostu kupowaliśmy sobie serwer np. na rok za 10-15 tysięcy złotych i nie zwracaliśmy uwagi, czy chodzi on godzinę, miesiąc czy rok.
Jednak jak powstały chmury i zaczęły się rozpowszechniać, pojawiła się możliwość kupowania serwerów na krótszy okres. Właśnie wtedy pojawił się koncept, zwany auto skalowaniem, czyli po ang. autoscaling i jemu będzie poświęcony ten tekst.  

Autoskalowanie to taki sposób działania, którego celem jest dostosowanie ilości zasobów do potrzeb użytkownika. Rozwiązanie to tak, jak wiele rozwiązań chmurowych ma swoje plusy i minusy. Generalnie chodzi w nim o to, że możemy sobie dodawać i odejmować serwery w
zależności od tego, jaki jest ruch na stronie – najczęściej właśnie w taki sposób to się odbywa.
Normalnie każdy serwer można skalowć w opcji scale up i scale down, które polegają na tym, że możemy np. dodać więcej RAMu, dodatkowe procesory i w ten sposób zwiększać jego możliwości. Jednak powoduje to, że jego zasoby również rosną – w związku z tym jest to metoda, która działa do pewnego momentu, ale niestety nie jesteśmy w stanie powiększać
serwera w nieskończoność.  

Co w takiej sytuacji? Pojawia się drugie rozwiązanie, czyli dodawanie i usuwanie kolejnych serwerów (scale out i scale in). Możemy więc wystartować z jednym serwerem, ale po pewnym czasie wraz ze
zwiększeniem ruchu na stronie będziemy ich mieli już 2, 5 czy 50. Koncepcja ta sprawdza się bardzo dobrze w przypadku stron typu stateless, czyli takich, które nie posiadają sesji. Dla zobrazowania możemy użyć przykładu strony internetowej z kilkoma zakładkami,
np. o mnie, portfolio, oferta, itp. Użytkownik wchodzi na stronę, czyta, ogląda i wychodzi. I tak samo 10, czy 100 użytkowników – wchodzi, czyta, ogląda, wychodzi. W tym przypadku nie mamy do czynienia z sesją, bo niezależnie od tego, w którym miejscu czytelnik się znajduje to
przechodząc do kolejnego tematu, wychodzi z poprzedniej zakładki i tylko czyta.  

Przejdźmy więc do sytuacji, kiedy sesja jest. Wyobraźmy sobie aplikację linii lotniczej, która sprzedaje bilety. Wchodzi klient i wybiera, że chciałby kupić bilet z Warszawy do Paryża – klika i wyświetlają mu się wyniki zgodne z jego zapytaniem. Na co klient wybiera sobie datę i godzinę i ponownie klika. Następnie wyświetlają mu się dostępna miejsce i użytkownik
wybiera sobie np. 27A. Taki “dialog” wymaga, żeby następowały jakieś zwrotne działania – konkretne zapytanie zostało wysłane do serwera i serwer na tę informację odpowiedział dając dopasowaną odpowiedź. W jaki sposób realizuje się takie połączenie? Serwer musi niejako wiedzieć, że to jest ten konkretny użytkownik, bo w tym samym czasie na stronie mogą być inni klienci wyszukujący zróżnicowane połączenia. Na tym właśnie polega sesja – serwer „wie” z kim „rozmawia”.

Problem z sesjami przy auto scalingu jest więc taki, że nasz serwer musi pamiętać użytkownika, żeby go obsłużyć.  

Wyobraźmy sobie taki prosty przykład. Idziemy do urzędu, w którym pracuje kilku różnych urzędników. Trafiamy do Pana Jacka, z którym załatwiamy jakąś sprawę i ten Pan mówi nam, że brakuje kilku dokumentów i będziemy musieli je donieść. Wracamy więc do domu, kompletujemy resztę papierów i przychodzimy ponownie. Pan Jacek na nasz widok mówi tak
wiem, pamiętam, uzupełnia dane i wszystko jest załatwione. Jednym słowem mamy z Panem Jackiem sesję. Ale co w sytuacji, kiedy nie ma Pana Jacka i trafimy do Pani Basi, która widzi nas po raz pierwszy? Nie będzie wiedziała kompletnie o co chodzi i ciężko jej będzie rozwiązać nasz problem. Podsumowując, serwer musi mieć informację o każdym użytkowniku, którego obsługuje.  

Problem pojawia się, kiedy mamy kilka serwerów i musimy przyporządkować go za każdym razem do odpowiedniego klienta. Z pomocą przychodzi load balancer, którego zadaniem jest
delegowanie ruchu na poszczególne serwery. Żeby to zrobić musi wiedzieć, kogo należy wysłać do kogo. Wracając do naszego przykładu – nazwijmy load balancera Panem Krzysiem, który wita klientów przy wejściu do urzędu i kieruje odpowiednio do Pana Jacka lub Pani
Basi. Żeby to zrobić poprawnie – musi mieć informacje o danym użytkowniku i osobie, z którą rozmawiał ostatnio. Tak samo w przypadku naszej aplikacji biletowej, load balancer zapamiętuje informację o przychodzącym użytkowniku i o tym, który serwer go obługiwał. W ten sposób możemy zarezerwować sobie konkretne miejsce w samolocie, mimo wielu serwerów, jesteśmy obsługiani ciągle przez ten, do którego zostaliśmy przydzieleni na początku.  

A co w przypadku, kiedy ruchu na stronie nie ma? 1000 osób zakupiło bilety i wyszło ze strony, zostały na niej 2, a my mamy aż 10 aktywnych serwerów. W tej sytuacji trzeba je usuwać – to także robi load balancer. W pierwszej kolejności sprawdza, które z serwerów są zajęte, a które się zwolniły i usuwa te, które nie są już potrzebne. To rozwiązanie jest
oczywiście w porządku, ale pojawia nam się inny problem.  

Problem polega na tym, że chcemy usunąć użytkowników natomiast nie wiemy, kiedy.
Powiedzmy, że mamy 5 serwerów i każdy z nich może obsługiwać jednocześnie 1000 osób – jeśli jest większy ruch to trzeba dostawić nowy. No i faktycznie w pewnym momencie mieliśmy po kilkaset osób wchodzących, jednak teraz ruch spadł i mamy 3 serwery, a na
każdym z nich zostało po 1 użytkowniku. Do ich obsługi oczywiście wystarczyłby nam 1 serwer, jednak nie możemy ich przerzucić, bo każdy z nich ma osobne sesje i stracilibyśmy do nich dostęp. Tak więc mimo, że teoretycznie moglibyśmy obsługiwać 1000 użytkowników na
jednym serwerze, jesteśmy w tej sytuacji zmuszeni trzymać te 3, ponieważ rozpoczęto już na nich sesje.  

Możemy wówczas zastosować rozwiązanie, które nazywa się server drainage i polega na wprowadzeniu maksymalnego czasu trwania sesji dla użytkownika. Czyli np. jeżeli w ciągu 15 minut użytkownik nie odpowie na wszystkie pytania dotyczące lotu to go usuwamy – dostaje informację, że sesja wygasła i musi rozpocząć proces od nowa.  

Chciałbym tutaj zrobić taką prostą analogię do kolejki w Lidlu. Ja sobie tam gdzieś stoję, wyłożyłem na taśmę swoje zakupy, jestem trzeci w kolejce i pani, która obsługuje prosi, żebym wziął plakietkę i na końcu położył – z informacją, że już dalej nie obsługujemy. Co to oznacza? Nowych klientów już nie obsłużymy, ale oczywiście tych którzy już wyłożyli swoje
produkty tak. Na podobnej zasadzie funkcjonuje server drainage – load balancer widzi, że serwer ma tylko kilka aktywnych sesji, więc przestaje kierować do niego nowych użytkowników. Natomiast te sesje,
które zostały już rozpoczęte mogą pozostać włączone – jednak ustawia się limit czasowy, np. tylko przez 15 minut. Inaczej użytkownik, który rozpoczął sesję i nie zakończył, mógłby taki serwer blokować w nieskończoność.

Co jeszcze możemy zrobić, żeby usprawnić ten proces? Najwygodniej byłoby, gdyby serwery mogły użytkowników między sobą przejmować – jak to zrobić? Istnieją dwa sposoby. Pierwszy z nich to zastosowanie tzw. serwerów sesji. Stawiamy sobie dodatkowy serwer, którego
jedynym zadaniem jest zbieranie informacji o sesjach. Działa to w ten sposób, że użytkownik przechodzi przez load balancer, a następnie jest kierowany do losowego serwera, który nie ma informacji o jego sesji. W pierwszym zapytaniu nie ma to znaczenia, serwer rozpoczyna sesję i informacje o niej wysyła na serwer sesyjny. Gdy użytkownik wyśle kolejne zapytanie, zostanie znów skierowany na losowy serwer, który z kolei wyśle zapytanie o sesję do serwera sesji. Dostanie z powrotem wszystkie dotychczasowe informacje i będzie mógł obłużyć użytkownika.

Drugim ze sposobów jest przechowywanie informacji o sesjach, zamiast na serwerze, w bazie danych. W tej sytuacji wszystkie serwery mają do niej dostęp i mogą z niej korzystać. Dane zwykle przechowywane są w tabeli – możemy tam znaleźć session ID i dodatkowe informacje na temat tego, co użytkownik aktualnie robi. Wówczas, kiedy klient wchodzi na stronę serwer
pobiera informacje z bazy i jest w stanie bez problemów go obsłużyć.

Na zakończenie, jest jeszcze jedna kwestia, którą chciałbym poruszyć. A mianowicie skąd właściwie mamy wiedzieć, ile powinniśmy usunąć serwerów i w jakim tempie to robić, kiedy zauważymy spadki w ruchu na stronie? Może się przecież zdarzyć sytuacja, że użytkownicy
przestaną wchodzić na naszą aplikację, my usuniemy 95% serwerów, ale po krótkim czasie okaże się, że ruch znowu znacząco wzrośnie i będziemy zmuszeni tworzyć nowe. Żeby uniknąć takiego przebiegu wydarzeń dajemy load balancerowi zazwyczaj określony czas zanim usunie kolejny serwer, np. 5 minut. Czas ten oczywiście jest do sprecyzowania
przez nas.  Dzięki temu w razie wzrostu ruchu jesteśmy przygotowani na nowych użytkowników. Wadą autoskalingu jest to, że wszystkie procesy trwają, także dużo rozsądniej jest poczekać dłużej z usunięciem serwera, niż później nie nadążać ze stawianiem nowych.
Czas, jaki potrzebuje nowy serwer, żeby się uruchomić to zwykle 3-4 minuty – równolegle nasz działający serwer stara się obsłużyć nowych użytkowników, ale nie daje rady, co kończy się najczęściej niedziałającą stroną z informacją typu time out.  

A jak myślicie, skąd load balancer wie, kiedy ma stawiać nowe serwery albo usuwać stare?
Otóż przez niego przechodzą informacje o ruchu więc wie on ile zapytań jest na każdym serwerze. Może więc ustalić limit 1000 requestów na serwer i pewien margines na uruchomienie nowego serwera, np. już przy 700 trzeba postawić nowy serwer, a przy spadku do 100 któryś z nich można usunąć. Load balancer może również badać obciążenie procesora – jeśli np. przy 90% się grzeje to jest to informacja, że trzeba uruchomić nowy serwer. Analogicznie, jeśli wykorzystuje tylko 10% mocy to znaczy, ze można usunąć. Można oczywiście również ustalić swoje własne parametry i ich górny/dolny pułap, na który load balancer ma odpowiednio reagować.   

To już wszystko w dzisiejszym artykule – tak właśnie działa auto scaling na chmurze. Mam nadzieję, że był dla Was przydatny i udało mi się choć trochę rozjaśnić, jak funkcjonuje autoskalowanie i w jaki sposób może się różnić w przypadku aplikacji bezsesyjnych oraz sesyjnych. Jeśli macie jakieś pytania lub wątpliwości to piszcie i dawajcie znać.