Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Notatka. przeł.: W tym artykule Banzai Cloud udostępnia przykład wykorzystania niestandardowych narzędzi, aby ułatwić korzystanie z platformy Kafka w Kubernetes. Poniższe instrukcje ilustrują, jak określić optymalny rozmiar infrastruktury i skonfigurować samą platformę Kafka, aby osiągnąć wymaganą przepustowość.

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Apache Kafka to rozproszona platforma do przesyłania strumieniowego służąca do tworzenia niezawodnych, skalowalnych i wydajnych systemów przesyłania strumieniowego w czasie rzeczywistym. Jego imponujące możliwości można rozszerzyć za pomocą Kubernetes. W tym celu opracowaliśmy Operator Open Source Kafka oraz narzędzie tzw Supertuby. Umożliwiają uruchomienie Kafki na Kubernetesie i korzystanie z jego różnych funkcji, takich jak dostrajanie konfiguracji brokera, skalowanie oparte na metrykach z ponownym równoważeniem, świadomość stojaka, „miękkość” (wdzięczny) wprowadzanie aktualizacji itp.

Wypróbuj Supertubes w swoim klastrze:

curl https://getsupertubes.sh | sh и supertubes install -a --no-democluster --kubeconfig <path-to-eks-cluster-kubeconfig-file>

Lub skontaktuj się dokumentacja. Możesz także przeczytać o niektórych możliwościach Kafki, z którą praca jest zautomatyzowana za pomocą Supertubes i operatora Kafki. Pisaliśmy już o nich na blogu:

Decydując się na wdrożenie klastra Kafka na platformie Kubernetes, prawdopodobnie staniesz przed wyzwaniem określenia optymalnego rozmiaru podstawowej infrastruktury i koniecznością dostosowania konfiguracji Kafki, aby spełniała wymagania dotyczące przepustowości. Maksymalna wydajność każdego brokera jest określana na podstawie wydajności podstawowych komponentów infrastruktury, takich jak pamięć, procesor, szybkość dysku, przepustowość sieci itp.

W idealnym przypadku konfiguracja brokera powinna zapewniać maksymalne wykorzystanie wszystkich elementów infrastruktury. Jednak w prawdziwym życiu konfiguracja ta jest dość złożona. Bardziej prawdopodobne jest, że użytkownicy skonfigurują brokery tak, aby zmaksymalizować wykorzystanie jednego lub dwóch komponentów (dysku, pamięci lub procesora). Ogólnie rzecz biorąc, broker wykazuje maksymalną wydajność, gdy jego konfiguracja pozwala na maksymalne wykorzystanie najwolniejszego komponentu. W ten sposób możemy uzyskać przybliżone pojęcie o obciążeniu, jakie może obsłużyć jeden broker.

Teoretycznie możemy również oszacować liczbę brokerów wymaganych do obsługi danego ładunku. Jednak w praktyce istnieje tak wiele opcji konfiguracji na różnych poziomach, że bardzo trudno (jeśli nie niemożliwe) ocenić potencjalną wydajność konkretnej konfiguracji. Innymi słowy, bardzo trudno jest zaplanować konfigurację w oparciu o określoną wydajność.

W przypadku użytkowników Supertubes zwykle stosujemy następujące podejście: zaczynamy od konfiguracji (infrastruktura + ustawienia), następnie mierzymy jego wydajność, dostosowujemy ustawienia brokera i powtarzamy proces od nowa. Dzieje się tak do momentu pełnego wykorzystania najwolniejszego elementu infrastruktury.

W ten sposób mamy jaśniejszy pogląd, ilu brokerów potrzebuje klaster, aby obsłużyć określone obciążenie (liczba brokerów zależy także od innych czynników, takich jak minimalna liczba replik komunikatów zapewniająca odporność, liczba partycji liderzy itp.). Dodatkowo zyskujemy wgląd w to, które elementy infrastruktury wymagają skalowania w pionie.

W tym artykule omówiono kroki, które podejmujemy, aby maksymalnie wykorzystać najwolniejsze komponenty w początkowych konfiguracjach i zmierzyć przepustowość klastra Kafka. Konfiguracja o dużej odporności wymaga co najmniej trzech działających brokerów (min.insync.replicas=3), rozmieszczonych w trzech różnych strefach dostępności. Do konfiguracji, skalowania i monitorowania infrastruktury Kubernetes wykorzystujemy własną platformę do zarządzania kontenerami dla chmur hybrydowych - Rurociąg. Obsługuje on-premise (bare metal, VMware) i pięć typów chmur (Alibaba, AWS, Azure, Google, Oracle), a także dowolną ich kombinację.

