artykuły

Przetwarzanie wsadowe w chmurze AWS

Brak komentarzy

Aplikacje, z którymi mamy do czynienia, bardzo często są związane z pewnego rodzaju interakcją z użytkownikiem. Obsługują one żądania, które są odzwierciedleniem procesów biznesowych zależnych od domeny, w której działają. Niejednokrotnie jednak pojawia się potrzeba przetwarzania danych w oderwaniu od interakcji z użytkownikiem. Potocznie takie zadania nazywamy zadaniami wsadowymi (batch job). W tym artykule przedstawię Ci sposoby uruchamiania zadań wsadowych w chmurze AWS.

Przykładami zadań wsadowych, o których pisałem wcześniej, mogą być:

  • Import lub eksport danych w integracji z firmą zewnętrzną.
  • Cykliczne przeliczanie lub modyfikacja danych w systemie.
  • Okresowo wykonywane operacje takie jak fakturowanie, wysyłka dokumentów czy tworzenie raportów.

Rodzajów zadań może być oczywiście więcej. Wszystko zależy od wymagań, które musimy spełnić. Inną kwestią jest natomiast sposób wywoływania tego typu zadań. Zasadniczo istnieją dwa typy wyzwalaczy:

  • Czasowy (time-based) – uruchamiamy zadanie cyklicznie, na przykład co godzinę lub raz w miesiącu.
  • Zdarzeniowy (event-based) – uruchamiamy zadanie w reakcji na pewne wydarzenie, na przykład pojawienie się pliku w pożądanej lokalizacji.

Najpierw przedstawię przykład procesu, który będę chciał zaimplementować, a następnie możliwe rozwiązania techniczne.

Przykładowy problem

W celu pokazania, w jaki sposób można zaimplementować przetwarzanie wsadowe przy użyciu chmury AWS, posłużę się prostym przykładem. Załóżmy, że na pewnym buckecie S3 pojawiają się cyklicznie pliki, które musimy przetworzyć. Proces ten polega na przeczytaniu ich zawartości, zapisaniu informacji w bazie danych, opublikowaniu wiadomości na topic SNS, a na końcu przeniesieniu przetworzonego pliku na inny bucket S3. W analizie możliwych rozwiązań nie będę się skupiać na szczegółach implementacyjnych, ani na szczegółach analizowanej domeny.

Ogólny schemat przykładowego zadania wsadowego

Wyzwalacz oparty o harmonogram

Pierwszym ze sposobów uruchomienia zadania wsadowego jest wyzwalacz oparty o harmonogram. Jest przydatny w scenariuszu, kiedy chcemy uruchamiać przetwarzanie cyklicznie.

Ogólny schemat przykładowego zadania wsadowego, uruchamianego za pomocą wyzwalacza opartego o harmonogram

Wyzwalacz oparty o zdarzenie

Drugim ze sposobów uruchomienia zadania wsadowego jest wyzwalacz oparty o zdarzenie. Jest przydatny w scenariuszu, kiedy chcemy uruchamiać przetwarzanie, gdy tylko nastąpi pewne zdarzenie. W tym przypadku jest to pojawienie się nowych plików na buckecie S3.

Ogólny schemat przykładowego zadania wsadowego, uruchamianego za pomocą wyzwalacza opartego o zdarzenie

AWS Lambda

Pierwszy sposób implementacji powyżej opisanego procesu bazuje na serwisie AWS Lambda. To zdecydowanie najprostszy, najszybszy i najtańszy sposób zrealizowania takiej funkcjonalności. Istnieją jednak ograniczenia, na które trzeba zwrócić uwagę. Po pierwsze jest to limit czasu wykonywania funkcji. Twardym limitem działania funkcji Lambda jest 15 minut. Jeżeli przetwarzanie, które chcemy zaimplementować, będzie trwało dłużej, należy pomyśleć o innym rozwiązaniu. Drugim z ograniczeń jest limit pamięci, którą możemy przydzielić. Jest to maksymalnie 3008 MB. W niektórych scenariuszach może to być zbyt mała liczba.

Wyzwalacz oparty o harmonogram

