2016-11-11 40 views
6

Napotkałem pytanie z równoważeniem obciążenia w kafejce. Stworzyłem więc temat z 10 partycjami i utworzyłem 2 klientów. Dziesięć partycji zostało podzielonych i przypisanych do tych konsumentów (5 partycji do pierwszej i 5 do drugiej) i działa dobrze. Czasami pierwszy konsument pracuje, czasem drugi.Jak ładuje się saldo kafka?

Ale w pewnym momencie możemy spotkać się z sytuacją, gdy na przykład drugi konsument otrzymuje wiadomość i potrzeba czasu (na przykład 10 minut) na obsłużenie tej wiadomości.

Moje pytanie brzmi: jak kafka zdecyduje, w której partycji przechowywać wiadomość?

W tym przypadku robota typu round robin nie jest dobrym pomysłem, ponieważ wiadomości w partycjach obsługiwanych przez drugiego użytkownika nie będą obsługiwane, dopóki drugi konsument nie zakończy długich prac.

Zaktualizowano!

Zgodnie z odpowiedzią @Milan Baran obciążenie jest zrównoważone po stronie producenta. Ale w tym przypadku, nawet jeśli zapewniamy niestandardową realizację, będzie to ten sam problem, że wiadomość, która była przechowywana w partycji, która została przypisana konsumentowi, który wykonuje długoterminową pracę, nie zostanie przetworzona, dopóki ten konsument kończy swoją długoterminową pracę.

Być może gdzieś jest dodatkowy system równoważenia obciążenia?

+0

Dlaczego po prostu nie uruchomisz większej liczby klientów? Jeśli uruchomisz 10 klientów, a następnie jeden będzie zajęty przez dłuższy czas, nadal będziesz mieć 9 dodatkowych operacji przetwarzania danych na pozostałych 9 partycjach. –

+0

Jednak wszystkie wiadomości na partycji 10-owej nie są przetwarzane, dopóki nie są zajęte. Oto problem. –

+0

Czy możesz napisać niestandardowy program do partycjonowania, który umieszcza długie komunikaty w specjalnej partycji, aby wszystkie małe mogły być partycjonowane i przetwarzane na pozostałych partycjach? –

Odpowiedz

2

Dziękuję wszystkim za pomoc. Ale znalazłem odpowiedź na moje pytanie.Więc przede wszystkim, istnieją co najmniej 3 miejsca gdzie Kafka równoważy obciążenie:

  1. Aby przypisać partycji dla konsumentów „round robin” lub „zasięg” algorytmy są wykorzystywane. Można to skonfigurować, ustawiając właściwość partition.assignment.strategy. Domyślnie używany jest zakres.
  2. Na poziomie producenta można zastosować strategię wyboru partycji do przechowywania wiadomości. Można to zrobić przez partitioner.class
  3. A odpowiedź na moje pytanie. Jeśli jeden konsument przetwarza komunikat przez długi czas, kafka uważa, że ​​ten konsument nie działa, a ponownie przypisuje partycje innym użytkownikom. Tak więc, gdy zadanie jest wykonywane przez użytkownika długo, nie są do niego przypisywane żadne partycje. Gdy klient zakończy pracę na długim etacie, partycje zostaną ponownie przypisane do . I żadne wiadomości nie będą w toku.
2

Decyzja, która partycja powinna zostać użyta, nie należy do kafka, ale producent wysyłający wiadomość musi zdecydować. Spójrz na https://kafka.apache.org/documentation#producerconfigs

Możesz podać klasę partycjonera, aby zdecydować, którą partycję wybrać.

partitioner.class
klasy partycjonowania, który implementuje interfejs partycjonowania. org.apache.kafka.clients.producer.internals.DefaultPartitioner

Jest opis strategii DefaultPartitioner

/** 
* The default partitioning strategy: 
* <ul> 
* <li>If a partition is specified in the record, use it 
* <li>If no partition is specified but a key is present choose a partition based on a hash of the key 
* <li>If no partition or key is present choose a partition in a round-robin fashion 
*/ 
+0

Twoja odpowiedź jest dobra, ale wydaje mi się, że istnieje dodatkowe miejsce, w którym obciążenie jest zrównoważone. Zgodnie z twoją odpowiedzią wydaje się, że nie ma sposobu, aby przetworzyć wiadomość przechowywaną w partycji, która została przypisana konsumentowi, który wykonuje pracę długoterminową. –

+0

Co masz na myśli, mówiąc o pracy długoterminowej? Czy ustawiłeś różne group.id dla konsumentów? Lub przetwarzasz wiadomości w tym samym wątku, co odczyty konsumenta. Na przykład otrzymasz: fast_msg, fast_msg, fast_msg, slow_msg, fast_msg i utkniesz na slow_msg i nie możesz uzyskać następnego fast_msg? W takim przypadku użyj paralelizmu do przetwarzania tych wiadomości lub strumieni akka. –

+0

Używanie różnych wątków do odbierania i przetwarzania komunikatów spowoduje dodatkowy problem: mam slow_msg fast_msg1 fast_msg2 fast_msg3, mogę stanąć w obliczu sytuacji, gdy slow_msg nadal przetwarza, ale fast_msg1 i fast_msg2 są pomyślnie przetwarzane, a następnie jvm ulega awarii. Po restarcie mój konsument zostanie wskazany na fast_msg3, a slow_msg zostanie utracone. –

2

Wydaje się, czego potrzebujesz to KOLEJKA. ONE Partycja jest konsumowana przez MULTIPLE konsumentów. Każdy konsument pobiera zapis z partycji, przetwarza ją i pobiera inny. Jeśli jeden konsument zajmuje zbyt dużo czasu na przetworzenie rekordu, inni mogą nadal pobierać (różne) rekordy z partycji.

Jednak Kafka ma NOT obsługuje to. Każda partycja może być zużywana tylko przez jednego konsumenta w grupie konsumenckiej.

Jednym słowem, potrzebujesz czegoś innego, aby osiągnąć cel, na przykład RabbitMQ.