Rozważania na temat infrastruktury i konfiguracji klastra Kafki

W poniższych przykładach wybraliśmy AWS jako dostawcę chmury i EKS jako dystrybucję Kubernetes. Podobną konfigurację można zaimplementować za pomocą P.K.E. - Dystrybucja Kubernetes z Banzai Cloud, certyfikowana przez CNCF.

dysk

Amazon oferuje różne Typy woluminów EBS. U źródła gp2 и io1 istnieją jednak dyski SSD, aby zapewnić wysoką przepustowość gp2 zużywa zgromadzone kredyty (Kredyty we/wy), więc woleliśmy ten typ io1, który zapewnia stałą, wysoką przepustowość.

Typy instancji

Wydajność Kafki w dużym stopniu zależy od pamięci podręcznej stron systemu operacyjnego, dlatego potrzebujemy instancji z wystarczającą ilością pamięci dla brokerów (JVM) i pamięci podręcznej stron. Instancja c5.2xduże - dobry początek, skoro ma 16 GB pamięci i zoptymalizowany do współpracy z EBS. Jego wadą jest to, że jest w stanie zapewnić maksymalną wydajność tylko przez nie więcej niż 30 minut na dobę. Jeśli Twoje obciążenie wymaga najwyższej wydajności przez dłuższy okres czasu, możesz rozważyć inne typy instancji. Dokładnie to zrobiliśmy, zatrzymując się c5.4xduże. Zapewnia maksymalną przepustowość w 593,75 Mb/s. Maksymalna przepustowość woluminu EBS io1 wyższa niż instancja c5.4xduże, więc najwolniejszym elementem infrastruktury będzie prawdopodobnie przepustowość we/wy tego typu instancji (co powinny również potwierdzić nasze testy obciążenia).

Sieć

Przepustowość sieci musi być wystarczająco duża w porównaniu z wydajnością instancji maszyny wirtualnej i dysku, w przeciwnym razie sieć stanie się wąskim gardłem. W naszym przypadku interfejs sieciowy c5.4xduże obsługuje prędkości do 10 Gb/s, czyli znacznie więcej niż przepustowość we/wy instancji maszyny wirtualnej.

Wdrożenie brokera

Brokery należy wdrożyć (zaplanowano w Kubernetes) w dedykowanych węzłach, aby uniknąć konkurowania z innymi procesami o zasoby procesora, pamięci, sieci i dysku.

Wersja Java

Logicznym wyborem jest Java 11, ponieważ jest kompatybilna z Dockerem w tym sensie, że JVM poprawnie określa procesory i pamięć dostępną dla kontenera, w którym działa broker. Wiedząc, że limity procesora są ważne, JVM wewnętrznie i przejrzyście ustawia liczbę wątków GC i wątków JIT. Użyliśmy obrazu Kafki banzaicloud/kafka:2.13-2.4.0, który obejmuje wersję Kafka 2.4.0 (Scala 2.13) na Javie 11.

Jeśli chcesz dowiedzieć się więcej o Javie/JVM na Kubernetesie, sprawdź nasze poniższe wpisy:

Ustawienia pamięci brokera

Istnieją dwa kluczowe aspekty konfigurowania pamięci brokera: ustawienia maszyny JVM i modułu Kubernetes. Limit pamięci ustawiony dla poda musi być większy niż maksymalny rozmiar sterty, aby maszyna JVM miała miejsce na metaprzestrzeń Java znajdującą się w jej własnej pamięci oraz na pamięć podręczną stron systemu operacyjnego, z której aktywnie korzysta Kafka. W naszych testach uruchomiliśmy brokerów Kafka z parametrami -Xmx4G -Xms2G, a limit pamięci dla kapsuły wynosił 10 Gi. Należy pamiętać, że ustawienia pamięci dla JVM można uzyskać automatycznie za pomocą -XX:MaxRAMPercentage и -X:MinRAMPercentage, w oparciu o limit pamięci dla modułu.

Ustawienia procesora brokera