Chcąc zrealizować cyklicznie uruchamianą funkcję Lambda, najlepiej posłużyć się Eventem CloudWatch. Tworząc odpowiednią regułę, możemy skonfigurować ją na dwa sposoby. Pierwszym z nich jest uruchamianie się w określonych momentach w czasie (cron expressions). Drugim jest uruchamianie co pewien interwał czasu (rate expressions). Więcej na ten temat znajdziesz tutaj. Przy tworzeniu opisanej reguły należy również podać funkcję Lambda jako target.

Schemat przykładowego zadania wsadowego zrealizowanego przy użyciu funkcji Lambda, uruchamianej za pomocą wyzwalacza opartego o harmonogram

Wyzwalacz oparty o zdarzenie

W celu zrealizowania scenariusza, w którym chcemy wywołać zadanie bezpośrednio po pojawieniu się nowego obiektu w buckecie S3, należy skonfigoruwać event notification. Korzystając z tego mechanizmu, funkcja Lambda zostanie wywołana zaraz po pojawieniu się nowego obiektu o pasującym szablonie w skonfigurowanej lokalizacji.

Schemat przykładowego zadania wsadowego zrealizowanego przy użyciu funkcji Lambda, uruchamianej za pomocą wyzwalacza opartego o zdarzenie

Amazon ECS

W sytuacjach, kiedy potrzebujemy dłuższego działania zadania niż 15 minut lub większej ilości pamięci niż 3008 MB, musimy skorzystać z innego rozwiązania. Może nim być wykorzystanie usługi Amazon ECS, która pozwala na orkiestrację kontenerów. Zadanie zdefiniowane w ECS korzysta z obrazów dockerowych przechowywanych w Amazon ECR – zarządzanego rejestru obrazów dockerowych na AWS.

Wyzwalacz oparty o harmonogram

Żeby wywołać zadanie zdefiniowane w ECS, najlepiej jest stworzyć odpowiednią regułę CloudWatch (tak jak w przypadku Lambdy). Jedyną zmianą będzie wybranie jako target ECS Task – zamiast funkcji Lambda.

Schemat przykładowego zadania wsadowego zrealizowanego przy użyciu zadania Amazon ECS, uruchamianego za pomocą wyzwalacza opartego o harmonogram

Wyzwalacz oparty o zdarzenie

Zrealizowanie przypadku, w którym wywołujemy zadanie po pojawieniu się obiektu w buckecie S3, nie jest tak banalne jak w przypadku Lambdy. Nie dysponujemy żadnym mechanizmem, dzięki któremu możemy bezpośrednio spełnić to wymaganie. W tym wypadku musimy niejako połączyć rozwiązanie oparte na ECS z rozwiązaniem opartym na Lambdzie i wykorzystać ten sam mechanizm, który został opisany wcześniej. Funkcja Lambda powinna zostać wywołana automatycznie po pojawieniu się obiektu w buckecie S3 i powinna zająć się rozpoczęciem zadania w ECS.

Schemat przykładowego zadania wsadowego zrealizowanego przy użyciu zadania Amazon ECS, uruchamianego za pomocą wyzwalacza opartego o zdarzenie

AWS Batch

W przypadku, kiedy potrzebujemy wywołać bardziej złożone zadanie, które planujemy skalować do wielu instancji lub wywoływać array jobs, warto rozważyć użycie AWS Batch. Do uruchomienia zadania w ten sposób potrzebujemy kilku elementów. Przede wszystkim musimy stworzyć definicję zadania, w którym (podobnie jak w ECS) wskażemy, z jakiego obrazu dockerowego w ECR chcemy skorzystać. Oprócz tego musimy wprowadzić definicję środowiska uruchomieniowego, określając parametry maszyn, na jakich nasze zadania zostaną uruchomione. Posiadając te definicje, zadania na AWS Batch uruchamiane są w sposób w pełni zarządzany przez AWS, w momencie pojawienia się nowych wiadomości w kolejce zadania.

Wyzwalacz oparty o harmonogram

Tak jak w poprzednich przykładach możemy z powodzeniem zintegrować reguły CloudWatch z AWS Batch. W tym przypadku jako target powinniśmy ustawić Batch job queue.

Schemat przykładowego zadania wsadowego zrealizowanego przy użyciu zadania AWS Batch, uruchamianego za pomocą wyzwalacza opartego o harmonogram

