上游数据存储到kafka中,使用flume来采集数据,传输至hdfs等多种flumeSink。在此过程中,若kafka的数据生产速度高于了flume的消费速度,就会产生数据积压。为了对此过程进行监控,需要定时来监控kafka的生产与消费的状态。
知识参考:https://blog.csdn.net/yxgxy270187133/article/details/53666760
bin/kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list ${ip_port} -topic pz_test_topic --time -2
输出:pz_test_topic:0:1000
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]
/zookeeper/bin/zkCli.sh
set /consumers/testgroup/offsets/pz_test_topic/0 1000
set /kafka/consumers/testgroup/offsets/pz_test_topic/0 1000
重启相关的应用程序,就可以从设置的offset开始读数据了
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}');"