在实际生产开发当中,适当的设计agent的数量和模式,并很好的将数据采集过来,是我们分析数据的第一步,即先要有数据
业务系统那边进行埋点,记录日志,到服务器本地磁盘当中
考虑使用高可用模式,并使用级联模式,上游一个agent,下游两个agent,因为要对数据进行简单的清洗 、处理,所以需要一个自定义拦截器
上游agent
高可用模式
1个source taildir类型
1个channel file类型
高可用:2个sink 获得的数据一样 但同时只有一个sink在运转 当主sink发生故障 即使用备用sink进行传输数据 但每过一段时间(惩罚时间) 就会尝试着重新启动主sink
a1.sources = r1 a1.channels = c1 a1.sinks = k1 k2 a1.sources.r1.channels = c1 a1.sources.r1.type = TAILDIR a1.sources.r1.filegroups= g1 g2 a1.sources.r1.filegroups.g1= /opt/data/logdata/app/event.* a1.sources.r1.filegroups.g2= /opt/data/logdata/wx/event.* a1.sources.r1.headers.g1.dataType = app a1.sources.r1.headers.g2.dataType = wx a1.sources.r1.batchSize = 100 a1.sources.r1.interceptors = i1 a1.sources.r1.interceptors.i1.type=cn.study.demo03.SelectorInterceptor$EventStampInterceptorBuilder a1.sources.r1.interceptors.i1.to_encrypt = account a1.sources.r1.interceptors.i1.to_time = timeStamp a1.channels.c1.type = file a1.channels.c1.checkpointDir = /opt/data/flumedata/file-channel/checkpoint a1.channels.c1.dataDirs = /opt/data/flumedata/file-channel/data a1.sinks.k1.type=avro a1.sinks.k1.channel=c1 a1.sinks.k1.hostname = linux02 a1.sinks.k1.port = 41414 a1.sinks.k1.batch-size = 100 a1.sinks.k2.type=avro a1.sinks.k2.channel=c1 a1.sinks.k2.hostname = linux03 a1.sinks.k2.port = 41414 a1.sinks.k2.batch-size = 100 # 定义sink组及其配套的sink处理器 a1.sinkgroups = g1 a1.sinkgroups.g1.sinks = k1 k2 a1.sinkgroups.g1.processor.type = failover a1.sinkgroups.g1.processor.priority.k1 = 5 a1.sinkgroups.g1.processor.priority.k2 = 1 a1.sinkgroups.g1.processor.maxpenalty = 10000
下游 两个agent配置一样:
a1.sources = r1 a1.channels = c1 a1.sinks = k1 a1.sources.r1.channels = c1 a1.sources.r1.type = avro a1.sources.r1.bind = 0.0.0.0 a1.sources.r1.port = 41414 a1.channels.c1.type = file a1.channels.c1.checkpointDir = /opt/data/flumedata/file-channel/checkpoint a1.channels.c1.dataDirs = /opt/data/flumedata/file-channel/data a1.sinks.k1.channel = c1 a1.sinks.k1.type = hdfs a1.sinks.k1.hdfs.path = hdfs://linux01:8020/logdata/%{dataType}/%Y-%m-%d/ a1.sinks.k1.hdfs.filePrefix = DoitEduData a1.sinks.k1.hdfs.fileSuffix = .log.gz a1.sinks.k1.hdfs.rollInterval = 600 a1.sinks.k1.hdfs.rollSize = 268435456 a1.sinks.k1.hdfs.rollCount = 0 a1.sinks.k1.hdfs.batchSize = 100 a1.sinks.k1.hdfs.codeC = gzip a1.sinks.k1.hdfs.fileType = CompressedStream a1.sinks.k1.hdfs.useLocalTimeStamp = false
采集完成,存储到hdfs中
接下来构建ods层表数据
先根据两个业务域的数据 创建不同的表数据
#app表
DROP TABLE IF EXISTS `ods.event_app_log`;
CREATE EXTERNAL TABLE `ods.event_app_log`(
`account` string ,
`appid` string ,
`appversion` string ,
`carrier` string ,
`deviceid` string ,
`devicetype` string ,
`eventid` string ,
`ip` string ,
`latitude` double ,
`longitude` double ,
`nettype` string ,
`osname` string ,
`osversion` string ,
`properties` map,
`releasechannel` string ,
`resolution` string ,
`sessionid` string ,
`timestamp` bigint
)
PARTITIONED BY (`dt` string)
ROW FORMAT SERDE
'org.apache.hive.hcatalog.data.JsonSerDe'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
TBLPROPERTIES (
'bucketing_version'='2',
'transient_lastDdlTime'='1610337798'
);#wx表
DROP TABLE IF EXISTS `ods.event_wx_log`;
CREATE EXTERNAL TABLE `ods.event_wx_log`(
`account` string ,
`carrier` string ,
`deviceType` string ,
`ip` string ,
`latitude` double ,
`longitude` double ,
`netType` string ,
`openid` string ,
`osName` string ,
`osVersion` string ,
`resolution` string ,
`sessionId` string ,
`timeStamp` bigint ,
`properties` map,
`eventId` string
)
PARTITIONED BY (`dt` string)
ROW FORMAT SERDE
'org.apache.hive.hcatalog.data.JsonSerDe'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
TBLPROPERTIES (
'bucketing_version'='2',
'transient_lastDdlTime'='1610337798'
);写个脚本,将hdfs中的数据导入到hive表中
脚本------导入数据到ods层表(hive) wx表
#!/bin/bash
export JAVA_HOME=/opt/apps/jdk1.8.0_141/
export HIVE_HOME=/opt/apps/hive-3.1.2/
DT=$(date -d'-1 day' +%Y-%m-%d)${HIVE_HOME}/bin/hive -e "
load data inpath '/logdata/wx/${DT}' into table ods.event_wx_log partition(dt='${DT}')
"if [ $? -eq 0 ]
then
echo "${DT}app埋点日志,入库成功"
else
echo "入库失败"
fi导入成功之后:
日志采集常见错误总结:
采集日志过程中简单错误
1.自定义拦截器 使用了第三方jar包
需要在pom中加入打包的工具依赖 否则打包的jar包弄到集群上会没有依赖 比如fastjson
org.apache.maven.plugins
maven-shade-plugin
2.4.3
package
shade
*:*
META-INF/*.SF
META-INF/*.DSA
META-INF/*.RSA
2.采集数据 .* 不是以.结尾的所有的文件 这是一个正则表达式 比如event.* 会匹配以event开头的所有的文件
3.如果需要选择器 type=multiplexing 是负载均衡 a拿了b就不会拿
4.拦截器的type 里面有内部类 内部类需要用$连接 且代码中内部类 需要用static 否则报错,因为需要先实例化
5.采集过来的数据需要后缀名需要加上.gz 且下游sink要使用压缩的形式压缩数据
a1.sinks.k1.hdfs.codeC = gzip
a1.sinks.k1.hdfs.fileType = CompressedStream 否则 hdfs不能将不能识别出这种压缩数据
6.多次采集失败 每次重新采集需要 删掉上游source的偏移量和下游channel的记录的偏移量
具体在 rm -rf
/opt/data/flumedata /root/.flume 不过以后采集正常了就不要再删了,否则将从最开始采集数据,会积压很多数据
其他是一些不细心的小问题,配置文件用的时候 参考实战日志采集高级错误
1. flume的agent的堆内存大小
默认只有20M,在生产中是肯定不够的
一般需要给到1G
vi bin/flume-ng
搜索 Xmx ,并修改2.channel阻塞
启动flume之前,积压的数据过多,所以,source读得很快,而sink写hdfs速度有限,会导致反压
反压从下游传递到上游,上游的flume的运行日志中会不断报:channel已满,source重试这里就涉及到flume的运行监控
如果通过监控,发现channel频繁处于阻塞状态,可以通过如下措施予以改善(优化):
a. 如果资源允许,可以增加写入hdfs的agent机器数,通过负载均衡来提高整体吞吐量
b. 如果资源不允许,可以适当增大batchSize,来提高写入hdfs的效率
c. 如果资源不允许,可以配置数据压缩,来降低写入hdfs的数据流量
d. 如果source的数据流量不是恒定大于sink的写出速度,可以提高channel的缓存容量,来削峰
3.如果agent进程宕机,如何处理?
下游宕机:问题不大,我们配置高可用模式,会自动切换;当然,还是要告警,通知运维尽快修复;
上游宕机:问题较大,通过脚本监控进程状态,发现异常则重新拉起agent进程;并告警通知运维尽快查明原因予以修复;
agent进程监控:
FLUME在运行时,状态是否正常,吞吐量是否正常,需要监控
Flume自身具有向外提交状态数据的功能;但是它本身没有一个完善的监控平台;
开启内置监控功能
-Dflume.monitoring.type=http -Dflume.monitoring.port=34545
将监控数据发往ganglia进行展现
-Dflume.monitoring.type=ganglia -Dflume.monitoring.port=34890
脚本监控并唤醒进程,且发送邮件通知相关人员,尽快修复:
#!/bin/bash
export JAVA_HOME=/opt/apps/jdk1.8.0_191/
export HADOOP_HOME=/opt/apps/hadoop-3.1.1/
export HBASE_HOME=/opt/apps/hbase-2.0.6/查看所有的"....application"的详细 进程 -e 显示所有进程 -f 全格式
反选 选择不带有grep的进程 并统计行数
num=`ps -ef | grep "org.apache.flume.node.Application" | grep -v "grep" | wc -l`
定义一个方法,以启动flume进程
start(){
/opt/apps/flume-1.9.0/bin/flume-ng agent -c /opt/apps/flume-1.9.0/conf -f /opt/apps/flume-1.9.0/agentsconf/doit19-xiayou.conf -n a1
}
if [ $num -eq 1 ]
then
echo "ok"
else
echo "flume进程崩掉拉!"
echo "flume进程崩掉拉!" | mail -s "集群组件告警邮件" 215931921@qq.com
start
fi脚本写好了
1)接下来,现在集群中装邮件的服务
yum install mailx -y
2)配置邮件账号、服务器等
vi /etc/mail.rcset bsdcompat
set smtp=smtp.qq.com # 这里填入smtp地址
set smtp-auth=login # 认证方式
set smtp-auth-user=1074386747@qq.com # 这里输入邮箱账号
set smtp-auth-password=xxxxxxx # 这里填入密码,这里是授权码而不是邮箱密码
set ssl-verify=ignore # 忽略证书警告
#set nss-config-dir=/etc/pki/nssdb # 证书所在目录
set from=1074386747@qq.com 周星星 # 设置发信人邮箱和昵称
更多学习、面试资料尽在微信公众号:Hadoop大数据开发