#版权声明:不定期更新维护地址,看这里→_→ https://blog.csdn.net/qq_16592497/article/details/84589660
#检查 kafka 集群 Isr 信息
#用法简介
function print_usage(){
echo -e "\e[1;31mIncorrect parameter input. Please reenter! \e[0m"
echo -e "Usage:\e[1;32msh $0 <cluster_id>( cb | xl | cunliang | cdb_1 | ctx_cl | cjhyx | xin_dingdan\
| ctx-kafka | zc_bigdata | new_cb )\e[0m"
echo -e "e.g.: \e[1;32msh $0 new_cb\e[0m"
#exit退出shell脚本,不加数字参数则退出码不变,即为最后一个命令的退出码
exit
}
#如果脚本传入参数个数不正确则打印使用手册
if [[ $# -ne 1 ]]; then
#调用函数打印使用手册
print_usage
fi
#传入的第一个参数为集群 ID
case $1 in
cb )
zookeeper_ip=10.161.17.71
;;
xl )
zookeeper_ip=10.162.1.250
;;
cunliang )
zookeeper_ip=10.162.4.29
;;
cdb_1 )
zookeeper_ip=10.162.233.170
;;
ctx_cl )
zookeeper_ip=10.162.233.170
;;
cjhyx )
zookeeper_ip=10.162.2.83
;;
xin_dingdan )
zookeeper_ip=10.161.18.216
;;
ctx-kafka )
zookeeper_ip=10.162.235.1
;;
zc_bigdata )
zookeeper_ip=10.161.26.28
;;
new_cb )
zookeeper_ip=10.161.18.132
;;
* )
#echo 输出错误提示
echo -e "\e[1;31mSorry! Functions to be developed...\e[0m"
#调用函数打印使用手册
print_usage
;;
esac
#tar 包方式安装使用自带脚本 kafka-topics.sh 查看所有 topic 信息输出到中间文件中
kafka-topics.sh --zookeeper ${zookeeper_ip}:2181 --describe > topics_info
#if 判断上一条命令是否执行成功,若失败则尝试是否是 cm 方式安装的
if [[ $? -ne 0 ]]; then
#cm 方式安装使用自带脚本 kafka-topics 查看所有 topic 信息输出到中间文件中
kafka-topics --zookeeper ${zookeeper_ip}:2181 --describe > topics_info
#if 判断上一条命令是否执行成功,若失败则说明当前用户未配置环境变量,执行命令自动替换脚本路径为绝对路径
if [[ $? -ne 0 ]]; then
echo -e "\e[1;31m当前用户未配置环境变量,执行命令自动替换脚本路径为绝对路径\e[0m"
echo -e "\e[1;32m正在执行 find / -name 'kafka-topics.sh' -o -name 'kafka-topics' 2>/dev/null\e[0m"
#find -name 查找文件名为 kafka-topics 或 kafka-topics.sh 的文件的绝对路径
find / -name 'kafka-topics' -o -name 'kafka-topics.sh' 2>/dev/null
#获取命令的执行结果保存为数组
script_dir=(`find / -name 'kafka-topics' -o -name 'kafka-topics.sh' 2>/dev/null`)
if [[ ${#script_dir[*]} -ne 0 ]]; then
#执行命令自动替换脚本路径为绝对路径(这里使用 find 命令查找到的第一个绝对路径)
echo -e "\e[1;32m正在执行 sed -i \"s|^kafka-topics.sh|${script_dir[0]}|g\" $0\e[0m"
sed -i "s|^kafka-topics.sh|${script_dir[0]}|g" $0
echo -e "\e[1;31m脚本绝对路径替换成功,请重新执行脚本~\e[0m"
exit
else
echo -e "\e[1;31m${USER} 用户有权访问的文件中没有 kafka-topics.sh 或 kafka-topics 脚本,请更换用户或机器执行!\e[0m"
#删除不必要的中间文件以节省磁盘空间
rm topics_info
exit
fi
fi
fi
#while 循环按行读取文件
cat topics_info | while read line
do
#获取 Replicas 列表存为数组 Replicas
Replicas=(`echo ${line} | grep -oE "Replicas: [0-9,]+" | grep -oE "[0-9]+" | sort | uniq`)
#获取 Isr 列表存为数组 Isr
Isr=(`echo ${line} | grep -oE "Isr: [0-9,]+" | grep -oE "[0-9]+" | sort | uniq`)
#如果数组 Isr 的长度小于数组 Replicas 的长度,则说明有不同步的 broker
if [[ ${#Isr[*]} -lt ${#Replicas[*]} ]]; then
#设置变量 k 表示第 ${k} 个不在 Isr 列表的 broker,设置初始值为 0
k=0
#设置数组 not_isr_broker 记录不在 Isr 中 但在 Replicas 中的 broker,每次记录前先 unset 清空数组
unset not_isr_broker
#for 循环遍历 Replicas 数组中的元素和 Isr 中的进行对比,若存在则标记 flag 为 1
for i in ${Replicas[*]}; do
#变量 flag 用来确定变量 i 是否在 Isr 中,若在则为 1,若不在则为 0,设置初始值为 0
flag=0
for j in ${Isr[*]}; do
#if 判断若 i 等于 j,则说明数组 Isr 中存在 Replicas 的值,改变 flag 的值,break跳出内层 for 循环
if [[ $i -eq $j ]]; then
flag=1
break
fi
done
#if 判断若 flag 仍未0 说明 broker ${i} 不在 Isr 列表中,故在 not_isr_broker 数组中记录
if [[ ${flag} -eq 0 ]]; then
not_isr_broker[$k]=${i}
#变量 k 自增 1
k=$[ ${k} + 1 ]
fi
done
#echo 输出 Isr 缺失的行的完整信息
echo ${line}
echo -e "\e[1;31m落后的 broker ID 为 ${not_isr_broker[*]}\e[0m"
#追加输出 not_isr_broker 数组内容到中间文件中
echo ${not_isr_broker[*]} >> not_isr_broker
#追加输出 isr 缺失的行的信息到中间文件中
echo ${line} >> lack_isr_info
fi
done
if [[ -e not_isr_broker ]]; then
#对 not_isr_broker 文件内容进行排序去重后输出
echo -e "\e[1;31m\nbroker 上落后的 partition 个数及 broker ID 为:\e[0m"
cat not_isr_broker | grep -oE "[0-9]+" | sort | uniq -c
#删除不必要的中间文件以节省磁盘空间
rm not_isr_broker
else
echo -e "\e[1;32m集群状态健康,没有落后的 broker\e[0m"
fi
if [[ -e lack_isr_info ]]; then
#对 lack_isr_info 文件内容进行排序去重后输出
echo -e "\e[1;31m\nTopic 落后的 partition 个数及 Topic ID 为:\e[0m"
awk '{print $2}' lack_isr_info | sort | uniq -c
#删除不必要的中间文件以节省磁盘空间
rm lack_isr_info
else
echo -e "\e[1;32m集群状态健康,没有缺少 Isr 的信息\e[0m"
fi
#删除不必要的中间文件以节省磁盘空间
rm topics_info