Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Catatan. terjemahan: Dalam artikel ini, Banzai Cloud membagikan contoh bagaimana alat kustomnya dapat digunakan untuk membuat Kafka lebih mudah digunakan dalam Kubernetes. Petunjuk berikut mengilustrasikan bagaimana Anda dapat menentukan ukuran optimal infrastruktur Anda dan mengonfigurasi Kafka sendiri untuk mencapai throughput yang diperlukan.

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Apache Kafka adalah platform streaming terdistribusi untuk menciptakan sistem streaming real-time yang andal, terukur, dan berkinerja tinggi. Kemampuannya yang mengesankan dapat diperluas dengan menggunakan Kubernetes. Untuk ini kami telah mengembangkannya Operator Kafka Sumber Terbuka dan alat yang disebut Supertube. Mereka memungkinkan Anda menjalankan Kafka di Kubernetes dan menggunakan berbagai fiturnya, seperti menyempurnakan konfigurasi broker, penskalaan berbasis metrik dengan penyeimbangan ulang, kesadaran rak, “lunak” (anggun) meluncurkan pembaruan, dll.

Coba Supertubes di cluster Anda:

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

Atau hubungi dokumentasi. Anda juga dapat membaca tentang beberapa kemampuan Kafka, yang pekerjaannya diotomatisasi menggunakan Supertubes dan operator Kafka. Kami telah menulis tentang mereka di blog:

Saat Anda memutuskan untuk menerapkan klaster Kafka di Kubernetes, Anda mungkin akan dihadapkan pada tantangan dalam menentukan ukuran optimal infrastruktur dasar dan kebutuhan untuk menyempurnakan konfigurasi Kafka agar memenuhi persyaratan throughput. Kinerja maksimum setiap broker ditentukan oleh kinerja komponen infrastruktur yang mendasarinya, seperti memori, prosesor, kecepatan disk, bandwidth jaringan, dll.

Idealnya, konfigurasi broker harus sedemikian rupa sehingga semua elemen infrastruktur digunakan secara maksimal. Namun, dalam kehidupan nyata pengaturan ini cukup rumit. Kemungkinan besar pengguna akan mengkonfigurasi broker untuk memaksimalkan penggunaan satu atau dua komponen (disk, memori, atau prosesor). Secara umum, broker menunjukkan kinerja maksimal ketika konfigurasinya memungkinkan komponen paling lambat digunakan secara maksimal. Dengan cara ini kita bisa mendapatkan gambaran kasar tentang beban yang bisa ditangani oleh satu broker.

Secara teoritis, kita juga dapat memperkirakan jumlah broker yang dibutuhkan untuk menangani beban tertentu. Namun, dalam praktiknya terdapat begitu banyak pilihan konfigurasi pada tingkat yang berbeda sehingga sangat sulit (jika bukan tidak mungkin) untuk mengevaluasi potensi kinerja konfigurasi tertentu. Dengan kata lain, sangat sulit merencanakan konfigurasi berdasarkan performa tertentu.

Untuk pengguna Supertubes, kami biasanya mengambil pendekatan berikut: kami memulai dengan beberapa konfigurasi (infrastruktur + pengaturan), kemudian mengukur kinerjanya, menyesuaikan pengaturan broker dan mengulangi prosesnya lagi. Hal ini terjadi sampai komponen infrastruktur yang paling lambat dimanfaatkan sepenuhnya.

Dengan cara ini, kita mendapatkan gambaran yang lebih jelas tentang berapa banyak broker yang dibutuhkan sebuah cluster untuk menangani beban tertentu (jumlah broker juga bergantung pada faktor lain, seperti jumlah minimum replika pesan untuk memastikan ketahanan, jumlah partisi pemimpin, dll). Selain itu, kami mendapatkan wawasan tentang komponen infrastruktur mana yang memerlukan penskalaan vertikal.

Artikel ini akan membahas langkah-langkah yang kami ambil untuk mendapatkan hasil maksimal dari komponen paling lambat dalam konfigurasi awal dan mengukur throughput cluster Kafka. Konfigurasi yang sangat tangguh memerlukan setidaknya tiga broker yang berjalan (min.insync.replicas=3), didistribusikan di tiga zona aksesibilitas berbeda. Untuk mengonfigurasi, menskalakan, dan memantau infrastruktur Kubernetes, kami menggunakan platform manajemen kontainer kami sendiri untuk cloud hybrid - Pipa saluran. Ini mendukung on-premise (bare metal, VMware) dan lima jenis cloud (Alibaba, AWS, Azure, Google, Oracle), serta kombinasi keduanya.

Pemikiran tentang infrastruktur dan konfigurasi klaster Kafka

Untuk contoh di bawah ini, kami memilih AWS sebagai penyedia cloud dan EKS sebagai distribusi Kubernetes. Konfigurasi serupa dapat diimplementasikan menggunakan PKE - Distribusi Kubernetes dari Banzai Cloud, disertifikasi oleh CNCF.

cakram

Amazon menawarkan beragam Jenis volume EBS. Pada intinya gp2 и io1 namun ada drive SSD untuk memastikan throughput yang tinggi gp2 menghabiskan akumulasi kredit (Kredit I/O), jadi kami lebih memilih tipenya io1, yang menawarkan throughput tinggi yang konsisten.

Jenis instans

Kinerja Kafka sangat bergantung pada cache halaman sistem operasi, jadi kita memerlukan instance dengan memori yang cukup untuk broker (JVM) dan cache halaman. Contoh c5.2xbesar - awal yang baik, karena memiliki memori 16 GB dan dioptimalkan untuk bekerja dengan EBS. Kekurangannya adalah hanya mampu memberikan performa maksimal tidak lebih dari 30 menit setiap 24 jam. Jika beban kerja Anda memerlukan performa puncak dalam jangka waktu yang lebih lama, Anda mungkin ingin mempertimbangkan jenis instans lainnya. Itulah tepatnya yang kami lakukan, berhenti di c5.4xbesar. Ini memberikan throughput maksimum 593,75 Mbps. Throughput maksimum volume EBS io1 lebih tinggi dari contohnya c5.4xbesar, jadi elemen infrastruktur yang paling lambat kemungkinan besar adalah throughput I/O dari jenis instans ini (yang juga harus dikonfirmasi oleh pengujian beban kami).

Сеть

Throughput jaringan harus cukup besar dibandingkan dengan kinerja instance VM dan disk, jika tidak maka jaringan akan menjadi hambatan. Dalam kasus kami, antarmuka jaringan c5.4xbesar mendukung kecepatan hingga 10 Gb/s, yang jauh lebih tinggi dibandingkan throughput I/O instance VM.

Penerapan Pialang

Broker harus dikerahkan (dijadwalkan di Kubernetes) ke node khusus untuk menghindari persaingan dengan proses lain untuk mendapatkan sumber daya CPU, memori, jaringan, dan disk.

versi Jawa

Pilihan logisnya adalah Java 11 karena kompatibel dengan Docker dalam artian JVM dengan tepat menentukan prosesor dan memori yang tersedia untuk container tempat broker berjalan. Mengetahui bahwa batasan CPU itu penting, JVM secara internal dan transparan menetapkan jumlah thread GC dan thread JIT. Kami menggunakan gambar Kafka banzaicloud/kafka:2.13-2.4.0, yang menyertakan Kafka versi 2.4.0 (Scala 2.13) di Java 11.

Jika Anda ingin mempelajari lebih lanjut tentang Java/JVM di Kubernetes, lihat postingan kami berikut:

Pengaturan memori broker

Ada dua aspek penting dalam mengonfigurasi memori broker: pengaturan untuk JVM dan pod Kubernetes. Batas memori yang ditetapkan untuk sebuah pod harus lebih besar dari ukuran heap maksimum sehingga JVM memiliki ruang untuk metaspace Java yang berada di memorinya sendiri dan untuk cache halaman sistem operasi yang digunakan secara aktif oleh Kafka. Dalam pengujian kami, kami meluncurkan broker Kafka dengan parameter -Xmx4G -Xms2G, dan batas memori untuk pod tersebut adalah 10 Gi. Harap dicatat bahwa pengaturan memori untuk JVM dapat diperoleh secara otomatis menggunakan -XX:MaxRAMPercentage и -X:MinRAMPercentage, berdasarkan batas memori pod.

Pengaturan prosesor broker

Secara umum, Anda dapat meningkatkan kinerja dengan meningkatkan paralelisme dengan menambah jumlah thread yang digunakan oleh Kafka. Semakin banyak prosesor yang tersedia untuk Kafka, semakin baik. Dalam pengujian kami, kami memulai dengan batas 6 prosesor dan secara bertahap (melalui iterasi) meningkatkan jumlahnya menjadi 15. Selain itu, kami menetapkan num.network.threads=12 dalam pengaturan broker untuk menambah jumlah thread yang menerima data dari jaringan dan mengirimkannya. Segera mengetahui bahwa broker pengikut tidak dapat menerima replika dengan cukup cepat, mereka menaikkannya num.replica.fetchers ke 4 untuk meningkatkan kecepatan di mana broker pengikut mereplikasi pesan dari para pemimpin.

Alat Pembangkit Beban