Wyzwalacz oparty o zdarzenie

Podobnie jak w przypadku ECS, nie mamy wbudowanego mechanizmu, który pozwalałby na uruchomienie zadania w AWS Batch w reakcji na zdarzenie pojawienia się nowego pliku w buckecie S3. Musimy posłużyć się wcześniej opisanym mechanizmem pośredniej funkcji Lambda, która tym razem w reakcji na zdarzenie wyśle wiadomość do kolejki zadania AWS Batch.

Schemat przykładowego zadania wsadowego zrealizowanego przy użyciu zadania AWS Batch, uruchamianego za pomocą wyzwalacza opartego o zdarzenie

AWS Elastic Beanstalk

Kolejną możliwą realizacją zadań wsadowych jest wykorzystanie worker environments usługi AWS Elastic Beanstalk. Rozwiązanie polega na stworzeniu dedykowanego środowiska, które będzie odpowiedzialne za obsługę właśnie procesów wsadowych. Środowisko korzysta z dedykowanej kolejki, do której napływają żądania wykonania zadania. Może obsługiwać więcej typów operacji, a wybór odpowiedniej odbywa się poprzez wysłanie właściwej wiadomości do kolejki. Rozwiązanie jest przydatne przede wszystkim w sytuacjach, gdzie zadania wsadowe są bezpośrednio połączone z aplikacją wdrożoną za pomocą usługi Elastic Beanstalk. Daje nam to możliwość zarządzania komponentami systemu w jednym miejscu. Musimy jednak pamiętać, że zarządzanie środowiskiem leży po naszej stronie, więc musimy zadbać o odpowiednie jego skalowanie (również do zera).

Wyzwalacz oparty o harmonogram

Tym razem nie potrzebujemy dodatkowego elementu, jakim był CloudWatch Event. Elastic Beanstalk oferuje okresowe uruchamianie zadań na środowisku dzięki funkcjonalności Periodic tasks. Musimy jedynie zdefiniować, w jakim czasie i które zadania powinny zostać wywołane.

Schemat przykładowego zadania wsadowego zrealizowanego przy użyciu AWS Elastic Beanstalk worker, uruchamianego za pomocą wyzwalacza opartego o harmonogram

Wyzwalacz oparty o zdarzenie

Ponownie nie jesteśmy w stanie zapewnić takiej funkcjonalności bez angażowania pośredniej Lambdy. Czy skoro dysponujemy kolejką SQS, możemy bezpośrednio wysłać na nią zdarzenie z bucketa S3? Nie możemy tego zrobić. Wiadomość musi posiadać szczególne atrybuty z informacjami na temat tego, jakie zadanie powinno zostać uruchomione i w jakim czasie. Taką wiadomość możemy skonstruować (tak jak w poprzednich przykładach) w dodatkowej funkcji Lambda, która wyśle ją do odpowiedniej kolejki.

Schemat przykładowego zadania wsadowego zrealizowanego przy użyciu AWS Elastic Beanstalk worker, uruchamianego za pomocą wyzwalacza opartego o zdarzenie

Podsumowanie

Przedstawiłem kilka sposobów na uruchamianie zadań wsadowych w chmurze AWS. Każdy z nich jest przydatny w nieco innych przypadkach. Z punktu widzenia łatwości wdrożenia oraz kosztów zdecydowanie najlepiej wypada rozwiązanie oparte tylko na funkcji Lambda. Jak jednak wspomniałem, nie nadaje się w przypadkach, gdzie potrzebujemy więcej czasu na przetworzenie danych lub większej ilości pamięci. W takiej sytuacji warto jest rozważyć użycie ECS. Rozwiązanie oparte na AWS Batch powinniśmy wybierać w bardziej skomplikowanych przypadkach – takich jak równoczesne wywoływanie kilku powiązanych zadań lub grupy zadań. Implementację AWS Elastic Beanstalk worker environment możemy rozważyć, gdy mamy do czynienia z inną, symbiotyczną aplikacją, która działa w usłudze AWS Elastic Beanstalk.

Tags: , , ,

Powiązane artykuły

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

Wypełnij to pole
Wypełnij to pole
Proszę wprowadzić prawidłowy adres email.
You need to agree with the terms to proceed

Menu