Flume快速入门:安装配置与监控端口实例详解 Flume快速入门系列讲到第二篇该动手了。上一篇如果把Flume是什么、三个核心组件Source、Channel、Sink的关系讲清楚了那这一篇的目标就非常明确把Flume装起来让它监听一个端口然后你随手往端口塞几个字符Flume能把这段数据变成一个个Event打印出来。这个例子是Flume世界的“Hello World”也叫监控端口实例几乎所有入门教程都会用它来验证环境。我第一次装Flume的时候概念其实早就看明白了但真正卡住我的不是概念而是两件小事装完之后不知道怎么验证安装成功启动agent之后屏幕上什么都没有我以为程序挂了后来才发现是日志级别和输出方式没配好。所以这篇我会把“安装验证”和“启动参数”这两个容易被一带而过的细节讲透尽量让你少走弯路。这篇适合刚看完Flume概念、准备动手做实验的同学。不需要有分布式系统基础只要会基本的Linux命令就能跟上。Windows上也能跑只是有些细节差异我会单独说明。1. 安装前的三个决定Flume版本、JDK版本和安装包来源安装Flume本身不难难的是安装之前的一次决定装哪个版本在什么Java环境上跑用什么方式下载这些决定在教程里通常被一笔带过但它们恰恰决定了你后面会不会遇到莫名其妙的坑。1.1 版本怎么选1.9.0为什么是更多人默认的选择Flume的版本号不算多但版本之间的差异值得了解。我列一下我接触过的几个版本版本发布时间特点1.6.02015年很多发行版内置的版本部分老环境仍在使用网上资料多1.7.02016年相对小众的过渡版本1.8.02017年修复了一批bug但存在时间较短1.9.02017年长期稳定版绝大多数教程和生产环境的选择社区资源最丰富1.11.02023年修复了旧版本的部分问题核心用法与1.9.0基本一致我的建议很直接如果是学习或者快速验证直接选1.9.0。一方面是你遇到任何问题搜索引擎几乎都能找到前人记录的解决方案另一方面是很多第三方组件比如各种Source、Sink插件默认就是按1.9.0编译的版本越偏越容易遇到不匹配。如果你的项目是全新开始的也想用更新一点的版本那选1.11.0也行它的核心用法和1.9.0几乎没有差别配置文件格式是一样的。唯一需要注意的是新版在网上能找到的踩坑记录相对少遇到冷门问题得自己啃源码。1.2 JDK环境Java 8是安全选项别用太新的JDK直接跑Flume本身是Java写的整个启动过程要靠Java运行时所以JDK版本直接决定Flume能不能正常运行。以Flume 1.9.0为例官方要求Java 8实际跑下来Java 8也是体验最顺的。有些同学机器上装的是Java 11、17甚至更高版本这在很多场景下没问题但Flume的启动脚本和一些内置组件在更高版本JDK上可能报出奇怪错误比如某些反射调用的权限问题或者控制台出现你根本没配置过却一直在刷的告警。我的做法是给Flume专门准备一个Java 8环境。如果你机器上已经装了别的版本不用卸载只需要在flume-env.sh里把JAVA_HOME明确指向Java 8的路径即可影响范围最小。这个做法在实际环境里很常见因为一台机器上并存多个JDK本来就是常态。另外要注意Flume的启动脚本在Linux下是flume-ngWindows下是flume-ng.cmd。两者都会通过JAVA_HOME去定位java命令所以JAVA_HOME这个环境变量必须配好否则启动时会直接看到Unable to find java之类的报错。1.3 安装包从哪里下认准二进制包记得做校验Flume的官方下载页面在Apache Archive里所有历史版本都能找到。国内环境下载Apache软件经常速度不稳定用镜像站是常见做法选离自己网络最近的即可。这里要强调一个很多人容易忽略的点下载的时候一定认准名字里带bin的包。拿Apache Flume 1.9.0来说下载页面通常有两个压缩包apache-flume-1.9.0-bin.tar.gz编译好的二进制包解压即用apache-flume-1.9.0-src.tar.gz源码包需要自己编译对绝大多数人来说选bin包就够了不需要碰源码包。下载完之后最好做一次完整性校验Apache官网会提供对应的SHA512校验文件Linux下用sha512sum命令核对一下避免下载过程中文件损坏。这一步经常被跳过但一旦你遇到解压报错或者启动时报类找不到回头查一下很可能就是包坏了。1.4 解压后的目录结构一眼看明白拿到bin包之后解压出来的目录大致长这样apache-flume-1.9.0-bin/ ├── bin/ # 启动脚本目录Linux下是flume-ngWindows下是flume-ng.cmd ├── conf/ # 配置文件目录agent配置、日志配置都在这里 ├── lib/ # Flume运行所需的全部jar包数量非常多 ├── tools/ # 一些辅助工具与依赖 └── docs/ # 官方文档这个结构建议先有个印象。后面写agent配置文件默认会放在conf目录下要是遇到“类找不到”或者“组件类型不存在”这种报错多半是lib目录下缺对应的jar包到时候你就知道去哪里排查了。另外conf目录下默认会有几个文件flume-env.sh.template、flume-env.ps1.template、log4j.properties、flume-conf.properties.template。带template后缀的都需要自己复制一份去掉后缀再修改这个习惯跟很多Java项目的配置方式一样别在原模板文件上直接改否则升级或重置时你自己的改动会被覆盖。2. 安装步骤里的隐藏细节环境变量、配置文件与验证方式这一节是我踩坑最多的地方。很多人以为Flume安装就是“解压、配个环境变量、完事”但对Flume来说安装验证和解压部署的规范性直接影响后面做实验的体验。2.1 解压到固定目录用软链接管理版本解压本身没什么好说的tar命令一下就行。但我建议不要解压完就把目录随手丢在下载文件夹里最好放到一个专门的路径比如/opt/flume或者你自己习惯的工作目录。一个我比较推荐的做法是保留版本号目录再用软链接指过去tar -zxvf apache-flume-1.9.0-bin.tar.gz -C /opt/ ln -s /opt/apache-flume-1.9.0-bin /opt/flume这样做的目的是方便以后切换版本。Flume升级的时候只需要把软链接换到新版本目录不需要改任何配置文件也方便你自己记清楚当前用的是哪个版本。2.2 环境变量配置JAVA_HOME和FLUME_HOME都配齐Flume运行需要两个环境变量一个是JAVA_HOME一个是FLUME_HOME。编辑~/.bashrc或者/etc/profile在末尾追加export JAVA_HOME/usr/local/java/jdk1.8.0_202 export PATH$JAVA_HOME/bin:$PATH export FLUME_HOME/opt/flume export PATH$FLUME_HOME/bin:$PATH配完之后记得让配置生效source ~/.bashrc这里有个容易出错的地方如果你机器上有多个Java版本一定要确保JAVA_HOME指向的是Java 8。我之前遇到过一台机器默认java命令是较新版本但JAVA_HOME没设Flume启动脚本用的是PATH里找到的java结果Flume能启动但控制台出现一堆看不懂的告警。所以JAVA_HOME和PATH里的java最好保持一致否则你会在排查时精神分裂。2.3 修改flume-env.sh最重要的一个文件conf目录下默认的flume-env.sh是个template文件第一步是复制cd /opt/flume/conf cp flume-env.sh.template flume-env.sh然后用编辑器打开flume-env.sh找到JAVA_HOME这一行设置成你自己的Java 8路径JAVA_HOME/usr/local/java/jdk1.8.0_202如果你机器内存比较紧张也可以顺手改一下JAVA_OPTS里的堆内存参数。默认配置通常能满足实验需求我一般不动它等到了大数据量的场景再调。Flume这种Java进程JVM参数调错往往比业务配置写错更容易让人挠头记得每次改动只动一个变量。2.4 安装验证flume-ng version到底该看到什么环境变量配好、flume-env.sh改完之后在任意目录执行flume-ng version如果输出类似下面这样的版本信息说明安装这一关过了Flume 1.9.0 Source code repository: https://gitbox.apache.org/repos/asf/flume.git Revision: ...如果提示command not found基本可以肯定是PATH没配好回到2.2检查。如果出现Unable to determine Hadoop version这样的信息不用慌这是Flume在探测Hadoop环境变量。Flume本身可以不依赖Hadoop运行只是很多内置组件跟Hadoop相关才做这个探测干净环境里缺少HADOOP_HOME时出现这行提示是正常的不影响普通组件的运行。2.5 Windows下的安装差异脚本、环境变量与路径格式如果你在Windows上做这套实验有几个点需要提前注意。第一启动脚本是flume-ng.cmd而不是flume-ng并且需要进入bin目录执行或者把FLUME_HOME\bin写进PATH。第二Windows下没有flume-env.sh对应的是flume-env.ps1.template文件。如果你用PowerShell可以复制并修改它或者在系统环境变量里直接配置JAVA_HOME和FLUME_HOME。第三Windows的环境变量修改完要重新打开终端才生效而且某些电脑的cmd对等号和逗号的解析比较奇怪遇到命令无法解析时可以给-D参数加上双引号或者改用PowerShell执行。第四Windows不自带nc命令所以后面做端口测试时我更推荐直接用Python发送数据具体方法会在4.2里给出。3. 监控端口实例用一份配置文件把Source、Channel、Sink串起来安装搞定之后进入正题监控一个端口。所谓监控端口就是让Flume监听某个TCP端口任何客户端往这个端口发送的数据都会被Flume接收并处理。3.1 为什么要选netcat source memory channel logger sinkFlume支持的Source类型很多比如监控文件变化的tail、监控目录的spooldir、接收HTTP请求的http等Sink也很多比如写入HDFS的hdfs、输出到Kafka的kafka等。但入门实例我强烈推荐这个组合netcat source监听TCP端口把收到的每一行数据当作一个Event简单直接最适合手动测试。memory channel事件保存在内存队列中吞吐量高配置简单但机器重启会丢数据因此只适合测试场景。logger sink把每个Event直接打印到Flume的日志里即时反馈让你肉眼确认Flume确实收到了数据。这个组合的意义在于它把一个完整的数据传输链路压缩到了极致数据从网络端口进去放进内存队列再从日志里打印出来。整个链路不需要任何外部系统一台空机器就能跑出了问题能立刻看出来是哪一环坏了。3.2 配置文件逐行拆解在conf目录下新建一个文件名字随意我习惯叫flume-netcat.conf# agent名字叫a1各组件名称自定但要保持一致 a1.sources r1 a1.sinks k1 a1.channels c1 # 配置source类型为netcat监听本机的44444端口 a1.sources.r1.type netcat a1.sources.r1.bind localhost a1.sources.r1.port 44444 # 配置sink类型为logger将event输出到日志 a1.sinks.k1.type logger # 配置channel类型为memory内存队列容量和事务容量先用默认值 a1.channels.c1.type memory a1.channels.c1.capacity 1000 a1.channels.c1.transactionCapacity 100 # 绑定关系source把event放进c1sink从c1取event a1.sources.r1.channels c1 a1.sinks.k1.channel c1我来逐段解释这个理解透了后面所有Flume配置文件你都能看懂。首先是顶部三行a1.sources r1 a1.sinks k1 a1.channels c1这里a1是agent的名字r1、k1、c1分别是source、sink、channel的别名这些名字完全由你自己决定没有强制要求用r1/k1/c1。关键是后面所有配置项都要用同样的名字去引用比如a1.sources.r1.type就是在给别名r1的source设置type。然后是source的配置a1.sources.r1.type netcat a1.sources.r1.bind localhost a1.sources.r1.port 44444type netcat表示使用NetcatSource它会在bind指定的地址和port指定的端口上开启TCP监听。bind可以填localhost也可以填具体IP甚至填0.0.0.0表示监听所有网卡这样局域网内的机器也能连上来。sink的配置最简单a1.sinks.k1.type loggerlogger类型的sink会把Event以固定格式打印到日志里它没有任何必须额外配置的参数非常适合调试。channel的配置有两行关键参数a1.channels.c1.type memory a1.channels.c1.capacity 1000 a1.channels.c1.transactionCapacity 100capacity表示channel中最多能缓存多少个EventtransactionCapacity表示每次事务最多批量传输多少个Event。这两个参数涉及Flume的可靠性机制简单理解channel相当于一个缓冲区capacity是缓冲区大小transactionCapacity是每次取放的批次大小。最后是绑定关系a1.sources.r1.channels c1 a1.sinks.k1.channel c1注意这里的单复数。source可以对接多个channel所以是复数channelssink只能从一个channel取数据所以是单数channel。这个细节容易混淆建议记牢。3.3 理解Agent的运作逻辑一条流水线的三个工位如果光看配置还不够直观可以换个角度agent是一条流水线source是进货口channel是仓库sink是出货口。客户端往端口发数据等价于往进货口扔原材料。NetcatSource把原材料一行文本打包成一个标准件Event放进仓库channel。LoggerSink从仓库取出标准件拆包打印出来让你看清里面装的是什么。Event是Flume传输的最小单位结构上有两部分headers和body。headers是一个键值对字典可以附带一些元信息body是真正的数据内容。logger sink打印Event的时候会同时打出headers和body的十六进制形式这正是我们验证数据有没有完整到达的手段。3.4 配置文件里的常见书写错误三个高频低级坑写这份配置文件时有三个低级错误我见别人犯过无数次自己也犯过在这里提前排掉。第一个错误是agent名字对不上。启动命令里的--name a1和配置文件里的a1.sources这一整段前缀必须一致。如果你改了agent名比如改成agent1那么文件里所有以a1开头的行都要换成agent1。第二个错误是组件别名写错。比如source别名是r1但配置sink时误写成了a1.sinks.r1.type而不是a1.sinks.k1.type。Flume不会帮你检查别名是否合理它只会告诉你某个组件找不到配置然后启动失败。第三个错误是漏掉绑定关系。有些同学把source、sink、channel三块都配置了但忘记写最后那两行绑定结果source和sink都启动了数据却不会流动日志里也看不出来。排查时先看有没有这两行。4. 启动命令与数据验证清楚地看到Flume在工作配置文件写好了接下来就是启动agent、发数据、看日志。这个过程是整个实验最有成就感的环节也是理解Flume数据流的关键。4.1 flume-ng agent命令的每个参数说明启动agent的命令模板如下flume-ng agent \ --conf conf \ --name a1 \ --conf-file conf/flume-netcat.conf \ -Dflume.root.loggerINFO,console如果你在Windows下用的是bin/flume-ng.cmd路径写法稍有不同但参数是一样的。四个参数逐个说明--conf conf指定Flume自身配置所在的目录通常是conf目录里面要有log4j.properties等文件。--name a1指定agent的名字必须跟配置文件中a1开头的前缀一致对不上会报错。--conf-file conf/flume-netcat.conf指定agent配置文件的路径就是刚才写的那个文件。-Dflume.root.loggerINFO,console这是最容易遗漏的一个参数它把Flume的root logger设为INFO级别并输出到控制台。不加这个你启动后可能什么都看不到不是程序没启动只是日志跑别处去了。启动后控制台会看到一系列INFO日志大致如下时间戳和具体行号会不同INFO node.Application: Starting INFO node.Application: Attempting to start agent a1 INFO source.NetcatSource: Source starting INFO source.NetcatSource: Created serverSocket: {serverSocketServerSocket[addr/0:0:0:0:0:0:0:1,localport44444]}看到Created serverSocket就说明netcat source已经成功监听在44444端口上了。到这里agent已经跑起来了。4.2 往44444端口发数据三种方式选一种就行接下来用客户端往44444端口发送数据。Linux和macOS下最常用的命令是ncnc localhost 44444执行后输入任意文本比如hello flume然后回车。如果不想手动敲也可以直接管道传入echo hello flume | nc localhost 44444没有nc命令的环境用telnet也能达到同样效果telnet localhost 44444如果这两个都没有比如在Windows的PowerShell下可以用一个Python脚本发送数据Python几乎每个环境都有不需要额外安装import socket s socket.socket() s.connect((localhost, 44444)) s.sendall(bhello flume from python\n) s.close()我自己的习惯是Linux下直接用ncWindows下用Python理由很简单省事。4.3 在日志里看到Event数据链路闭环了当数据发送成功后把目光切回Flume的控制台。你会看到类似这样的输出INFO sink.LoggerSink: Event: {headers:{} body: 68 65 6C 6C 6F 20 66 6C 75 6D 65 0A }这行日志是logger sink打印出来的其中body后面的十六进制就是hello flume\n每个字符的ASCII码68对应h65对应e6C对应l6F对应o20对应空格66对应f6C对应l75对应u6D对应m65对应e0A对应换行看到这行Event输出就说明整条链路已经通了你的文本通过TCP端口进入NetcatSource被包装成Event放进memory channelLoggerSink再把它取出来打印在日志里。4.4 发送多行数据时Event数量和你预期的关系用nc连上端口后如果你一次输入多行文本Flume会为每一行生成一个Event。这是因为NetcatSource默认按行解析每收到一个换行符就认为一条完整数据到达了。我遇到过有人在这里产生困惑明明自己粘贴了一段5行的配置为什么日志里打印了5个Event其实这正是Flume的工作方式。理解了这个规则你会明白一个很重要的点以后接入真实日志文件时日志文件里的一行通常就对应一个Event而多行堆栈信息需要专门的解析器去合并那是后话。5. 实战中必然遇到的几个坑端口、日志级别与跨平台细节我见过很多同学卡在莫名其妙的报错上而且这些报错往往不是因为配置写错而是卡在一些环境层面的细节。下面这几个是我自己实测或者帮别人排查时最高频的问题。5.1 端口被占用启动即报错怎么处理如果你启动agent时看到类似这样的日志java.net.BindException: Address already in use说明44444端口已经被某个进程占用了。处理方法很简单换一个端口比如改成44445记得同时改配置文件里的port和后续nc命令里的端口。找到占用进程并处理仅限测试环境lsof -i:44444 kill -9 pid这个报错本身没什么技术含量但容易让人慌张。看到BindException先冷静99%是端口冲突。另外还有一个容易被忽略的点如果你bind写的是localhost某些机器上可能会解析出IPv6地址导致你用自己的IP去连却连不上这时候把bind改成0.0.0.0往往就通了。5.2 启动后控制台没有任何输出十有八九是日志级别问题这个坑我开头提过但值得单独再讲一遍。很多人第一次启动agent发现控制台只输出几行甚至什么都没输出以为程序卡住了直接CtrlC打断然后到处找问题。其实agent可能已经正常启动了只是日志级别和输出目标不对。Flume的日志由log4j控制conf目录下的log4j.properties文件定义了日志写到文件还是控制台默认往往不是全量输出到控制台。解决办法有两个一是在启动命令里强制指定-Dflume.root.loggerINFO,console二是在conf/flume-env.sh里把JAVA_OPTS加上同样的参数。我更推荐第一种因为它不修改任何文件只在启动时生效排查问题时更干净。5.3 Windows下跑Flume的差异命令、路径和换行符如果你在Windows环境做这个实验有几个坑要提前避第一启动脚本是flume-ng.cmd不是flume-ng。在cmd或者PowerShell里执行时要进入bin目录指定脚本路径bin\flume-ng.cmd agent --conf conf --name a1 --conf-file conf\flume-netcat.conf -Dflume.root.loggerINFO,console第二路径分隔符是反斜杠--conf-file参数里的路径要注意写法。第三Windows的cmd对参数里的等号和逗号处理有时比较奇怪如果遇到命令无法解析可以试试给-D参数加上双引号。第四nc命令不是Windows自带工具不建议为了做个实验特意去装直接用4.2里的Python脚本方式更省事。5.4 这个实例跑通之后下一步往哪里扩展监控端口实例是Flume快速入门的起点它的意义不只是让你看到一个Event长什么样而是让你建立一套配置思维任何Flume数据流的本质都是把某个source接到某个sink上中间用channel解耦。基于这个理解后续扩展就顺理成章了想采集日志文件时把source换成spooldir或tail监控一个目录文件新增内容自动进入Flume。想把数据写进HDFS时把sink换成hdfs类型并填好路径和文件滚动参数。想兼顾实时和可靠性时研究一下Kafka channel或者把sink换成Kafka producer。数据量大了memory channel可能丢数据换成kafka channel或file channel同时调整capacity和transactionCapacity。每次改动都只需要动配置文件里的组件类型和对应参数整体框架不变。这也是Flume最友好的地方你掌握了一套配置逻辑之后新组件基本就是查参数、填参数的事。最后再分享一个我个人的小习惯做Flume实验时我会单独开一个终端窗口专门看agent日志另一个窗口用来发测试数据。agent启动命令里如果没有把日志打到控制台我会先打开conf/log4j.properties看一眼日志文件路径这样每次测试的数据有没有进来一眼就能确认出错也能第一时间定位是在source、channel还是sink环节。监控端口实例跑通之后我建议你在日志文件里看到的每一行Event都动手解析一下十六进制哪怕只有一次你对Flume数据流的体感都会完全不同。