Kafka-exporter采集參數調整方案

#作者:張桐瑞

文章目錄

  • 1 問題概述
  • 2 修改方案
    • 2.1修改參數
    • 2.2配置示例
  • 3 消費者組均分腳本
    • 3.1使用說明
    • 3.2腳本內容
    • 3.3實現原理說明
  • 4 KAFKA-EXPORTER流程代碼
    • 4.1KAFKA-EXPORTER拉取數據流程

1 問題概述

由于kafka-exporter獲取kafka指標時間過長,無法通過curl kafka-exporter:9308/metrics 獲取指標,通過查看kafka-exporter日志,發現
time=“2025-07-22T02:18:00Z” level=error msg=“Cannot get offset of group xxxx: kafka: broker not connected” source=“kafka_exporter.go:396”
的報錯信息,發現kafka-exporter在查詢消費者組時出現超時,通過命令
kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --all-groups
同樣出現超時信息。
java.util.concurrent.ExecutionException: org.apache.kafka.common.errors.TimeoutException: Call(callName=describeConsumerGroups, deadlineMs=1753170317381, tries=1, nextAllowedTryMs=1753170317482) timed out at 1753170317382 after 1 attempt(s)
通過針對具體消費者組進行查看,發現返回信息較快,故計劃過濾一部分groups來減少數據量。

2 修改方案

當前環境中,Kafka與Kafka Exporter共同部署在同一Pod 內,且各個Kafka Exporter未配置過濾規則,導致采集數據存在大量重復。為提升采集效率和準確性,計劃通過以下措施進行優化:

  1. 基于不同的 ReplicaSet(RC)配置差異化過濾規則;
    針對每個RC單獨設置專屬的消費者組過濾規則,避免重復采集。
  2. 利用消費者均分腳本生成過濾正則表達式;
    通過腳本將所有消費者組按規則均分,生成適用于Kafka Exporter的正則表達式,保證每個 Exporter 只采集其分配范圍內的消費者組。
  3. 將生成的消費者組過濾正則應用于不同 Exporter 配置中;
    將對應的正則表達式配置到各自 Exporter 實例中,實現消費組采集的隔離和均衡分布

2.1修改參數

group.filter .* Regex that determines which consumer groups to collect
group.filter # 正則表達式,用于確定要收集哪些消費者組(Consumer Groups)的指標。

2.2配置示例

只需為每個Kafka Exporter添加對應的YAML配置段落即可。

2.2.1KAFKA_EXPORTER_1:

  • args:
    • –kafka.server=localhost:9092
    • –web.listen-address=:9308
    • –group.filter=^(A|a|B).*

2.2.2KAFKA_EXPORTER_2:

  • args:
    • –kafka.server=localhost:9092
    • –web.listen-address=:9308
    • –group.filter=^(E|b).*

2.2.3KAFKA_EXPORTER_3:

  • args:
    • –kafka.server=localhost:9092
    • –web.listen-address=:9308
    • –group.filter=^?.*

3 消費者組均分腳本

3.1使用說明

配置參數:

  • BOOTSTRAP_SERVER: 指定 Kafka 服務地址;
  • EXPORTER_COUNT: 指定需要生成多少個 Exporter 的過濾規則。
# Bash group-distributor.sh使用消費者組均分腳本進行消費者組均勻分布,腳本執行結果如下:
bash-5.0$ bash /bitnami/kafka/data/topic_to_consumer_group.sh================ Hash by 首字母 (區分大小寫) =================
Exporter 1: --group.filter=^(A|a|B).*  [3 groups]
Exporter 2: --group.filter=^(E|b).*  [2 groups]
Exporter 3: --group.filter=^(C).*  [1 groups]

可參考對應的exporter過濾正則結果。

3.2腳本內容

3.2.1Hash分組腳本

#!/bin/bashBOOTSTRAP_SERVER="localhost:9092"
EXPORTER_COUNT=3# 獲取所有消費者組
all_groups=$(kafka-consumer-groups.sh --bootstrap-server "$BOOTSTRAP_SERVER" --list)# 初始化數組
for ((i=0; i<EXPORTER_COUNT; i++)); doprefix_sets[$i]=""count[$i]=0
donedeclare -A seen_prefix# 遍歷組名,按首字母 hash 均分
while IFS= read -r group; doprefix=$(echo "$group" | cut -c1)[[ -z "$prefix" ]] && continue# 計算哈希分配位置hash_hex=$(echo -n "$prefix" | md5sum | awk '{print $1}' | cut -c1-8)hash_dec=$((16#$hash_hex))idx=$((hash_dec % EXPORTER_COUNT))# 記錄唯一首字母,用于生成正則if [[ -z "${seen_prefix[$prefix]}" ]]; thenseen_prefix[$prefix]=1if [[ -z "${prefix_sets[$idx]}" ]]; thenprefix_sets[$idx]="$prefix"elseprefix_sets[$idx]+="|$prefix"fifi# 每個實際組都會計入對應 exporter 的數量count[$idx]=$((count[$idx] + 1))
done <<< "$all_groups"# 輸出結果
echo "================ Hash by 首字母 (區分大小寫) ================="
for ((i=0; i<EXPORTER_COUNT; i++)); doif [[ -n "${prefix_sets[$i]}" ]]; thenecho "Exporter $((i+1)): --group.filter='^(${prefix_sets[$i]}).*'  [${count[$i]} groups]"elseecho "Exporter $((i+1)): --group.filter='^()'  [${count[$i]} groups]"fi
done

3.2.2 排序分組腳本

#!/bin/bashBOOTSTRAP_SERVER="localhost:9092"
EXPORTER_COUNT=3# 獲取所有消費組
all_groups=$(kafka-consumer-groups.sh --bootstrap-server "$BOOTSTRAP_SERVER" --list)# 按首字母分組(區分大小寫)
declare -A initial_to_groups
declare -A initial_countswhile IFS= read -r group; do[[ -z "$group" ]] && continuefirst_char=${group:0:1}initial_to_groups["$first_char"]+="$group"$'\n'initial_counts["$first_char"]=$((initial_counts["$first_char"] + 1))
done <<< "$all_groups"# 將首字母按消費組數量降序排序
sorted_initials=$(for k in "${!initial_counts[@]}"; doecho -e "${initial_counts[$k]}\t$k"
done | sort -rn | awk '{print $2}')# 初始化每個 exporter 的負載、過濾項和組列表
for ((i=0; i<EXPORTER_COUNT; i++)); doexporter_filters[$i]=""exporter_loads[$i]=0exporter_groups[$i]=""
done# 分配首字母到 exporter,按消費組數量均衡
for initial in $sorted_initials; docount=${initial_counts[$initial]}# 找當前負載最小的 exportermin_index=0min_load=${exporter_loads[0]}for ((i=1; i<EXPORTER_COUNT; i++)); doif (( exporter_loads[i] < min_load )); thenmin_index=$imin_load=${exporter_loads[i]}fidone# 添加到對應 exporterif [[ -z "${exporter_filters[$min_index]}" ]]; thenexporter_filters[$min_index]="$initial"elseexporter_filters[$min_index]+="|$initial"fiexporter_loads[$min_index]=$((exporter_loads[$min_index] + count))exporter_groups[$min_index]+="${initial_to_groups[$initial]}"
done# 輸出格式
echo "================ kafka-exporter group.filter 正則分片 ================="
for ((i=0; i<EXPORTER_COUNT; i++)); dogroup_count=$(echo -n "${exporter_groups[$i]}" | grep -c '^')echo "Exporter $((i+1)): ($group_count groups)"echo "  --group.filter='^(${exporter_filters[$i]}).*'"echo
done

3.3實現原理說明

3.3.1Hash分組腳本說明
該腳本通過以下核心邏輯實現消費者組的分配與正則表達式生成:

  1. 獲取消費者組列表:
    利用 kafka-consumer-groups.sh --list 獲取當前 Kafka 所有消費者組名。
  2. 提取首字母并去重:
    對每個消費者組名提取首字母(區分大小寫),使用關聯數組 seen_prefix 確保相同首字母只處理一次。
  3. Hash 均分邏輯:
    1)使用 md5sum 對首字母進行 Hash 處理;
    2)將 Hash 值轉為十進制,再通過取模操作將其平均分配到 N 個 Exporter 中;
    3)每個 Exporter 收集分配到的首字母集合,組合成正則表達式。
  4. 生成過濾規則:
    每個Exporter輸出一條形如–group.filter=^(A|B|C).* 的正則規則,僅匹配以指定前綴開頭的消費者組。
    3.3.2排序分鐘腳本說明
    在首字母提取之后,腳本還會對首字母列表進行 排序處理,其作用是:
  5. 確保穩定性
    通過排序(sort 命令),可以保證即使 Kafka 集群中的消費者組順序發生變化,腳本對首字母的處理順序仍保持一致,從而保證正則分配的穩定性。
  6. 提升分配公平性
    排序后的首字母經過統一的 Hash 計算和取模分配,有助于在 Exporter間更公平地分攤消費者組,提高采集性能和均衡性。
  7. 簡化調試和查看
    將字母排序輸出后,便于在查看分配結果時快速定位具體字母屬于哪個Exporter,也有助于問題定位和正則表達式核查。

4 KAFKA-EXPORTER流程代碼

4.1KAFKA-EXPORTER拉取數據流程

4.1.1拉取所有消費者組
在getConsumerGroupMetrics函數中,首先通過broker.ListGroups(&sarama.ListGroupsRequest{})向Kafka broker拉取所有的消費者組(group)列表。
這一步會返回集群中所有存在的group名稱。

groupIds := make([]string, 0)for groupId := range groups.Groups {if e.groupFilter.MatchString(groupId) {groupIds = append(groupIds, groupId)}}

4.1.2 過濾消費者組
拉取到所有group后,遍歷每個groupId,用e.groupFilter.MatchString(groupId)判斷該group是否匹配過濾條件。
只有匹配的groupId才會被加入到后續的處理流程。

 groupIds := make([]string, 0)for groupId := range groups.Groups {if e.groupFilter.MatchString(groupId) {groupIds = append(groupIds, groupId)}}

4.1.3 DESCRIBE消費者組
只對通過過濾的group進行DescribeGroups、FetchOffset等詳細指標采集。

describeGroups, err := broker.DescribeGroups(&sarama.DescribeGroupsRequest{Groups: groupIds})if err != nil {glog.Errorf("Cannot get describe groups: %v", err)return}for _, group := range describeGroups.Groups {offsetFetchRequest := sarama.OffsetFetchRequest{ConsumerGroup: group.GroupId, Version: 1}if e.offsetShowAll {for topic, partitions := range offset {for partition := range partitions {offsetFetchRequest.AddPartition(topic, partition)}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92469.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92469.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92469.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AT32的freertos下modbus TCP移植

1.準備模板 打開雅特力官網&#xff0c;也就是帶有LwIP的示例。 下載官方源碼&#xff1a;modbus 2.移植 我這里是在這里新建兩個文件夾&#xff0c;分別是modbus與port&#xff0c;這個任意&#xff0c;只需要將必要的文件加入項目即可。 將源碼中的modbus這些都移植過來&a…

Redis面試精講 Day 16:Redis性能監控與分析工具

【Redis面試精講 Day 16】Redis性能監控與分析工具 開篇 歡迎來到"Redis面試精講"系列第16天&#xff0c;今天我們將深入探討Redis性能監控與分析工具。在大型分布式系統中&#xff0c;Redis作為關鍵的數據存儲和緩存組件&#xff0c;其性能指標直接影響整個系統的…

vue3+vue-flow制作簡單可拖拽可增刪改流程圖

實現效果實現代碼 準備工作 安裝依賴 npm install vue-flow/core npm install vue-flow/minimap //小地圖 npm install vue-flow/controls //自帶的縮放、居中、加鎖功能我這里只用到上述三個&#xff0c;還有其余的可根據實際情況配合官方文檔使用。 npm install vue-flow/bac…

itextPdf獲取pdf文件寬高不準確

正常情況下我們通過下面方式獲取寬高PdfReader reader new PdfReader(file.getPath()); float width reader.getPageSize(1).getWidth(); float height reader.getPageSize(1).getHeight();但是這樣獲取的寬高是不準確的&#xff0c;永遠都是 寬 > 高&#xff0c;也就是橫…

NodeJs學習日志(2):windows安裝使用node.js 安裝express,suquelize,mysql,nodemon

windows安裝使用node.js 安裝express&#xff0c;suquelize&#xff0c;mysql&#xff0c;nodemon 系統是win10&#xff0c;默認已經安裝好nodejs與npm包名作用expressWeb應用框架suquelize數據庫ORMmysql數據庫nodemon代碼熱重載安裝express 添加express生成器 npm add expres…

VueCropper 圖片裁剪組件在Vue項目中的實踐應用

VueCropper 圖片裁剪組件在Vue項目中的實踐應用 1. 組件介紹 VueCropper 是一個基于 Vue.js 的圖片裁剪組件&#xff0c;它提供了豐富的圖片裁剪功能&#xff0c;包括&#xff1a; 圖片縮放、旋轉、移動固定比例裁剪高質量圖片輸出多種裁剪模式選擇 2. 安裝與引入 首先需要安裝…

給同一個wordpress網站綁定多個域名的實現方法

在WordPress網站上綁定多個域名&#xff0c;可以通過以下幾種方法實現&#xff1a; 1. 修改wp-config.php文件 在wp-config.php文件中&#xff0c;找到define(‘WP_DEBUG’, false);&#xff0c;在其下方添加以下代碼&#xff1a; define(WP_SITEURL, http:// . $_SERVER[HT…

HarmonyOS分布式開發實戰:打造跨設備協同應用

&#x1f4d6; 文章目錄 第一章&#xff1a;HarmonyOS分布式架構揭秘第二章&#xff1a;跨設備協同的核心技術第三章&#xff1a;開發環境搭建與配置第四章&#xff1a;實戰項目&#xff1a;智能家居控制系統第五章&#xff1a;數據同步與狀態管理第六章&#xff1a;性能優化與…

用 Enigma Virtual Box 把 Qt 程序壓成單文件 EXE——從編譯、收集依賴到一鍵封包

關鍵詞&#xff1a;Qt、windeployqt、Enigma Virtual Box、單文件、綠色軟件 為什么要打成單文件&#xff1f; 傳統做法&#xff1a;用 windeployqt 把依賴拷進 release 目錄&#xff0c;發給用戶一個文件夾&#xff0c;文件又多又亂。理想做法&#xff1a;把整個目錄壓成一個…

unity中實現選中人物腳下顯示圓形標識且完美貼合復雜地形(如彈坑) 的效果

要實現人物腳下圓形 完美貼合復雜地形&#xff08;如彈坑&#xff09; 的效果&#xff0c;核心思路是 「動態生成貼合地面的 Mesh」 —— 即根據地面的高度場實時計算環形頂點的 Y 坐標&#xff0c;讓每個頂點都 “貼” 在地面上。核心邏輯&#xff1a;確定環形范圍&#xff1a…

引領GameFi 2.0新范式:D.Plan攜手頂級財經媒體啟動“龍珠創意秀”

在GameFi賽道尋求新突破的今天&#xff0c;一個名為Dragonverse Plan&#xff08;D.Plan&#xff09;的項目正以其獨特的經濟模型和宏大愿景&#xff0c;吸引著整個Web3社區的目光。據悉&#xff0c;D.Plan即將聯合中文區頂級加密媒體金色財經與非小號&#xff08;Feixiaohao&a…

通信算法之307:fpga之時序圖繪制

時序圖繪制軟件 一. 序言 在FPGA設計過程中&#xff0c;經常需要編寫設計文檔&#xff0c;其中&#xff0c;不可缺少的就是波形圖的繪制&#xff0c;可以直接截取Vivado或者Modelsim平臺實際仿真波形&#xff0c;但是往往由于信號雜亂無法凸顯重點。因此&#xff0c;通過相應軟…

計網學習筆記第3章 數據鏈路層(灰灰題庫)

題目 11 單選題 下列說法正確的是______。 A. 路由器具有路由選擇功能&#xff0c;交換機沒有路由選擇功能 B. 三層交換機具有路由選擇功能&#xff0c;二層交換機沒有路由選擇功能 C. 三層交換機適合異構網絡&#xff0c;二層交換機不適合異構網絡 D. 路由器適合異構網絡&…

SQL的LEFT JOIN優化

原sql&#xff0c;一個base表a,LEFT JOIN三個表抽數 SELECT ccu.*, ctr.*, om.*, of.* FROM ods.a ccu LEFT JOIN ods.b ctr ON ccu.coupon_code ctr.coupon_code AND ctr.is_deleted 0 LEFT JOIN ods.c om ON ctr.bill_code om.order_id AND om.deleted 0 LEFT JOIN ods.…

Redis 核心概念、命令詳解與應用實踐:從基礎到分布式集成

目錄 1. 認識 Redis 2. Redis 特性 2.1 操作內存 2.2 速度快 2.3 豐富的功能 2.4 簡單穩定 2.5 客戶端語言多 2.6 持久化 2.7 主從復制 2.8 高可用 和 分布式 2.9 單線程架構 2.9.1 引出單線程模型 2.9.2 單線程快的原因 2.10 Redis 和 MySQL 的特性對比 2.11 R…

【Day 18】Linux-DNS解析

目錄 一、DNS概念 1、概念和作用 2、域名解析類型 3、 軟件與服務 4、DNS核心概念 區域 記錄 5、查詢類型 6、分層結構 二、DNS操作 配置本機為DNS內網解析服務器 &#xff08;1&#xff09;修改主配置文件 &#xff08;2&#xff09;添加區域 正向解析區域&#xff1a; …

Python 中 OpenCV (cv2) 安裝與使用介紹

Python 中 OpenCV (cv2) 安裝與使用詳細指南 OpenCV (Open Source Computer Vision Library) 是計算機視覺領域最流行的庫之一。Python 通過 cv2 模塊提供 OpenCV 的接口。 一、安裝 OpenCV 方法 1&#xff1a;基礎安裝&#xff08;推薦&#xff09; # 安裝核心包&#xff0…

微軟WSUS替代方案

微軟WSUS事件回顧2025年7月10日&#xff0c;微軟最新確認Windows Server Update Services&#xff08;WSUS&#xff09;出現了問題&#xff0c;導致IT管理員無法正常同步和部署Windows更新。WSUS是允許管理員根據策略配置&#xff0c;將更新推送到特定計算機&#xff0c;并優化…

Minio 分布式集群安裝配置

目錄創建 mkdir -p /opt/minio/run && mkdir -p /etc/minio && mkdir -p /indata/disk_0/minio/datarun&#xff1a;啟動腳本及二進制文件目錄/etc/minio&#xff1a;配置文件目錄data&#xff1a;數據存儲目錄下載 minio wget https://dl.min.io/server/minio…

Spring Boot + ShardingSphere 實現分庫分表 + 讀寫分離實戰

&#x1f680; Spring Boot ShardingSphere 實現分庫分表 讀寫分離&#xff08;涵蓋99%真實場景&#xff09; &#x1f3f7;? 標簽&#xff1a;ShardingSphere、分庫分表、讀寫分離、MySQL 主從、Spring Boot 實戰 分庫分表 vs 讀寫分離 vs 主從配置與數據庫高可用架構區別 …