### 使用apache flume 进行ftp文件采集汇总

### 基础知识
#####flume的优势：<br>
 可以高速采集数据，采集的数据能够以想要的文件格式及压缩方式存储在hdfs上<br>
 事务功能保证了数据在采集的过程中数据不丢失<br>
 部分Source保证了Flume挂了以后重启依旧能够继续在上一次采集点采集数据，真正做到数据零丢失<br>

 #####flume的组成
 flume有3大组件<br>
 source(源端数据采集)：Flume提供了各种各样的Source、同时还提供了自定义的Source<br>
 Channel(临时存储聚合数据)：主要用的是memory channel和File channel（生产最常用），生产中channel的数据一定是要监控的，防止sink挂了，撑爆channel<br>
 Sink（移动数据到目标端）：如HDFS、KAFKA、DB以及自定义的sink<br>


 flume-ng agent -c D:\software\apache-flume-1.8.0-bin\conf -f D:\software\apache-flume-1.8.0-bin\conf\flume-ftp-source-dir.conf -n agent


 flume-ng agent -c D:\software\apache-flume-1.8.0-bin\conf -f D:\software\apache-flume-1.8.0-bin\conf\flume-ftp-result.conf -n agent


 telnet localhost 44444

 flume-ng agent -c conf -f conf/flume-ng-ftp-source-FTP.conf --name agent -Dflume.root.logger=INFO,console

 #####flume实战案例一：从ftp环境读取json文件，数据存入mysql
 参考链接：https://blog.csdn.net/qq_40015759/article/details/82429117<br>
 前提条件：jdk1.8<br>
 flume1.9的安装包<br>
 mysql数据库<br>
 ftp环境<br>

 步骤：<br>
 一：解压flume1.9的压缩包，配置环境变量（linux环境需要做）<br>
 二：添加flume读取ftp环境中文件的三方包（https://github.com/keedio/flume-ftp-source）<br>
 flume本身并没有类型去读取ftp文件的功能，需要引入三方包去实现<br>
 三：commons-net-3.3.jar,jsch-0.1.54.jar ,mysql-connector-java-6.0.5.jar,<br>
 flume-ftp-source-2.2.0.jar(步骤二打成的jar包)共四个jar包加入之前解压的flume中的lib 中<br>
 四：在flume的conf中新增配置文件ftp.conf<br>
 具体配置如下<br>
 # flume监控ftp文件功能的配置如下
 agent.sources = ftp1<br>
 agent.sinks = k1<br>
 agent.channels = ch1<br>

 agent.sources.ftp1.type = org.keedio.flume.source.ftp.source.Source<br>
 agent.sources.ftp1.client.source = ftp<br>

 #ftp服务地址
 agent.sources.ftp1.name.server = 61.159.214.198<br>
 #端口
 agent.sources.ftp1.port = 50021<br>
 #ftp用户名
 agent.sources.ftp1.user = flume<br>
 #密码
 agent.sources.ftp1.password = sSt23dDmcikTNiw8<br>
 #文件所在目录 （相对于根目录）
 agent.sources.ftp1.working.directory = /<br>
 #文件的名称匹配 （java正则表达式）
 agent.sources.ftp1.filter.pattern = .+\.json<br>

 #ftp的根目录
 agent.sources.ftp1.folder = /flume<br>
 agent.sources.ftp1.run.discover.delay=5000<br>
 agent.sources.ftp1.flushlines = true<br>
 agent.sources.ftp1.search.recursive = true<br>
 agent.sources.ftp1.processInUse = false<br>
 agent.sources.ftp1.processInUseTimeout = 30<br>
 agent.sources.ftp1.channels = ch1<br>
 agent.sources.ftp1.inputCharset=utf8<br>

 agent.channels.ch1.type = memory<br>
 agent.channels.ch1.capacity = 100000000<br>
 agent.channels.ch1.transactionCapacity = 100000000<br>

 agent.sinks.k1.type = com.ihooyah.flume.sink.MySqlSink<br>
 agent.sinks.k1.url = jdbc:mysql://127.0.0.1:3306/flume?autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC&characterEncoding=UTF-8&useUnicode=true
 agent.sinks.k1.user= root<br>
 agent.sinks.k1.password= root<br>
 agent.sinks.k1.driver= com.mysql.cj.jdbc.Driver<br>
 agent.sinks.k1.databaseName = flume<br>
 agent.sinks.k1.tableName = flume_test<br>
 agent.sinks.k1.iscustom = false<br>
 agent.sinks.k1.channel = ch1<br>

 #####参数解释
 sources配置的数据来源<br>
 agent.sources.ftp1.type填的是三方jar中的方法去开启读取ftp文件 必填项<br>
 agent.sources.ftp1.folder填的是读取日志文件生成目录（记录那些文件已读取过 避免重复读取）<br>
 agent.sources.ftp1.flushlines true代表用行去读，false用代码块去读<br>
 agent.sources.ftp1.channels = ch1此配置必填不然无法去读取sink<br>

 sinks配置的数据接受项（此配置可以自己定义参数，后台通过context对象获取到）<br>
 agent.sinks.k1.type = com.ihooyah.flume.sink.MySqlSink 此配置填写项目中的执行类（该类继承 AbstractSink）<br>
 agent.sinks.k1.channel = ch1此配置必填  关联数据源<br>

 #####代码讲解
 处理数据逻辑参考com.ihooyah.flume.sink.MySqlSink这个类<br>
 event对象里面中body读取的是文件内容  headers读取的是文件名称<br>
 需要注意body的byte数组转换成string是需要指定编码格式  防止乱码<br>
 读取的文件也需要确定编码格式utf8否则会出现乱码<br>

 ####注意事项
 process方法中  必须要有事务的代码不然会报错<br>
 Transaction transaction = channel.getTransaction();<br>
 transaction.begin();<br>
 transaction.commit();<br>
 transaction.rollback();<br>
 transaction.close();<br>
 否则事务报错会回退<br>
 详情请见源代码<br>

 五：将本次项目打包放入lib目录下<br>
 共五个jar<br>
 进入D:\flume\apache-flume-1.9.0-bin\bin此目录  打开控制台<br>
 启动命令flume-ng agent --conf-file ../conf/ftp.conf --name agent -property flume.root.logger=INFO,console<br>

  #####flume实战案例二：从ftp环境读取文件存到本地服务器路径
  conf文件示例<br>
  # flume监控ftp文件功能的配置如下
  agent.sources = ftp1<br>
  agent.sinks = k1<br>
  agent.channels = ch1<br>
  agent.sources.ftp1.type = org.keedio.flume.source.ftp.source.Source<br>
  agent.sources.ftp1.client.source = ftp<br>

  #ftp服务地址
  agent.sources.ftp1.name.server = 61.159.214.198<br>
  #端口
  agent.sources.ftp1.port = 50021<br>
  #ftp用户名
  agent.sources.ftp1.user = flume<br>
  #密码
  agent.sources.ftp1.password = sSt23dDmcikTNiw8<br>
  #文件所在目录 （相对于根目录）
  agent.sources.ftp1.working.directory = /<br>
  #文件的名称匹配 （java正则表达式）
  agent.sources.ftp1.filter.pattern = .+<br>
  #ftp的根目录
  agent.sources.ftp1.folder = /flume<br>
  agent.sources.ftp1.run.discover.delay=5000<br>
  agent.sources.ftp1.flushlines = false<br>
  agent.sources.ftp1.search.recursive = true<br>
  agent.sources.ftp1.processInUse = false<br>
  agent.sources.ftp1.processInUseTimeout = 30<br>
  agent.sources.ftp1.channels = ch1<br>
  agent.sources.ftp1.chunk.size = 102400<br>

  agent.channels.ch1.type = memory<br>
  agent.channels.ch1.capacity = 100000000<br>
  agent.channels.ch1.transactionCapacity = 100000000<br>

  agent.sinks.k1.type = com.ihooyah.flume.sink.LocalUploadSink<br>
  agent.sinks.k1.uploadDir = D:\\<br>
  agent.sinks.k1.batchSize = 10000<br>
  agent.sinks.k1.channel = ch1<br><br>
 与实战一区别的配置<br>
 agent.sources.ftp1.flushlines = false   图片需要按照块去读不能按行读取否则会出现字节丢失导致图片损坏打不开<br>
 agent.sinks.k1.type = com.ihooyah.flume.sink.LocalUploadSink  重新写的一个sink<br>
 event读取文件的时候是多次读取的也就是说不能只读到一个event就去生成文件  这是不完整的<br>



 

 

  

 

