Flink Sql读取hdfs目录时, 损坏的文件支持跳过

背景

使用flink sql读取某个目录的文件, 目录下存在某个文件副本丢失或block丢失, 但是任务无法正常运行, 直接异常退出了. 想在代码层面进行控制, 损坏的文件进行读取失败时不抛出异常, flink sql的封装太多, 无法对某个过程做筛选操作, 根据官网的提示, 可以通过创建META-INF/services/org.apache.flink.core.fs.FileSystemFactory文件, 来替换掉原来的FileSystemFactory, 做一些自定义的操作

副本丢失

pom

    
        
            org.apache.flink
            flink-table-planner-blink_2.12
            1.13.1
        
        
            org.apache.flink
            flink-clients_2.12
            1.13.1
        
    

测试示例

测试中的示例为副本丢失的文件, 可在hdfs的web界面查看

public class ReadHdfsSqlTest {
    public static void main(String[] args) {
        String table = "tmp_table";
        String schema = "message STRING";
        //可以是目录,也可以是文件
        String path = "hdfs://192.168.0.1:8020/user/flink/ha/application_1632893476013_0162/completedCheckpoint24e63d0c5530";
        String createSql = String.format("CREATE TABLE %s( %s ) WITH ('connector'='filesystem','path'='%s','format'='raw')",
                table, schema, path);
        TableEnvironment env = TableEnvironment.create(EnvironmentSettings.newInstance().inBatchMode().build());
        env.executeSql(createSql).print();
        env.executeSql("select * from " + table + " limit 10").print();
    }
}
副本丢失

如果不进行改造, 程序会异常退出, 无法进行后续文件的读取处理


block丢失

自定义FileSystemFactory

通过源码跟踪, 需要把原有的三个hadoop类复制过来进行简单改造, 随后在META-INF下创建下图的文件

代码结构

org.apache.flink.runtime.fs.hdfs.HadoopDataInputStream

两个read()方法进行异常捕获, 报错期间会有多个WARN的打印(无影响), 最后才会抛出异常进入到catch代码块


org.apache.flink.runtime.fs.hdfs.HadoopFileSystem

更改两个open()方法的返回值


org.apache.flink.runtime.fs.hdfs.HadoopFsFactory

更改getSchema()的返回值为hdfs

    @Override
    public String getScheme() {
        // the hadoop factory creates various schemes
        return "hdfs";
    }

create()方法中创建自定义的HadoopFileSystem


你可能感兴趣的:(Flink Sql读取hdfs目录时, 损坏的文件支持跳过)