Apache Kafka – Optymalizacja – Ilu partycji potrzebuję?

softwareskill.pl 2 lat temu

Apache Kafka umożliwia ustawienie liczby partycji dla wszystkich topick’a. W jednej z dyskusji z osób z naszej społeczności padło pytanie: Jak obliczyć ile partycji potrzebuję?

Czym są Partycje w Apache Kafka?

Topic może zostać podzielony na wiele partycji (części), do których trafiają komunikaty. W ramach partycji kolejność komunikatów jest zagrawantowana, dlatego istotny jest wybór klucza, po którym komunikaty trafiają na daną partycję.

To, na którą partycję trafi dany komunikat określa funkcja implementująca interfejs Partitioner. Domyślnie jest to hash(klucz)%liczba_partycji. (hash to MurmurHash).

Dla przykładu, o ile składamy zamówienie i zarządzamy jego cyklem życia, powinniśmy zapewnić taki klucz, aby zdarzenia z nim związane (np. złożenie, anulowanie, zmiana statusu płatności) trafiała na jedną partycję. Zapobiegnie to sytuacji, w której kolejność przetwarzania zostanie zaburzona, np. najpierw dotrze komunikat o anulowaniu zamówienia (które nie zostanie znalezione), a następnie o jego stworzeniu.

W tym przypadku dobry pomysłem jest przykładowo wygenerowanie unikatowego identyfikatora zamówienia (nawet przed jego stworzeniem), do którego pozostałe operacje będą się odnosiły.

Co daje większa liczba partycji?

Partycje pozwalają na zrównoleglenie przetwarzania. Wielu konsumentów może czytać z wielu partycji jednocześnie, do tego zachowując kolejność przetwarzania. Partycje mogą zostać przydzielone na wielu brokerów, więc wiele maszyn może zostać zaangażowanych w takie przetwarzanie. To powoduje, iż system oparty o Apache Kafka jest tak szybki.

Konsumentom przydzielane są dane partycje do czytania. Możemy skalować nasz system, dodając nowych konsumentów. Nowym konsumentom zostaje przydzielana część ruchu, a innym odbierana. Jest to proces rebalancing’u.

Nie można dodawać konsumentów bez końca. o ile będzie istnieć więcej konsumentów, niż samych partycji, części z nich nie zostanie przydzielona partycja do czytania. Dzieje się tak, ponieważ każdą partycję czyta co najwyżej jeden konsument. o ile byłoby inaczej, zostałaby utracona kolejność przetwarzania komunikatów. Część z nich może się zatem nudzić.

Dochodzimy do zasadniczego pytania:

Ilu partycji potrzebuję?

Do problemu możemy podejść modelując idealny system, w którym czas przetwarzania każdego komunikatu jest taki sam. Oto wzór:

Przykład: przetwarzanie komunikatu trwa 50ms. Oczekujemy obciążenia systemu 50 req/s.

(50 req/s) * 0.05 s = 2.5 (czyli 3).

Inaczej: przetwarzanie komunikatu przez 50ms przez jednego konsumenta oznacza, iż podczas 1s zostanie przetworzonych max. 20 komunikatów (1000ms / 50ms = 20). o ile spodziewane obciążenie to 50 komunikatów na sekundę, to 50 / 20 (max jednego konsumenta), potrzebnych jest 3 konsumentów.

Należy zatem znać wymagania niefunkcjonalne:

  1. Oczekiwane obciążenie systemu, na które jesteśmy przygotowani
  2. Zmierzyć czas przetwarzania

Warto zaznaczyć, iż nie każdy komunikat przetwarzany jest taką samą ilość czasu. Należy zbadać system i określić charakterystykę. Jako czas można np. przyjąć medianę lub 90-ty percentyl czasu przetwarzania.

Psst… Interesujący artykuł?

Jeżeli podoba Ci się ten artykuł i chcesz takich więcej – dołącz do newslettera. Nie ominą Cię materiały tego typu.

Dołączam

Dziękujemy!

Wysłaliśmy Ci mail powitalny, w którym znajdziesz link do aktywacji newslettera. Do usłyszenia!

Czy mogę skalować liczbę partycji wzwyż?

