flume中sink到hdfs,文件系统频繁产生文件,文件滚动配置不起作用?
在测试hdfs的sink,发现sink端的文件滚动配置项起不到任何作用,配置如下:
a1.sinks.k1.type=hdfs
a1.sinks.k1.channel=c1
a1.sinks.k1.hdfs.useLocalTimeStamp=true
a1.sinks.k1.hdfs.path=hdfs://192.168.11.177:9000/flume/events/%Y/%m/%d/%H/%M
a1.sinks.k1.hdfs.filePrefix=XXX
a1.sinks.k1.hdfs.rollInterval=60
a1.sinks.k1.hdfs.rollSize=0
a1.sinks.k1.hdfs.rollCount=0
a1.sinks.k1.hdfs.idleTimeout=0
这里配置的是60秒,文件滚动一次,也就每隔60秒,会新产生一个文件【前提,flume的source端有数据来】
但是当我启动flume的时候,运行十几秒,不断写入数据,发现hdfs端频繁的产生文件,每隔几秒就有新文件产生
而且在flume的日志输出可以频繁看到这句:
[WARN] Block Under-replication detected. Rotating file.
只要有这句,就会产生一个新的文件
意思就是检测到复制块正在滚动文件,结合源码看下:
private boolean shouldRotate() {
boolean doRotate = false; if (writer.isUnderReplicated()) {
this.isUnderReplicated = true;
doRotate = true;
} else {
this.isUnderReplicated = false;
} if ((rollCount > 0) && (rollCount <= eventCounter)) {
LOG.debug("rolling: rollCount: {}, events: {}", rollCount, eventCounter);
doRotate = true;
} if ((rollSize > 0) && (rollSize <= processSize)) {
LOG.debug("rolling: rollSize: {}, bytes: {}", rollSize, processSize);
doRotate = true;
} return doRotate;
}
这是判断是否滚动文件,但是这里面的第一判断条件是判断是否当前的HDFSWriter正在复制块
public boolean isUnderReplicated() {
try {
int numBlocks = getNumCurrentReplicas();
if (numBlocks == -1) {
return false;
}
int desiredBlocks;
if (configuredMinReplicas != null) {
desiredBlocks = configuredMinReplicas;
} else {
desiredBlocks = getFsDesiredReplication();
}
return numBlocks < desiredBlocks;
} catch (IllegalAccessException e) {
logger.error("Unexpected error while checking replication factor", e);
} catch (InvocationTargetException e) {
logger.error("Unexpected error while checking replication factor", e);
} catch (IllegalArgumentException e) {
logger.error("Unexpected error while checking replication factor", e);
}
return false;
}
通过读取的配置复制块数量和当前正在复制的块比较,判断是否正在被复制
if (shouldRotate()) {
boolean doRotate = true; if (isUnderReplicated) {
if (maxConsecUnderReplRotations > 0 &&
consecutiveUnderReplRotateCount >= maxConsecUnderReplRotations) {
doRotate = false;
if (consecutiveUnderReplRotateCount == maxConsecUnderReplRotations) {
LOG.error("Hit max consecutive under-replication rotations ({}); " +
"will not continue rolling files under this path due to " +
"under-replication", maxConsecUnderReplRotations);
}
} else {
LOG.warn("Block Under-replication detected. Rotating file.");
}
consecutiveUnderReplRotateCount++;
} else {
consecutiveUnderReplRotateCount = 0;
}
以上方法,入口是shouldRotate()方法,也就是如果你配置了rollcount,rollsize大于0,会按照你的配置来滚动的,但是在入口进来后,发现,又去判断了是否有块在复制;
里面就读取了一个固定变量maxConsecUnderReplRotations=30,也就是正在复制的块,最多之能滚动出30个文件,如果超过了30次,该数据块如果还在复制中,那么数据也不会滚动了,doRotate=false,不会滚动了,所以有的人发现自己一旦运行一段时间,会出现30个文件
再结合上面的源码看一下:
如果你配置了10秒滚动一次,写了2秒,恰好这时候该文件内容所在的块在复制中,那么虽然没到10秒,依然会给你滚动文件的,文件大小,事件数量的配置同理了。
为了解决上述问题,我们只要让程序感知不到写的文件所在块正在复制就行了,怎么做呢??
只要让isUnderReplicated()方法始终返回false就行了
该方法是通过当前正在被复制的块和配置中读取的复制块数量比较的,我们能改的就只有配置项中复制块的数量,而官方给出的flume配置项中有该项
hdfs.minBlockReplicas
Specify minimum number of replicas per HDFS block. If not specified, it comes from the default Hadoop config in the classpath.
默认读的是hadoop中的dfs.replication属性,该属性默认值是3
这里我们也不去该hadoop中的配置,在flume中添加上述属性为1即可
配置如下:
a1.sinks.k1.type=hdfs
a1.sinks.k1.channel=c1
a1.sinks.k1.hdfs.useLocalTimeStamp=true
a1.sinks.k1.hdfs.path=hdfs://192.168.11.177:9000/flume/events/%Y/%m/%d/%H/%M
a1.sinks.k1.hdfs.filePrefix=cmcc
a1.sinks.k1.hdfs.minBlockReplicas=1
#a1.sinks.k1.hdfs.fileType=DataStream
#a1.sinks.k1.hdfs.writeFormat=Text
a1.sinks.k1.hdfs.rollInterval=60
a1.sinks.k1.hdfs.rollSize=0
a1.sinks.k1.hdfs.rollCount=0
a1.sinks.k1.hdfs.idleTimeout=0
这样程序就永远不会因为文件所在块的复制而滚动文件了
flume中sink到hdfs,文件系统频繁产生文件,文件滚动配置不起作用?的更多相关文章
- flume中sink到hdfs,文件系统频繁产生文件和出现乱码,文件滚动配置不起作用?
问题描述 解决办法 先把这个hdfs目录下的数据删除.并修改配置文件flume-conf.properties,重新采集. # Licensed to the Apache Software Fou ...
- django中使用FastDFS分布式文件系统接口代码实现文件上传、下载、更新、删除
运维使用docker部署好之后FastDFS分布式文件系统之后,提供给我接口如下: fastdfs tracker 192.168.1.216 192.168.1.217 storage 192.16 ...
- Flume中的HDFS Sink配置参数说明【转】
转:http://lxw1234.com/archives/2015/10/527.htm 关键字:flume.hdfs.sink.配置参数 Flume中的HDFS Sink应该是非常常用的,其中的配 ...
- flume中HdfsSink参数说明
flume到hdfsSink: type hdfs path 写入hdfs的路径,需要包含文件系统标识,比如:hdfs://namenode/flume/webdata/ 可以使用flume提供的日期 ...
- HDFS文件系统
Hadoop 附带了一个名为 HDFS(Hadoop分布式文件系统)的分布式文件系统,专门存储超大数据文件,为整个Hadoop生态圈提供了基础的存储服务. 本章内容: 1) HDFS文件系统的特点,以 ...
- hadoop(三)HDFS 文件系统
Hadoop 附带了一个名为 HDFS(Hadoop 分布式文件系统)的分布式文件系统,专门 存储超大数据文件,为整个 Hadoop 生态圈提供了基础的存储服务. 本章内容: 1) HDFS 文件系统 ...
- Flume监听文件目录sink至hdfs配置
一:flume介绍 Flume是一个分布式.可靠.和高可用的海量日志聚合的系统,支持在系统中定制各类数据发送方,用于收集数据:同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能 ...
- Flume实时监控目录sink到hdfs,再用sparkStreaming监控hdfs的这个目录,对数据进行计算
目标:Flume实时监控目录sink到hdfs,再用sparkStreaming监控hdfs的这个目录,对数据进行计算 1.flume的配置,配置spoolDirSource_hdfsSink.pro ...
- 在Spark shell中基于HDFS文件系统进行wordcount交互式分析
Spark是一个分布式内存计算框架,可部署在YARN或者MESOS管理的分布式系统中(Fully Distributed),也可以以Pseudo Distributed方式部署在单个机器上面,还可以以 ...
随机推荐
- TP5.0 PHPExcel 数据表格导出导入(原)
今天看的是PHPExcel这个扩展库,Comporse 下载不下来,最后只能自己去github里面手动下载,但有一个问题就是下载下来的PHPExcel没有命名空间,所以框架里面的use根本引入不进去, ...
- vue刷新当前路由
原理:跳转到空白页,然后再快速跳回原来的页面: 1,新建一个refresh.vue页面并添加到路由,页面内容如下 <script> export default { beforeRoute ...
- 【Monkey】Monkey基础概念
1.什么是Monkey? 发送伪随机用户事件的命令 2.Monkey在哪? 在手机系统里 3.什么是ADB? 4.MonkeyScript 一组可以被Monkey识别的命令集合,可以完成重复固定的操作 ...
- k8s 部署rabbitmq单节点
apiVersion: extensions/v1beta1 kind: Deployment metadata: annotations: fabric8.io/iconUrl: https://r ...
- CPU、GPU、CUDA、cuDNN
CPU擅长逻辑处理控制,GPU适合高强度的并行计算任务,为什么会存在这种差别?今天搜集了些相关资料,摘抄总结如下. 一.什么是GPU GPU这个概念是由Nvidia公司于1999年提出的.GPU是显卡 ...
- log日志文件
单文件写 根据日志的等级是否写入,下面的一个例子就是等级为10,大于等于等级10的记录,小于的话就不记录,在创建之前先进行基本的日志格式配置 import logging logging.basicC ...
- C++学习笔记(一):C++基础知识
一.C++基础知识 新的数据类型 C语言中的数据类型 C++中新的数据类型 思考:新的数据类型有什么好处?请看下面的代码: 可以见得:新的类型使整个程序更加简洁,程序变得易读易懂!这个就是bool类型 ...
- Servlet(2)
HttpServlet 简介: Servlet 就是一个普通的java类,是运行在web容器上(tomcat)上的一个java类 用来通过Servlet中的代码,接受Http中浏览器的请求信息,以及对 ...
- Dynamic learning rate in training - 培训中的动态学习率
I'm using keras 2.1.* and want to change the learning rate during training. I know about the schedul ...
- 学习python D1
shell脚本最擅长移动文件和替换文本,并不适合GUI界面或者游戏开发,Python是一种解释型语言,在程序开发阶段可以为你节省大量时间 Python2的用户输入需要用raw_input()而非inp ...