自定义flume-ftp-sink

160 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情

flume-ftp-sink

背景

因为项目需要,需要写一个flume-ftp-sink,而flume官方不支持ftp sink所以,我要先研究一下原来架构使用的flume-hdfs-sink,在自定义的写一个flume-ftp-sink。具体请看

自定义flumesink

flume-ftp-sink

源码

核心代码:

@Override
    public synchronized void start() {
        sinkCounter.start();
        connectServer();
        super.start();
        if (rollInterval > 0) {

            rollService = Executors.newScheduledThreadPool(
                    1,
                    new ThreadFactoryBuilder().setNameFormat(
                            "rollingFileSink-roller-" +
                                    Thread.currentThread().getId() + "-%d").build());

            /*
             * Every N seconds, mark that it's time to rotate. We purposefully do NOT
             * touch anything other than the indicator flag to avoid error handling
             * issues (e.g. IO exceptions occuring in two different threads.
             * Resist the urge to actually perform rotation in a separate thread!
             */
            rollService.scheduleAtFixedRate(new Runnable() {

                @Override
                public void run() {
                    logger.debug("Marking time to rotate file {}",
                            pathController.getCurrentFile());
                    shouldRotate = true;
                }

            }, rollInterval, rollInterval, TimeUnit.SECONDS);
        } else {
            logger.info("RollInterval is not valid, file rolling will not happen.");
        }
        logger.info("RollingFileSink {} started.", getName());
    }

    @Override
    public synchronized void stop() {
        disConnectServer();
        sinkCounter.stop();
        super.stop();
        if (rollInterval > 0) {
            rollService.shutdown();

            while (!rollService.isTerminated()) {
                try {
                    rollService.awaitTermination(1, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    logger.debug("Interrupted while waiting for roll service to stop. " +
                            "Please report this.", e);
                }
            }
        }
        logger.info("RollingFile sink {} stopped. Event metrics: {}",
                getName(), sinkCounter);
    }

    @Override
    public Status process() throws EventDeliveryException {
        Status status = Status.READY;
        Channel channel = getChannel();
        Transaction transaction = channel.getTransaction();
        try {
            transaction.begin();
            verifyConnection();

            List<Event> batch = new ArrayList<>();

            for (int i = 0; i < batchSize; i++) {
                Event event = channel.take();
                if (event == null) {
                    break;
                }
                realDirPath = BucketPath.escapeString(ftpDirPath, event.getHeaders(),
                        timeZone, needRounding, roundUnit, roundValue, useLocalTime);
                realprefix = BucketPath.escapeString(prefix, event.getHeaders(),
                        timeZone, needRounding, roundUnit, roundValue, useLocalTime);
                batch.add(event);
            }

            if (batch.size() == 0) {
                sinkCounter.incrementBatchEmptyCount();
                status = Status.BACKOFF;
            } else {
                if (batch.size() < batchSize) {
                    sinkCounter.incrementBatchUnderflowCount();
                } else {
                    sinkCounter.incrementBatchCompleteCount();
                }
                sinkCounter.addToEventDrainAttemptCount(batch.size());
                dealEventList(batch);
            }

            sinkCounter.addToEventDrainSuccessCount(batch.size());
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            sinkCounter.incrementEventWriteOrChannelFail(ex);
            transaction.rollback();
            throw new EventDeliveryException("Failed to send events", ex);
        } finally {
            transaction.commit();
            transaction.close();
        }

        return status;
    }

配置参数

Property NameDefaultDescription
type-need to be com.jzy.flume.FlumeFtpSink
host-host
port21port
user-user
password-password
ftpDirPath/ftp upload dir
prefixDATA-file prefix
suffix.datfile prefix
tempSuffix.tmptemp suffix when uploading
batchSize1000max records of a file
rollInterval30Number of seconds to wait before rolling current file (0 = never roll based on time interval)