簡體   English   中英

將已處理文件從一個文件夾移動到 flink 中的另一個文件夾

[英]Move already process file from one folder to another folder in flink

我是 flink 的新手,在解決以下用例時面臨一些挑戰

用例說明:

我將在某個文件夾中每天收到一個帶有時間戳的 csv 文件,例如輸入。 文件格式為 file_name_dd-mm-yy-hh-mm-ss.csv。

現在我的 flink 管道將逐行讀取這個 csv 文件,並將其寫入我的 Kafka 主題。

讀取此文件的數據完成后,需要立即將其移動到另一個文件夾歷史文件夾。

為什么我需要這個是因為:假設您的 ververica 服務器突然或手動停止,並且如果您將所有已處理的文件都放在同一位置,那么在 ververica 重新啟動后,flink 將重新讀取它之前處理過的所有文件。 因此,為了防止這種情況,這些文件需要立即將已讀取的文件移動到另一個位置。

我用谷歌搜索了很多,但沒有找到任何東西,所以你能指導我實現這一目標。

讓我知道是否需要其他任何東西。

開箱即用的 Flink 提供了監視新文件的目錄並讀取它們的工具 - 通過StreamExecutionEnvironment.getExecutionEnvironment.readFile (參見類似的堆棧溢出線程示例 - How to read new added file in a directory in Flink / Monitoring directory for new files使用 Flink 進行數據流等)

查看readFile函數的源代碼,它調用createFileInput() 方法,該方法簡單地實例化ContinuousFileMonitoringFunctionContinuousFileReaderOperatorFactory並配置源 -

addSource(monitoringFunction, sourceName, null, boundedness)
                        .transform("Split Reader: " + sourceName, typeInfo, factory);

ContinuousFileMonitoringFunction實際上是大部分邏輯發生的地方。

因此,如果我要實現您的要求,我將使用自己的邏輯擴展ContinuousFileMonitoringFunction的功能,將處理后的文件移動到歷史文件夾並從該函數構造源代碼。

鑒於run方法在checkpointLock內執行讀取和轉發 -

synchronized (checkpointLock) {
    monitorDirAndForwardSplits(fileSystem, context);
}

我想說移動到檢查點完成文件上的歷史文件夾是安全的,這些文件的修改日早於globalModificationTime ,它在拆分收集時在monitorDirAndForwardSplits中更新。

也就是說,我將擴展ContinuousFileMonitoringFunction類並實現CheckpointListener接口,並在notifyCheckpointComplete中將已處理的文件移動到歷史文件夾:

public class ArchivingContinuousFileMonitoringFunction<OUT> extends ContinuousFileMonitoringFunction<OUT> implements CheckpointListener {
  ...

   @Override
   public void notifyCheckpointComplete(long checkpointId) throws Exception {
          Map<Path, FileStatus> eligibleFiles = listEligibleForArchiveFiles(fs, new Path(path));
        // do move logic
     }

   /**
     * Returns the paths of the files already processed.
     *
     * @param fileSystem The filesystem where the monitored directory resides.
     */
    private Map<Path, FileStatus> listEligibleForArchiveFiles(FileSystem fileSystem, Path path) {

        final FileStatus[] statuses;
        try {
            statuses = fileSystem.listStatus(path);
        } catch (IOException e) {
            // we may run into an IOException if files are moved while listing their status
            // delay the check for eligible files in this case
            return Collections.emptyMap();
        }

        if (statuses == null) {
            LOG.warn("Path does not exist: {}", path);
            return Collections.emptyMap();
        } else {
            Map<Path, FileStatus> files = new HashMap<>();
            // handle the new files
            for (FileStatus status : statuses) {
                if (!status.isDir()) {
                    Path filePath = status.getPath();
                    long modificationTime = status.getModificationTime();
                    if (shouldIgnore(filePath, modificationTime)) {
                        files.put(filePath, status);
                    }
                } else if (format.getNestedFileEnumeration() && format.acceptFile(status)) {
                    files.putAll(listEligibleForArchiveFiles(fileSystem, status.getPath()));
                }
            }
            return files;
        }
    }
}

然后使用自定義函數手動定義數據流:

ContinuousFileMonitoringFunction<OUT> monitoringFunction =
                new ArchivingContinuousFileMonitoringFunction <>(
                        inputFormat, monitoringMode, getParallelism(), interval);

ContinuousFileReaderOperatorFactory<OUT, TimestampedFileInputSplit> factory = new ContinuousFileReaderOperatorFactory<>(inputFormat);

final Boundedness boundedness = Boundedness.CONTINUOUS_UNBOUNDED;

env.addSource(monitoringFunction, sourceName, null, boundedness)
                        .transform("Split Reader: " + sourceName, typeInfo, factory);

Flink 本身並沒有為此提供解決方案。 您可能需要自己構建一些東西,或者找到一個可以配置為處理此問題的工作流工具。

你可以在 flink 用戶郵件列表上詢問這個問題。 我知道其他人已經編寫了腳本來執行此操作; 也許有人可以分享一個解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM