kafka-producer的生产速度与kafka-consumer的消费速度对比

一、业务需求

上游数据存储到kafka中,使用flume来采集数据,传输至hdfs等多种flumeSink。在此过程中,若kafka的数据生产速度高于了flume的消费速度,就会产生数据积压。为了对此过程进行监控,需要定时来监控kafka的生产与消费的状态。

二、知识积累

知识参考:https://blog.csdn.net/yxgxy270187133/article/details/53666760

  1. 查询kafka topic的offset的范围
  • 查看topic=pz_test_topic,broker=${ip_port}的offset的最小值
bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list ${ip_port} -topic pz_test_topic --time -2

输出:pz_test_topic:0:1000

  • 查看offset的最大值
bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list ${ip_port} -topic pz_test_topic --time -1

输出:pz_test_topic:0:1982

可见,topic:pz_test_topic有一个分区partition:0,且 offset范围为:[1000,1982]

  1. 设置consumer group的offset
  • 启动zookeeper client

/zookeeper/bin/zkCli.sh

  • 设置consumer group:testgroup topic:pz_test_topic partition:0的offset为1000:
set /consumers/testgroup/offsets/pz_test_topic/0 1000
  • 注意如果kafka设置了zookeeper root,比如为/kafka,那么命令应该改为:
set /kafka/consumers/testgroup/offsets/pz_test_topic/0 1000

重启相关的应用程序,就可以从设置的offset开始读数据了

  1. 手动更新kafka存在zookeeper中的偏移量
    有时候需要手动将某个topic的偏移量设置成某个值,需要更新Zookeeper中的数据。Kafka内置为我们提供了修改偏移量的类:kafka.tools.UpdateOffsetsInZK,可以通过它修改Zookeeper中某个主题的偏移量,具体操作如下:
bin/kafka-run-class.sh kafka.tools.UpdateOffsetsInZK
USAGE: kafka.tools.UpdateOffsetsInZK$ [earliest | latest] consumer.properties topic

在不输入参数的情况下,我们可以得知kafka.tools.UpdateOffsetsInZK类需要输入的参数。我们的consumer.properties文件配置内容如下:

zookeeper.connect=${zookeeper_ip_port}
# timeout in ms for connecting to zookeeper
zookeeper.connection.timeout.ms=6000
#consumer group id
group.id=group

这个工具只能把Zookeeper中偏移量设置成earliest或者latest,如下:

bin/kafka-run-class.sh kafka.tools.UpdateOffsetsInZK  \
     earliest config/consumer.properties iteblog
updating partition 0 with new offset: 276022922
updating partition 1 with new offset: 234360148
updating partition 2 with new offset: 157237157
updating partition 3 with new offset: 106968019
updating partition 4 with new offset: 80696130
updating partition 5 with new offset: 317144986
updating partition 6 with new offset: 299182459
updating partition 7 with new offset: 197012246
updating partition 8 with new offset: 230433681
updating partition 9 with new offset: 120971431
updating partition 10 with new offset: 51200673
updated the offset for 11 partitions

三、具体实践

kafka生产者与消费者之间可以利用kafka的命令行,来查看生产与消费之间是否有数据积压。此方法仅为才疏学浅的我的一个想法,若不合理,请大家批评指出,有更有效的方法还请告知。

#监控flume消费kafka数据过程中是否有数据积压
#kafka的ip与端口
ip_port=$1
#kafka_topic名
kafka_topic=$2
#consumer消费者组名
consumer_group_id=$3
#脚本执行时间
sys_time=`date +'%Y-%m-%d %H:%M:%S'`
#查看kafkaTOPIC的最大offset,并使用":"分隔,打印出第3列,即offset数字列,再将所有分区的offset值求和
topic_offset=$(kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list ${ip_port} -topic ${kafka_topic} --time -1|awk -F ":"  '{print $3}' | awk '{sum+=$1}END{print sum}')
#kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list ${ip_port} -topic ${kafka_topic} --time -1|sort -f -t":" -k 3,3 -r |awk 'NR==1' 以":"进行分隔,用第3列的数值进行排序,并打印出第一行
#topic_offset=$(kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list ${ip_port} -topic ${kafka_topic} --time -1|sort -f|awk 'NR==1'|cut -d ":" -f 3)  排序,并打印出第1行,再使用":"分隔,切出第3列的值

#获取flume消费到的offset,由于flume的一个consumer.group中可能消费多个kafka topic,可以根据需要使用grep筛选出需要的topic的offset信息,并打印出第3行,并将该topic的所有分区offset求和
consumer_group_offset=$(kafka-consumer-groups.sh --bootstrap-server ${ip_port} --describe --group ${consumer_group_id}|grep -i ${kafka_topic}|awk '{print $3}'| awk '{sum+=$1}END{print sum}')
#consumer_group_offset=$(kafka-consumer-groups.sh --bootstrap-server ${ip_port} --describe --group ${consumer_group_id}|grep -i ${kafka_topic}|awk 'NR==1'|awk '{print $3}')

#计算两个offset的差
difference=$((topic_offset-consumer_group_offset))

#如果kafka topic的offset与flume consumer的offset值之间相差500以内,则认为是正常,否则则认为是存在s数据积压。
if [ ${difference} -le 500 ]; then
 topic_state=NOMAL
else
 topic_state=OVERSTACK
fi 

#将监控结果写入mysql数据库,方便日常监控
source ${conf_path}/mysql_conn_conf.sh
mysql -A -u ${m_user} -p${m_password} -h ${m_host} -P ${m_port} -D ${m_db} --local-infile=1 -e"
insert into kafka_consumers_offset_monitor (sys_time ,kafka_topic ,consumer_group_id ,topic_offset,consumer_group_offset,difference,topic_state) 
values ('${sys_time}','${kafka_topic}','${consumer_group_id}','${topic_offset}','${consumer_group_offset}','${difference}','${topic_state}');"

你可能感兴趣的:(kafka,flume,shell)