筆記。 翻譯。:在本文中,Banzai Cloud 分享了一個範例,說明如何使用其自訂工具使 Kafka 在 Kubernetes 中更容易使用。 以下說明說明如何確定基礎架構的最佳規模並配置 Kafka 本身以實現所需的吞吐量。
Apache Kafka 是一個分散式串流平台,用於創建可靠、可擴展且高效能的即時串流系統。 其令人印象深刻的功能可以使用 Kubernetes 進行擴充。 為此我們開發了
在您的叢集中嘗試 Supertubes:
curl https://getsupertubes.sh | sh и supertubes install -a --no-democluster --kubeconfig <path-to-eks-cluster-kubeconfig-file>
或聯繫
文件 。 您還可以了解 Kafka 的一些功能,它的工作是使用 Supertubes 和 Kafka 運算符實現自動化的。 我們已經在部落格上寫過它們:
當您決定在 Kubernetes 上部署 Kafka 叢集時,您可能會面臨確定底層基礎架構的最佳大小以及需要微調 Kafka 配置以滿足吞吐量要求的挑戰。 每個代理程式的最大效能由底層基礎設施元件的效能決定,例如記憶體、處理器、磁碟速度、網路頻寬等。
理想情況下,代理配置應使所有基礎設施元素都能發揮其最大功能。 然而,在現實生活中,這種設定相當複雜。 使用者更有可能配置代理程式以最大限度地利用一兩個元件(磁碟、記憶體或處理器)。 一般來說,當代理的配置允許最慢的元件得到最大程度的使用時,代理就會顯示出最大的效能。 這樣我們就可以粗略地了解一個代理可以處理的負載。
理論上,我們還可以估計處理給定負載所需的代理數量。 然而,實際上,不同級別的配置選項如此之多,以至於評估特定配置的潛在性能非常困難(如果不是不可能的話)。 換句話說,根據某些給定的效能來規劃配置是非常困難的。
對於Supertubes用戶,我們通常採取以下方法:我們從一些配置(基礎設施+設定)開始,然後測量其效能,調整經紀商設定並再次重複該過程。 這種情況會一直發生,直到基礎設施中最慢的元件被充分利用為止。
這樣,我們就可以更清楚地了解一個叢集需要多少個broker來處理一定的負載(broker的數量還取決於其他因素,例如保證彈性的最小訊息副本數、分區數量等)領導等)。 此外,我們也深入了解哪些基礎設施組件需要垂直擴展。
本文將討論我們為充分利用初始配置中最慢的元件並測量 Kafka 群集的吞吐量而採取的步驟。 高彈性配置需要至少三個正在運行的代理(min.insync.replicas=3
),分佈在三個不同的可訪問區域。 為了配置、擴展和監控 Kubernetes 基礎設施,我們使用自己的混合雲容器管理平台 -
關於Kafka叢集基礎設施和配置的思考
對於下面的範例,我們選擇 AWS 作為雲端供應商,選擇 EKS 作為 Kubernetes 發行版。 可以使用類似的配置來實現
磁盤
亞馬遜提供各種
實例類型
Kafka 的效能高度依賴作業系統的頁面緩存,因此我們需要為代理(JVM)和頁面快取提供足夠記憶體的實例。 實例 c5.2xlarge - 一個好的開始,因為它有 16 GB 內存
Сеть
與虛擬機器實例和磁碟的效能相比,網路吞吐量必須足夠大,否則網路將成為瓶頸。 在我們的例子中,網路接口 c5.4xlarge 支援高達 10 Gb/s 的速度,明顯高於 VM 實例的 I/O 吞吐量。
代理部署
Brokers 應部署(在 Kubernetes 中調度)到專用節點,以避免與其他進程競爭 CPU、記憶體、網路和磁碟資源。
Java版本
合理的選擇是 Java 11,因為它與 Docker 相容,因為 JVM 可以正確確定運行代理程式的容器可用的處理器和記憶體。 知道 CPU 限制很重要,JVM 在內部透明地設定 GC 執行緒和 JIT 執行緒的數量。 我們使用了 Kafka 圖像 banzaicloud/kafka:2.13-2.4.0
,其中包括 Java 2.4.0 上的 Kafka 版本 2.13 (Scala 11)。
如果您想了解有關 Kubernetes 上的 Java/JVM 的更多信息,請查看我們的以下帖子:
經紀商內存設置
配置代理記憶體有兩個關鍵面向:JVM 和 Kubernetes Pod 的設定。 為 pod 設定的記憶體限制必須大於最大堆大小,以便 JVM 為駐留在其自己記憶體中的 Java 元空間以及 Kafka 主動使用的作業系統頁面快取提供空間。 在我們的測試中,我們啟動了帶有參數的 Kafka 代理 -Xmx4G -Xms2G
,並且 Pod 的記憶體限制為 10 Gi
。 請注意,JVM 的記憶體設定可以使用以下命令自動獲取 -XX:MaxRAMPercentage
и -X:MinRAMPercentage
,基於 Pod 的記憶體限制。
經紀商處理器設定
一般來說,可以透過增加Kafka使用的線程數來提高並行度來提高效能。 可用於 Kafka 的處理器越多越好。 在我們的測試中,我們一開始限制為 6 個處理器,並逐漸(透過迭代)將其數量增加到 15 個。此外,我們設定 num.network.threads=12
在代理設定中增加從網路接收資料並發送資料的執行緒數量。 他們立即發現追隨者經紀人無法足夠快地接收副本,他們提出了 num.replica.fetchers
到 4 以提高追隨者經紀人從領導者複製訊息的速度。
負載產生工具
您應該確保在 Kafka 叢集(正在進行基準測試)達到最大負載之前,所選負載產生器不會耗盡容量。 也就是說,需要對負載產生工具的能力進行初步評估,並為其選擇具有足夠數量的處理器和記憶體的執行個體類型。 在這種情況下,我們的工具將產生超過 Kafka 叢集可以處理的負載。 經過多次實驗,我們確定了三份 c5.4xlarge,每個都有一台發電機在運作。
對標
績效衡量是一個迭代過程,包括以下階段:
- 設定基礎設施(EKS叢集、Kafka叢集、負載產生工具以及Prometheus和Grafana);
- 產生一定週期的負載,過濾收集到的效能指標中的隨機偏差;
- 根據觀察到的績效指標調整經紀商的基礎設施和配置;
- 重複此過程,直到達到 Kafka 群集吞吐量所需的水平。 同時,它必須具有一致的可重複性,並且表現出最小的吞吐量變化。
下一節介紹測試叢集基準測試過程中執行的步驟。
工具
以下工具用於快速部署基線配置、產生負載和測量效能:
-
萬歲雲端管道 用於從 Amazon c 組織 EKS 叢集普羅米修斯 (收集 Kafka 和基礎設施指標)和格拉法納 (可視化這些指標)。 我們利用了 融合的 в管道 提供聯合監控、集中日誌收集、漏洞掃描、災難復原、企業級安全等的服務。 -
桑格勒內爾 — 用於對 Kafka 叢集進行負載測試的工具。 - 用於視覺化 Kafka 指標和基礎設施的 Grafana 儀表板:
庫伯內特卡夫卡 ,節點導出器 . - Supertubes CLI 是在 Kubernetes 上設定 Kafka 叢集最簡單的方法。 Zookeeper、Kafka Operator、Envoy 和許多其他元件均已安裝並正確配置,以便在 Kubernetes 上運行生產就緒的 Kafka 叢集。
- 安裝用 超級管 CLI 使用提供的說明
這裡 .
- 安裝用 超級管 CLI 使用提供的說明
EKS叢集
準備具有專用工作節點的 EKS 集群 c5.4xlarge 具有 Kafka 代理程式的 Pod 位於不同的可用區域,以及負載產生器和監控基礎設施的專用節點。
banzai cluster create -f https://raw.githubusercontent.com/banzaicloud/kafka-operator/master/docs/benchmarks/infrastructure/cluster_eks_202001.json
EKS 叢集啟動並運行後,啟用其集成
卡夫卡系統組件
使用 supertubes CLI 在 EKS 中安裝 Kafka 系統元件(Zookeeper、kafka-operator):
supertubes install -a --no-democluster --kubeconfig <path-to-eks-cluster-kubeconfig-file>
卡夫卡集群
預設情況下,EKS 使用 EBS 磁碟區類型 gp2,所以需要根據磁碟區建立單獨的儲存類 io1 對於卡夫卡集群:
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
設定經紀人的參數 min.insync.replicas=3
並在三個不同可用區的節點上部署 Broker Pod:
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
話題
我們並行運行三個負載生成器實例。 他們每個人都寫自己的主題,也就是說,我們總共需要三個主題:
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
對於每個主題,複製因子為 3 — 高可用生產系統的最小建議值。
負載產生工具
我們啟動了負載產生器的三個副本(每個副本都在單獨的主題中編寫)。 對於負載產生器 Pod,您需要設定節點關聯性,以便僅在為其指派的節點上調度它們:
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
有幾點要注意:
- 負載產生器產生長度為 512 位元組的訊息,並以 500 個訊息為批次發佈到 Kafka。
- 使用參數
-required-acks=all
當 Kafka 代理收到並確認訊息的所有同步副本時,發布被視為成功。 這意味著在基準測試中,我們不僅測量了領導者接收訊息的速度,還測量了他們的追隨者複製訊息的速度。 此測驗的目的不是要評估消費者的閱讀速度 (消費者) 最近收到的仍保留在作業系統頁面快取中的消息,及其與儲存在磁碟上的消息的讀取速度的比較。 - 負載產生器並行運行 20 個工作執行緒(
-workers=20
)。 每個worker包含5個生產者,它們共享worker與Kafka叢集的連結。 因此,每個生成器有 100 個生產者,它們都會向 Kafka 叢集發送訊息。
監控叢集的健康狀況
在 Kafka 叢集的負載測試期間,我們還監控其運行狀況,以確保沒有 pod 重新啟動、沒有不同步的副本以及最大吞吐量和最小波動:
- 負載產生器寫入有關已發布訊息數量和錯誤率的標準統計資料。 錯誤率應該保持不變
0,00%
. -
巡航控制 由 kafka-operator 部署,提供了一個儀表板,我們也可以在其中監視叢集的狀態。 若要查看此面板,請執行以下操作:supertubes cluster cruisecontrol show -n kafka --kubeconfig <path-to-eks-cluster-kubeconfig-file>
- 情監偵級別 (「同步」副本的數量) 收縮和膨脹等於 0。
測量結果
3 個代理,訊息大小 - 512 位元組
透過將分區均勻分佈在三個代理上,我們能夠實現效能 ~500 Mb/s(每秒約 990 萬則訊息):
JVM虛擬機器的記憶體消耗不超過2GB:
在執行代理程式的所有三個實例上,磁碟吞吐量均達到最大 I/O 節點吞吐量:
從節點記憶體使用資料來看,系統緩衝和快取佔用了約 10-15 GB:
3 個代理,訊息大小 - 100 位元組
隨著訊息大小的減小,吞吐量會下降約 15-20%:處理每個訊息所花費的時間會對其產生影響。 此外,處理器負載幾乎增加了一倍。
由於代理節點仍然有未使用的核心,因此可以透過更改 Kafka 配置來提高效能。 這不是一件容易的任務,因此為了提高吞吐量,最好使用更大的消息。
4 個代理,訊息大小 - 512 位元組
只需新增新的代理並保持分區平衡(這可確保負載在代理之間均勻分配),您就可以輕鬆提高 Kafka 叢集的效能。 在我們的例子中,新增代理後,叢集吞吐量增加到 約 580 Mb/s(約每秒 1,1 萬則訊息)。 成長結果低於預期:這主要是由於分區不平衡造成的(並非所有經紀商都在其能力的巔峰狀態下工作)。
JVM 機器的記憶體消耗保持在 2 GB 以下:
具有驅動器的代理程式的工作受到分區不平衡的影響:
發現
上面提出的迭代方法可以擴展到涵蓋涉及數百個消費者、重新分區、滾動更新、pod 重新啟動等的更複雜的場景。 所有這些使我們能夠評估 Kafka 叢集在各種條件下的能力限制,識別其運行中的瓶頸並找到解決它們的方法。
我們設計 Supertubes 是為了快速輕鬆地部署叢集、配置叢集、新增/刪除代理程式和主題、回應警報並確保 Kafka 在 Kubernetes 上正常運作。 我們的目標是幫助您專注於主要任務(「產生」和「消費」Kafka 訊息),並將所有艱苦的工作留給 Supertubes 和 Kafka 操作員。
如果您對 Banzai Cloud 技術和開源專案感興趣,請訂閱該公司:
譯者PS
另請閱讀我們的博客:
- «
關於 K8s 中的 Redis 操作員的一個故事以及用於分析該數據庫中的數據的實用程序的簡短回顧 “; - «
RabbitMQ 無縫遷移到 Kubernetes “; - «
CoreOS 中的 zetcd:用 etcd 儲存替換 ZooKeeper “。
來源: www.habr.com