Flume自定义Sink实现将数据写入到MySQL表中

目录

需求说明

代码开发步骤

第一步:创建mysql数据库表

第二步:定义mysqlSink类

第三步:代码打包上传

第四步:开发flume的配置文件

第五步:启动flume

第六步:创建文件验证数据进入mysql


需求说明

  • 官方提供的sink类型已经很多,但是有时候并不能满足实际开发当中的需求,此时我们就需要根据实际需求自定义某些sink。如:需要把接受到的数据按照规则进行过滤之后写入到某张mysql表中,所以此时需要我们自己实现MySQLSink。

  • 官方也提供了自定义sink的接口:

  • 官网说明:https://flume.apache.org/FlumeDeveloperGuide.html#sink

代码开发步骤

根据官方说明自定义MysqlSink需要继承AbstractSink类并实现Configurable

实现对应的方法:

  1. configure(Context context)

    初始化context

  2. start()

    启动准备操作

  3. process()

    从channel获取数据,然后解析之后,保存在mysql表中

  4. stop()

    关闭相关资源

第一步:创建mysql数据库表

-- 创建一个数据库
CREATE DATABASE IF NOT EXISTS mysqlsource DEFAULT CHARACTER SET utf8 ;

USE mysqlsource;

-- 创建一个表,用户保存拉取目标表位置的信息
CREATE TABLE mysqlsource.flume2mysql (
  id INT(11) NOT NULL AUTO_INCREMENT,
  createTime VARCHAR(64) NOT NULL,
  content VARCHAR(255) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

第二步:定义mysqlSink类

 

import org.apache.flume.conf.Configurable;
import org.apache.flume.*;
import org.apache.flume.sink.AbstractSink;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 自定义MysqlSink
 */
public class MysqlSink extends AbstractSink implements Configurable {
    private String mysqlurl = "";
    private String username = "";
    private String password = "";
    private String tableName = "";

    Connection con = null;

    @Override
    public Status process(){
        Status status = null;
        // Start transaction 获得Channel对象
        Channel ch = getChannel();
        Transaction txn = ch.getTransaction();
        txn.begin();
        try
        {
            Event event = ch.take();

            if (event != null)
            {
                //获取body中的数据
                String body = new String(event.getBody(), "UTF-8");

                //如果日志中有以下关键字的不需要保存,过滤掉
                if(body.contains("delete") || body.contains("drop") || body.contains("alert")){
                    status = Status.BACKOFF;
                }else {

                    //存入Mysql
                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String createtime = df.format(new Date());

                    PreparedStatement stmt = con.prepareStatement("insert into " + tableName + " (createtime, content) values (?, ?)");
                    stmt.setString(1, createtime);
                    stmt.setString(2, body);
                    stmt.execute();
                    stmt.close();
                    status = Status.READY;
                }
            }else {
                status = Status.BACKOFF;
            }

            txn.commit();
        } catch (Throwable t){
            txn.rollback();
            t.getCause().printStackTrace();
            status = Status.BACKOFF;
        } finally{
            txn.close();
        }

        return status;
    }
    /**
     * 获取配置文件中指定的参数
     * @param context
     */
    @Override
    public void configure(Context context) {
        mysqlurl = context.getString("mysqlurl");
        username = context.getString("username");
        password = context.getString("password");
        tableName = context.getString("tablename");
    }

    @Override
    public synchronized void start() {
        try{
            //初始化数据库连接
            con = DriverManager.getConnection(mysqlurl, username, password);
            super.start();
            System.out.println("finish start");
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    @Override
    public synchronized void stop(){
        try{
            con.close();
        }catch(SQLException e) {
            e.printStackTrace();
        }
        super.stop();
    }

}

第三步:代码打包上传

  • 将我们的代码打成jar包上传到flume的lib目录下

第四步:开发flume的配置文件

cd /xsluo/install/apache-flume-1.6.0-cdh5.14.2-bin/conf
vim mysqlsink.conf
  • 内容如下

  • 根据自己的实际情况修改sink

a1.sources = r1
a1.sinks = k1
a1.channels = c1

#配置source
a1.sources.r1.type = exec
a1.sources.r1.command = tail -F /xsluo/install/flumeData/data.log
a1.sources.r1.channels = c1

#配置channel
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

#配置sink
a1.sinks.k1.channel = c1
a1.sinks.k1.type = com.xsluo.sink.MysqlSink
a1.sinks.k1.mysqlurl=jdbc:mysql://node03:3306/mysqlsource?useSSL=false
a1.sinks.k1.username=root
a1.sinks.k1.password=123456
a1.sinks.k1.tablename=flume2mysql

第五步:启动flume

cd /xsluo/install/apache-flume-1.6.0-cdh5.14.2-bin
bin/flume-ng agent -n a1 -c conf -f conf/mysqlsink.conf -Dflume.root.logger=info,console

第六步:创建文件验证数据进入mysql

  • 创建文件,验证数据进入mysql数据库

mkdir -p /xsluo/install/flumeData
echo "helloworld" >> /xsluo/install/flumeData/data.log

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将CSV文件写入MySQL,可以使用Flume自定义Sink。以下是一些基本步骤: 1. 创建一个自定义Sink类,继承AbstractSink类。 2. 在该类中实现process方法,在该方法中编写将CSV文件数据写入MySQL的逻辑。 3. 在Flume配置文件中指定自定义Sink类,并设置相关参数,例如CSV文件路径、MySQL连接信息等。 下面是一个简单的示例: ```java public class CsvToMysqlSink extends AbstractSink { private String csvPath; private String mysqlUrl; private String mysqlUsername; private String mysqlPassword; private String mysqlTable; private Connection connection; private PreparedStatement statement; @Override public void configure(Context context) { csvPath = context.getString("csvPath"); mysqlUrl = context.getString("mysqlUrl"); mysqlUsername = context.getString("mysqlUsername"); mysqlPassword = context.getString("mysqlPassword"); mysqlTable = context.getString("mysqlTable"); } @Override public void start() { try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection(mysqlUrl, mysqlUsername, mysqlPassword); statement = connection.prepareStatement("INSERT INTO " + mysqlTable + " VALUES (?, ?, ?)"); } catch (Exception e) { e.printStackTrace(); } } @Override public void stop() { try { statement.close(); connection.close(); } catch (Exception e) { e.printStackTrace(); } } @Override public Status process() throws EventDeliveryException { Status status = null; try { File csvFile = new File(csvPath); BufferedReader br = new BufferedReader(new FileReader(csvFile)); String line; while ((line = br.readLine()) != null) { String[] values = line.split(","); statement.setString(1, values[0]); statement.setString(2, values[1]); statement.setString(3, values[2]); statement.executeUpdate(); } br.close(); status = Status.READY; } catch (Exception e) { e.printStackTrace(); status = Status.BACKOFF; } return status; } } ``` 在Flume配置文件中,可以这样指定自定义Sink类: ```properties agent.sinks.mysqlSink.type = com.example.CsvToMysqlSink agent.sinks.mysqlSink.csvPath = /path/to/csv/file.csv agent.sinks.mysqlSink.mysqlUrl = jdbc:mysql://localhost:3306/mydatabase agent.sinks.mysqlSink.mysqlUsername = myusername agent.sinks.mysqlSink.mysqlPassword = mypassword agent.sinks.mysqlSink.mysqlTable = mytable ``` 这个示例假设CSV文件每行有三个值,分别对应MySQL表中的三个字段。在process方法中,将读取CSV文件中的每一行,并将其分割为三个值,然后使用PreparedStatement将这些值插入到MySQL表中。 注意,这个示例没有包含一些必要的异常处理和错误处理逻辑,需要根据实际情况进行完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值