Dodawanie partycji ma swoje zalety:

  • Większe zrównoleglenie przetwarzania i większa przepustowość. Liczba partycji określa wprost poziom zrównoleglenia, tworząc ich więcej, zwiększamy przepustowość.
  • Określenie większej liczby partycji oznacza możliwość uruchomienia większej liczby konsumentów w consumer group.
  • Jeżeli klaster jest złożony w wielu brokerów, mając więcej partycji wykorzystujemy ich zasoby. Przykładowo o ile mamy dwie partycje, będą umieszczone na dwóch brokerach, a reszta nie będzie obsługiwać tego topicka (poza replikacją).

Natomiast są też konsekwencje:

  • Każda partycja musi mieć swojego wybranego lidera. Im większa liczba partycji w klastrze, przy awarii brokerów dostępność klastra chwilowo spada.
  • Więcej plików otwartych przez Kafkę, trzeba uważać na limity systemu operacyjnego.
  • Więcej ruchu sieciowego przy replikacji danych.
  • Należy uważać na pamięć w consumerze, ponieważ w przypadku pobierania batch’ów wiadomości, przy dużej liczby partycji, a niewystarczającej liczbie konsumentów, może nie starczyć pamięci – należy zweryfikować te wartości.

Skalowanie w nieskończoność ma zatem swoje konsekwencje.

Confluent radzi, aby nie przekraczać liczby partycji na broker

100 x b x r

gdzie b to liczba brokerów, a r to replication factor.

Innymi kwestiami, które należy zdefiniować są:

Jaki jest zwyczajny load, a na jaki maksymalnie się przygotowujemy?

Jakie maksymalne latency jesteśmy w stanie zaakceptować?

Gdy przepustowość systemu nie pozwoli na przetworzenie n razy większego ruchu niż zazwyczaj, przez X minut, oznacza to, iż przez następny czas będziemy przetwarzać zaległe komunikaty. Ten czas można obliczyć przyjmując maksymalną przepustowość i liczbę nagromadzonych w tym czasie komunikatów.

Przykład: o ile przez 5 minut mamy 3x większy load, oznacza to, iż nagromadziło nam się komunikatów, które zajmą 10 minut dodatkowego przetwarzania (normalny load przez 5 minut + 2 razy tyle komunikatów, czyli kolejne 10 minut).

Uważaj przy dodawaniu nowych partycji

Przy dodawaniu partycji może ulec zmianie wynik funkcji hashującej. Przy domyślnej implementacji jest to hash(klucz)%liczba_partycji.

Uwaga! Może zatem zajść sytuacja, iż dana partycja, która była odpowiedzialna za przechowywanie komunikatów związanych z danym kluczem zmieni się. Wtedy ryzykujemy utratą kolejności odczytu podczas przypisania konsumenta do nowo utworzonej partycji.

Mamy dwa wyjścia:

  1. Mieć pewność, iż dotychczasowe komunikaty zostały już przetworzone.
  2. Przepisać cały topik.

Podsumowanie

Zwiększenie liczby partycji powoduje zrównoleglenie przetwarzania. Aby odpowiedzieć na pytanie jakiej liczby partycji potrzebuję, należy zdefiniować wymagania niefunkcjonalne, a w szczególności:

  • Określić oczekiwaną przepustowość systemu
  • Zmierzyć czas przetwarzania
  • Określić oczekiwania co do latency w przypadku zwiększonego ruchu

Podoba Ci się ten artykuł? Weź więcej.

Jeżeli uważasz ten materiał za wartościowy i chcesz więcej treści tego typu – nie przegap ich i otrzymuj je prosto na swoją skrzynkę. Nawiążmy kontakt.

Dołączam

Dziękujemy!

Wysłaliśmy Ci mail powitalny, w którym znajdziesz link do aktywacji newslettera. Do usłyszenia!

Gdybyś potrzebował jeszcze więcej:

Jesteś Java Developerem?

Przejdź na wyższy poziom wiedzy
„Droga do Seniora” 🔥💪

Chcę więcej wiedzy

Jesteś Team Leaderem? Masz zespół?

Podnieś efektywność i wiedzę swojego zespołu 👌

Sprawdź

Czytaj dalej

    Idź do oryginalnego materiału