Anda harus memastikan bahwa generator beban yang dipilih tidak kehabisan kapasitas sebelum klaster Kafka (yang sedang diukur) mencapai beban maksimumnya. Dengan kata lain, perlu dilakukan penilaian awal terhadap kemampuan alat pembangkit beban, dan juga memilih jenis instans untuk alat tersebut dengan jumlah prosesor dan memori yang memadai. Dalam hal ini, alat kami akan menghasilkan lebih banyak beban daripada yang dapat ditangani oleh cluster Kafka. Setelah banyak percobaan, kami memilih tiga salinan c5.4xbesar, yang masing-masing memiliki generator yang menyala.

Tolok ukur

Pengukuran kinerja merupakan proses berulang yang mencakup tahapan sebagai berikut:

  • menyiapkan infrastruktur (klaster EKS, cluster Kafka, alat pembangkit beban, serta Prometheus dan Grafana);
  • menghasilkan beban untuk jangka waktu tertentu untuk menyaring penyimpangan acak dalam indikator kinerja yang dikumpulkan;
  • menyesuaikan infrastruktur dan konfigurasi broker berdasarkan indikator kinerja yang diamati;
  • mengulangi proses tersebut hingga tingkat throughput klaster Kafka yang diperlukan tercapai. Pada saat yang sama, data tersebut harus dapat direproduksi secara konsisten dan menunjukkan variasi minimal dalam throughput.

Bagian selanjutnya menjelaskan langkah-langkah yang dilakukan selama proses benchmarking klaster pengujian.

Alat

Alat berikut digunakan untuk menerapkan konfigurasi dasar dengan cepat, menghasilkan beban, dan mengukur kinerja:

  • Pipa Awan Banzai untuk mengatur klaster EKS dari Amazon c Prometheus (untuk mengumpulkan Kafka dan metrik infrastruktur) dan grafana (untuk memvisualisasikan metrik ini). Kami mengambil keuntungan terintegrasi в Pipa saluran layanan yang menyediakan pemantauan gabungan, pengumpulan log terpusat, pemindaian kerentanan, pemulihan bencana, keamanan tingkat perusahaan, dan banyak lagi.
  • Sangrenel — alat untuk menguji beban cluster Kafka.
  • Dasbor Grafana untuk memvisualisasikan metrik dan infrastruktur Kafka: Kubernetes Kafka, Pengekspor Node.
  • Supertubes CLI untuk cara termudah menyiapkan cluster Kafka di Kubernetes. Zookeeper, operator Kafka, Envoy, dan banyak komponen lainnya telah diinstal dan dikonfigurasi dengan benar untuk menjalankan cluster Kafka yang siap produksi di Kubernetes.
    • Untuk pemasangan CLI supertube gunakan instruksi yang diberikan di sini.

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

klaster EKS

Siapkan klaster EKS dengan node pekerja khusus c5.4xbesar di zona ketersediaan yang berbeda untuk pod dengan broker Kafka, serta node khusus untuk generator beban dan infrastruktur pemantauan.

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

Setelah kluster EKS aktif dan berjalan, aktifkan integrasinya layanan pemantauan — dia akan menyebarkan Prometheus dan Grafana ke dalam sebuah cluster.

Komponen sistem Kafka

Instal komponen sistem Kafka (Zookeeper, kafka-operator) di EKS menggunakan supertubes CLI:

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

gugus Kafka

Secara default, EKS menggunakan tipe volume EBS gp2, jadi Anda perlu membuat kelas penyimpanan terpisah berdasarkan volume io1 untuk kluster Kafka:

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

Tetapkan parameter untuk broker min.insync.replicas=3 dan menyebarkan pod broker pada node di tiga zona ketersediaan berbeda:

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

Topik

Kami menjalankan tiga instance generator beban secara paralel. Masing-masing dari mereka menulis topiknya masing-masing, artinya kita membutuhkan total tiga topik:

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

Untuk setiap topik, faktor replikasinya adalah 3—nilai minimum yang disarankan untuk sistem produksi dengan ketersediaan tinggi.

Alat Pembangkit Beban

Kami meluncurkan tiga salinan generator beban (masing-masing menulis dalam topik terpisah). Untuk pod generator beban, Anda perlu mengatur afinitas node sehingga pod tersebut dijadwalkan hanya pada node yang dialokasikan untuknya:

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