Ogólnie rzecz biorąc, wydajność można poprawić, zwiększając równoległość, zwiększając liczbę wątków używanych przez Kafkę. Im więcej procesorów dostępnych dla Kafki, tym lepiej. W naszym teście zaczynaliśmy od limitu 6 procesorów i stopniowo (poprzez iteracje) zwiększaliśmy ich liczbę do 15. Dodatkowo ustawiliśmy num.network.threads=12 w ustawieniach brokera, aby zwiększyć liczbę wątków odbierających dane z sieci i wysyłających je. Natychmiast odkrywając, że brokerzy obserwujący nie mogą otrzymywać replik wystarczająco szybko, podbili num.replica.fetchers do 4, aby zwiększyć prędkość, z jaką brokerzy obserwujący replikują wiadomości od liderów.

Narzędzie do generowania obciążenia

Należy upewnić się, że wybranemu generatorowi obciążenia nie zabraknie mocy, zanim klaster Kafki (który jest testowany) osiągnie maksymalne obciążenie. Innymi słowy, konieczne jest przeprowadzenie wstępnej oceny możliwości narzędzia do generowania obciążenia, a także wybranie dla niego typów instancji z odpowiednią liczbą procesorów i pamięci. W tym przypadku nasze narzędzie wygeneruje większe obciążenie niż klaster Kafki jest w stanie obsłużyć. Po wielu eksperymentach zdecydowaliśmy się na trzy egzemplarze c5.4xduże, z których każdy miał działający generator.

Analiza porównawcza

Pomiar wydajności to proces iteracyjny, który obejmuje następujące etapy:

  • konfigurowanie infrastruktury (klaster EKS, klaster Kafka, narzędzie do generowania obciążenia, a także Prometheus i Grafana);
  • generowanie obciążenia na określony czas w celu filtrowania przypadkowych odchyleń w zebranych wskaźnikach wydajności;
  • dostosowywanie infrastruktury i konfiguracji brokera w oparciu o zaobserwowane wskaźniki wydajności;
  • powtarzanie procesu do momentu osiągnięcia wymaganego poziomu przepustowości klastra Kafki. Jednocześnie musi być stale powtarzalny i wykazywać minimalne różnice w wydajności.

W następnej sekcji opisano kroki, które zostały wykonane podczas procesu benchmarkingu klastra testowego.

Narzędzia

Do szybkiego wdrożenia konfiguracji bazowej, wygenerowania obciążeń i pomiaru wydajności wykorzystano następujące narzędzia:

  • Rurociąg chmurowy Banzai za zorganizowanie klastra EKS z Amazon c Prometheus (w celu gromadzenia wskaźników Kafki i infrastruktury) oraz grafana (aby zwizualizować te wskaźniki). Skorzystaliśmy zintegrowany в Rurociąg usługi zapewniające stowarzyszone monitorowanie, scentralizowane gromadzenie dzienników, skanowanie pod kątem luk w zabezpieczeniach, odzyskiwanie po awarii, bezpieczeństwo klasy korporacyjnej i wiele więcej.
  • Sangrenel — narzędzie do testowania obciążenia klastra Kafki.
  • Pulpity nawigacyjne Grafana do wizualizacji metryk i infrastruktury Kafki: Kubernetesa Kafki, Eksporter węzłów.
  • Interfejs CLI Supertubes umożliwiający najłatwiejszą konfigurację klastra Kafki w Kubernetesie. Zookeeper, operator Kafka, Envoy i wiele innych komponentów jest zainstalowanych i odpowiednio skonfigurowanych do uruchomienia gotowego do produkcji klastra Kafka na platformie Kubernetes.
    • Do instalacji Supertube CLI skorzystaj z podanych instrukcji tutaj.

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Klaster EKS

Przygotuj klaster EKS z dedykowanymi węzłami roboczymi c5.4xduże w różnych strefach dostępności dla podów z brokerami Kafka, a także w dedykowanych węzłach dla generatora obciążenia i infrastruktury monitorującej.

banzai cluster create -f https://raw.githubusercontent.com/banzaicloud/kafka-operator/master/docs/benchmarks/infrastructure/cluster_eks_202001.json

Po uruchomieniu klastra EKS włącz jego funkcję zintegrowaną usługę monitoringu — umieści Prometeusza i Grafanę w klastrze.

