系列文章目录
本文衔接采集日志通过logstash写入到hdfs,因前几天发现集群中毒,同运维人员对集群的访问权限做了限制,导致通过logstash写入hfds延迟严重,所以有了本文的替代方案
采集日志通过logstash写入hdfs_logstash output hdfs_冰帆<的博客-CSDN博客
前言
大数据的采集日志到hdfs,然后通过mr写入hive ods表,一般都是企业数据采集的必经之路。详见:大数据技术架构图_冰帆<的博客-CSDN博客
原本是同logstash消费kafka的数据实时写入到hdfs,因logstash写入到hdfs突然延迟严重,导致启动临时方案如下:通过logstash写入到本地文件(一小时一个文件),然后通过dolphinscheduler调度,将本地文件上传到hdfs相应的目录。
本文使用到的工具如下:
消息队列:kafka,采集日志通过filebeat将实时的日志推到kafka
logstash:消费kafka写入到本地文件,每小时一个文件
dolphinscheduler:调度任务,每小时将文件上传到hdfs目录。
一、流程图
数据流程图:
因本文主要是替换方案,以最小改动,最快上线的方案 。
二、logstash写入本地文件
1.logstash配置文件
input {
kafka {
bootstrap_servers => "hd.n132:9092,hd.n133:9092,hd.n134:9092"
topics => ["filebeat_records","filebeat_hearts"]
# codec => "json"
consumer_threads => 6
decorate_events => true
codec => "json"
auto_offset_reset => "latest"
group_id => "logstash-to-file" ##logstash 集群需相同}
}filter {
grok {
match => {
"message" => "\[%{DATA:uploadtimestamp}\] \[%{DATA:log}\] \[%{DATA:clientid}\] \[%{DATA:level}\]-%{GREEDYDATA:msgdata}"
}
}date {
match => ["uploadtimestamp","yyyy-MM-dd HH:mm:ss"]
target => "time_local"
}ruby {
code => "event.set('index.date', event.get('time_local').time.localtime.strftime('%Y-%m-%d'))"
}ruby {
code => "event.set('index.hour', event.get('time_local').time.localtime.strftime('%H'))"
}}
filter {
if "_grokparsefailure" in [tags] {
# drop {}
}
}output {
if "_grokparsefailure" in [tags] {
file {
path => "/home/hadoop/logstash/logs/logstash-records-log-%{index.date}-%{index.hour}"
# codec => line {
# format => "%{message}"
# }
}}
else if [fields][filetype] == "heart" {
#webhdfs {
# host => "hd.m1"
# port => 50070
# user => "hadoop"
# flush_size => 5000
# idle_flush_time => 5
# retry_interval => 3
# path => "/input/heartData/%{index.date}/%{index.date}-%{index.hour}"
# codec => line {
# format => "%{message}"
# }
# }
file {
path => "/home/hadoop/logstash/logs/heartData/%{index.date}/%{index.date}-%{index.hour}"
codec => line {
format => "%{message}"
}
}
}
else if [fields][filetype] == "records" {
#webhdfs {
# host => "hd.m1"
# port => 50070
# user => "hadoop"
# flush_size => 5000
# idle_flush_time => 5
# retry_interval => 3
# path => "/input/machine_log/%{index.date}/%{index.date}-%{index.hour}"
# codec => line {
# format => "%{message}"
# }
# }
file {
path => "/home/hadoop/logstash/logs/machine_log/%{index.date}/%{index.date}-%{index.hour}"
codec => line {
format => "%{message}"
}
}}
#stdout { codec => rubydebug }# file {
# path => "/home/hadoop/logstash/logs/logstash-records-log-%{index.date}-%{index.hour}"
# codec => line {
# format => "%{message}"
# }
# }}
配置代码解读:消费kafka两个topic:
"filebeat_records","filebeat_hearts"
每小时分别写入到:
logstash/logs/machine_log
logstash/logs/heartData
每天一个目录,每小时一个文件。
2.启动logstash
代码如下(示例):nohup ./bin/logstash -f config/filebeat-logstash-file.conf &
三、调度上传到hdfs脚本
脚本如下:
echo "file to hdfs"
DATE_HOUR=$(date -d last-hour +%Y-%m-%d-%H)
DATE=$(date -d last-hour +%Y-%m-%d)
if [ -z "$1" ]; then
DATE=$DATE
else
DATE=$1
DATE_HOUR=$2
fi
RECORDS_SRC=/input/machine_log/$DATE/
HEARTS_SRC=/input/heartData/$DATE/
RECORDS_PATH=/home/hadoop/logstash/logs/machine_log/$DATE
HEARTS_PATH=/home/hadoop/logstash/logs/heartData/$DATE
RECORDS_DST=/home/hadoop/logstash/logs/machine_log/$DATE/$DATE_HOUR
HEARTS_DST=/home/hadoop/logstash/logs/heartData/$DATE/$DATE_HOUR
hadoop fs -test -e $RECORDS_SRC
if [ $? -eq 0 ]; then
echo "File is exist!"
else
echo "File is not exist!"
hdfs dfs -mkdir -p $RECORDS_SRC
fi
hadoop fs -test -e $HEARTS_SRC
if [ $? -eq 0 ]; then
echo "File is exist!"
else
echo "File is not exist!"
hdfs dfs -mkdir -p $HEARTS_SRC
fi
if [ ! -d "${RECORDS_PATH}" ]; then
mkdir ${RECORDS_PATH}
fi
if [ ! -d "${HEARTS_PATH}" ]; then
mkdir ${HEARTS_PATH}
fi
scp -r -P 40 hd-es-1:$RECORDS_DST $RECORDS_DST
scp -r -P 40 hd-es-1:$HEARTS_DST $HEARTS_DST
hdfs dfs -put -f $RECORDS_DST $RECORDS_SRC
hdfs dfs -put -f $HEARTS_DST $HEARTS_SRC
rm $RECORDS_DST
rm $HEARTS_DST
ssh -n -p 40 hd-es-1 "rm $RECORDS_DST"
ssh -n -p 40 hd-es-1 "rm $HEARTS_DST"
各个节点服务器
脚本流程介绍:
1)设定自动的日期与小时值,
2)在hdfs上判断日期目录是否存在,不存在则创建。
3)在hd.n106 判断日期目录是否存在,不存在创建
4)从hd-es-1 scp 文件到hd.n106 同名目录
5)上传hd.n106 本地文件到hdfs 相应目录
6)删除本地hd.n106 相应文件
7)删除hd-es-1 相应文件
四、dolphinscheduler调度
在dolphinscheduler 上创建shell工作流
shell 脚本如下:
ssh -n -p 40 hd.n106 'sh /home/hadoop/job/file-to-hdfs.sh'
远程执行hd.n106 上的/home/hadoop/job/file-to-hdfs.sh 文件。
设置定时管理:
看看最终的结果运行效果:
与之前logstash直接写入hdfs基本一致。
放一张之前logstash 写入hdfs 的图:
总结
遇到问题,如果原有路径解决需要很长的时间,需要尽快有替代方案,解决眼前的问题,不能影响后面数仓的任务调度。解决问题后,再去查原logstash写入hdfs慢的问题。