Beberapa hal yang perlu diperhatikan:

  • Generator beban menghasilkan pesan sepanjang 512 byte dan menerbitkannya ke Kafka dalam kumpulan 500 pesan.
  • Menggunakan argumen -required-acks=all Publikasi dianggap berhasil ketika semua replika pesan yang disinkronkan diterima dan dikonfirmasi oleh broker Kafka. Artinya, dalam tolok ukur tersebut, kami tidak hanya mengukur kecepatan pemimpin dalam menerima pesan, namun juga pengikut mereka dalam mereplikasi pesan. Tujuan dari tes ini bukan untuk mengevaluasi kecepatan membaca konsumen (konsumen) baru-baru ini menerima pesan yang masih tersisa di cache halaman OS, dan perbandingannya dengan kecepatan membaca pesan yang disimpan di disk.
  • Generator beban menjalankan 20 pekerja secara paralel (-workers=20). Setiap pekerja berisi 5 produsen yang berbagi koneksi pekerja ke klaster Kafka. Hasilnya, setiap generator memiliki 100 produsen, dan semuanya mengirimkan pesan ke cluster Kafka.

Memantau kesehatan cluster

Selama pengujian beban cluster Kafka, kami juga memantau kesehatannya untuk memastikan tidak ada restart pod, tidak ada replika yang tidak sinkron, dan throughput maksimum dengan fluktuasi minimal:

  • Generator beban menulis statistik standar tentang jumlah pesan yang dipublikasikan dan tingkat kesalahan. Tingkat kesalahan harus tetap sama 0,00%.
  • Kontrol pelayaran, yang diterapkan oleh kafka-operator, menyediakan dasbor tempat kita juga dapat memantau status cluster. Untuk melihat panel ini lakukan:
    supertubes cluster cruisecontrol show -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file>
  • tingkat ISR (jumlah replika yang “disinkronkan”) penyusutan dan pemuaian sama dengan 0.

Hasil pengukuran

3 broker, ukuran pesan - 512 byte

Dengan partisi yang didistribusikan secara merata ke tiga broker, kami dapat mencapai kinerja ~500 Mb/s (sekitar 990 ribu pesan per detik):

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Konsumsi memori mesin virtual JVM tidak melebihi 2 GB:

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Throughput disk mencapai throughput simpul I/O maksimum pada ketiga instans yang dijalankan broker:

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Dari data penggunaan memori oleh node, dapat disimpulkan bahwa buffering dan caching sistem memerlukan waktu ~10-15 GB:

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

3 broker, ukuran pesan - 100 byte

Ketika ukuran pesan berkurang, throughput turun sekitar 15-20%: waktu yang dihabiskan untuk memproses setiap pesan mempengaruhi hal ini. Selain itu, beban prosesor meningkat hampir dua kali lipat.

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Karena node broker masih memiliki inti yang belum terpakai, performa dapat ditingkatkan dengan mengubah konfigurasi Kafka. Ini bukan tugas yang mudah, jadi untuk meningkatkan throughput, lebih baik bekerja dengan pesan yang lebih besar.

4 broker, ukuran pesan - 512 byte

Anda dapat dengan mudah meningkatkan kinerja klaster Kafka hanya dengan menambahkan broker baru dan menjaga keseimbangan partisi (ini memastikan bahwa beban didistribusikan secara merata antar broker). Dalam kasus kami, setelah menambahkan broker, throughput cluster meningkat menjadi ~580 Mb/s (~1,1 juta pesan per detik). Pertumbuhannya ternyata lebih kecil dari yang diharapkan: hal ini terutama disebabkan oleh ketidakseimbangan partisi (tidak semua broker bekerja pada puncak kemampuannya).

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Konsumsi memori mesin JVM tetap di bawah 2 GB:

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Pekerjaan broker dengan drive dipengaruhi oleh ketidakseimbangan partisi:

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Menentukan ukuran yang sesuai untuk cluster Kafka di Kubernetes

Temuan

Pendekatan berulang yang disajikan di atas dapat diperluas untuk mencakup skenario yang lebih kompleks yang melibatkan ratusan konsumen, partisi ulang, pembaruan berkelanjutan, restart pod, dll. Semua ini memungkinkan kami menilai batas kemampuan klaster Kafka dalam berbagai kondisi, mengidentifikasi hambatan dalam pengoperasiannya, dan menemukan cara untuk mengatasinya.

Kami merancang Supertubes untuk menyebarkan cluster dengan cepat dan mudah, mengonfigurasinya, menambah/menghapus broker dan topik, merespons peringatan, dan memastikan Kafka secara umum berfungsi dengan baik di Kubernetes. Tujuan kami adalah membantu Anda berkonsentrasi pada tugas utama (“menghasilkan” dan “menggunakan” pesan Kafka), dan menyerahkan semua kerja keras kepada Supertubes dan operator Kafka.

Jika Anda tertarik dengan teknologi Banzai Cloud dan proyek Sumber Terbuka, berlanggananlah ke perusahaan tersebut di GitHub, LinkedIn или Twitter.

PS dari penerjemah

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komentar