Elementy systemu Kafka

Zainstaluj komponenty systemu Kafka (Zookeeper, kafka-operator) w EKS przy użyciu interfejsu CLI supertubes:

supertubes install -a --no-democluster --kubeconfig <path-to-eks-cluster-kubeconfig-file>

Gromada Kafki

Domyślnie EKS używa woluminów typu EBS gp2, dlatego musisz utworzyć oddzielną klasę pamięci na podstawie woluminów io1 dla klastra Kafki:

kubectl create -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  iopsPerGB: "50"
  fsType: ext4
volumeBindingMode: WaitForFirstConsumer
EOF

Ustaw parametr dla brokerów min.insync.replicas=3 i wdrażaj moduły brokerów na węzłach w trzech różnych strefach dostępności:

supertubes cluster create -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file> -f https://raw.githubusercontent.com/banzaicloud/kafka-operator/master/docs/benchmarks/infrastructure/kafka_202001_3brokers.yaml --wait --timeout 600

Tematy

Uruchomiliśmy równolegle trzy instancje generatora obciążenia. Każdy z nich pisze na swój własny temat, czyli w sumie potrzebujemy trzech tematów:

supertubes cluster topic create -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file> -f -<<EOF
apiVersion: kafka.banzaicloud.io/v1alpha1
kind: KafkaTopic
metadata:
  name: perftest1
spec:
  name: perftest1
  partitions: 12
  replicationFactor: 3
  retention.ms: '28800000'
  cleanup.policy: delete
EOF

supertubes cluster topic create -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file> -f -<<EOF
apiVersion: kafka.banzaicloud.io/v1alpha1
kind: KafkaTopic
metadata:
    name: perftest2
spec:
  name: perftest2
  partitions: 12
  replicationFactor: 3
  retention.ms: '28800000'
  cleanup.policy: delete
EOF

supertubes cluster topic create -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file> -f -<<EOF
apiVersion: kafka.banzaicloud.io/v1alpha1
kind: KafkaTopic
metadata:
  name: perftest3
spec:
  name: perftest3
  partitions: 12
  replicationFactor: 3
  retention.ms: '28800000'
  cleanup.policy: delete
EOF

Dla każdego tematu współczynnik replikacji wynosi 3 — minimalna zalecana wartość dla systemów produkcyjnych o wysokiej dostępności.

Narzędzie do generowania obciążenia

Uruchomiliśmy trzy kopie generatora obciążenia (każdy pisał w osobnym temacie). W przypadku zasobników generatora obciążenia należy ustawić powinowactwo węzłów, tak aby były one zaplanowane tylko w przydzielonych im węzłach:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: loadtest
  name: perf-load1
  namespace: kafka
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: loadtest
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: loadtest
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: nodepool.banzaicloud.io/name
                operator: In
                values:
                - loadgen
      containers:
      - args:
        - -brokers=kafka-0:29092,kafka-1:29092,kafka-2:29092,kafka-3:29092
        - -topic=perftest1
        - -required-acks=all
        - -message-size=512
        - -workers=20
        image: banzaicloud/perfload:0.1.0-blog
        imagePullPolicy: Always
        name: sangrenel
        resources:
          limits:
            cpu: 2
            memory: 1Gi
          requests:
            cpu: 2
            memory: 1Gi
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

Kilka punktów, na które warto zwrócić uwagę:

  • Generator obciążenia generuje komunikaty o długości 512 bajtów i publikuje je w Kafce w partiach po 500 komunikatów.
  • Używanie argumentu -required-acks=all Publikację uznaje się za udaną, gdy wszystkie zsynchronizowane repliki wiadomości zostaną odebrane i potwierdzone przez brokerów Kafki. Oznacza to, że w benchmarku zmierzyliśmy nie tylko szybkość otrzymywania komunikatów przez liderów, ale także ich replikacji przez ich zwolenników. Celem tego testu nie jest ocena szybkości czytania przez konsumenta (konsumenci) ostatnio odebranych wiadomości, które nadal pozostają w pamięci podręcznej stron systemu operacyjnego, i jej porównanie z szybkością odczytu wiadomości przechowywanych na dysku.
  • Generator obciążenia obsługuje równolegle 20 procesów roboczych (-workers=20). Każdy proces roboczy zawiera 5 producentów, którzy dzielą połączenie pracownika z klastrem Kafka. W efekcie każdy generator ma 100 producentów i wszyscy oni wysyłają wiadomości do klastra Kafki.

Monitorowanie kondycji klastra

Podczas testów obciążenia klastra Kafka monitorowaliśmy także jego stan, aby upewnić się, że nie ma ponownych uruchomień podów, replik niezsynchronizowanych i maksymalnej przepustowości przy minimalnych wahaniach:

  • Generator obciążenia zapisuje standardowe statystyki dotyczące liczby opublikowanych wiadomości i poziomu błędów. Poziom błędu powinien pozostać taki sam 0,00%.
  • Cruise Control, wdrożony przez operatora kafka, udostępnia dashboard, na którym możemy także monitorować stan klastra. Aby wyświetlić ten panel, wykonaj:
    supertubes cluster cruisecontrol show -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file>
  • Poziom ISR (liczba „zsynchronizowanych” replik) kurczenie się i rozszerzanie są równe 0.

Wyniki pomiarów

3 brokerów, rozmiar wiadomości - 512 bajtów

Dzięki partycjom równomiernie rozłożonym na trzech brokerów udało nam się osiągnąć wydajność ~500 Mb/s (około 990 tysięcy wiadomości na sekundę):

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Zużycie pamięci maszyny wirtualnej JVM nie przekroczyło 2 GB:

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Przepustowość dysku osiągnęła maksymalną przepustowość węzła we/wy we wszystkich trzech instancjach, na których działały brokery:

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Z danych dotyczących wykorzystania pamięci przez węzły wynika, że ​​buforowanie i buforowanie systemu zajmowało ~10-15 GB:

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

3 brokerów, rozmiar wiadomości - 100 bajtów

W miarę zmniejszania się rozmiaru wiadomości przepustowość spada o około 15–20%: wpływa na to czas spędzony na przetwarzaniu każdej wiadomości. Ponadto obciążenie procesora wzrosło prawie dwukrotnie.

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Ponieważ węzły brokera nadal mają niewykorzystane rdzenie, wydajność można poprawić, zmieniając konfigurację platformy Kafka. Nie jest to łatwe zadanie, dlatego aby zwiększyć przepustowość, lepiej pracować z większymi wiadomościami.

4 brokerów, rozmiar wiadomości - 512 bajtów

Możesz łatwo zwiększyć wydajność klastra Kafki, po prostu dodając nowych brokerów i utrzymując równowagę partycji (zapewni to równomierne rozłożenie obciążenia pomiędzy brokerami). W naszym przypadku po dodaniu brokera przepustowość klastra wzrosła do ~580 Mb/s (~1,1 miliona wiadomości na sekundę). Wzrost okazał się mniejszy niż oczekiwano: wynika to głównie z braku równowagi przegród (nie wszyscy brokerzy pracują na szczycie swoich możliwości).

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Zużycie pamięci maszyny JVM pozostało poniżej 2 GB:

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Na pracę brokerów z dyskami wpływa brak równowagi partycji:

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

Określenie odpowiedniego rozmiaru klastra Kafki w Kubernetesie

odkrycia

Przedstawione powyżej podejście iteracyjne można rozszerzyć, aby objąć bardziej złożone scenariusze obejmujące setki konsumentów, ponowne partycjonowanie, aktualizacje kroczące, ponowne uruchamianie podów itp. Wszystko to pozwala ocenić granice możliwości klastra Kafki w różnych warunkach, zidentyfikować wąskie gardła w jego działaniu i znaleźć sposoby na ich zwalczanie.

Zaprojektowaliśmy Supertubes, aby szybko i łatwo wdrażać klaster, konfigurować go, dodawać/usuwać brokerów i tematy, reagować na alerty i ogólnie zapewniać, że Kafka działa poprawnie na Kubernetesie. Naszym celem jest pomóc Ci skoncentrować się na głównym zadaniu („generować” i „konsumować” wiadomości Kafki), a całą ciężką pracę pozostawić Supertubes i operatorowi Kafki.

Jeśli interesują Cię technologie Banzai Cloud i projekty Open Source, subskrybuj firmę pod adresem GitHub, LinkedIn lub Twitter.

PS od tłumacza

Przeczytaj także na naszym blogu:

Źródło: www.habr.com

Dodaj komentarz