flink实战--自定义source

版权声明:原创文章 欢迎参考 请勿抄袭 https://blog.csdn.net/aA518189/article/details/88726467

Data Source简介

             数据的来源是flink程序从中读取输入的地方。我们可以使用StreamExecutionEnvironment.addSource(sourceFunction)将源添加到程序中。flink附带大量预先实现好的各种读取数据源的函数,其余的需求需要我们通过为非并行源去实SourceFunction接口或者为并行源实现ParallelSourceFunction接口或扩展RichParallelSourceFunction来编写满足自己业务需要的定制源。

flink已经实现的数据源

 基于文件

readTextFile(path): 读取文本文件,该文件要符合TextInputFormat规范,逐行读取并作为字符串返回。
readFile(fileInputFormat,path): 根据指定的文件输入格式指定读取文件。
readFile(fileInputFormat,path,watchType,interval,pathFilter,typeInfo): 这是前两个方法在内部调用的方法。它根据给定的fileInputFormat读取路径中的文件。根据提供的watchType,该源可能会定期监视(每间隔ms)该路径下来到的新数据(FileProcessingMode.PROCESS_CONTINUOUSLY),或者处理当前路径中的数据后并退出(FileProcessingMode.PROCESS_ONCE)。使用pathFilter,用户可以进一步排除文件的处理。

基于套接字

socketTextStream : 从套接字读取。元素可以用分隔符分隔。

基于集合

fromCollection(Collection) : 从Java Java.util.Collection创建一个数据流。集合中的所有元素必须是相同的类型。
fromCollection(Iterator,Class) :从迭代器创建数据流。该类要指定迭代器返回的元素的数据类型。
fromElements(T ...) :根据给定的对象序列创建数据流。所有对象必须是相同的类型。
fromParallelCollection(SplittableIterator,Class) : 并行地从迭代器创建数据流。该类指定迭代器返回的元素的数据类型。
generateSequence(from,to) : 在给定的区间内并行生成数字序列 。

自定义Source

             自定source需要我们自己编写一个source类继承RichFunction<T>抽象类,其中泛型T的类型是source产生流的类型。

编写好source后,直接在env.addSource(自定义source类)中使用。继承RichFunction<T>需要我们实现这几个抽象方法。

public void open(Configuration parameters) 
public void run(SourceContext<T> ctx) 
public void close() 
public void cancel() 

open方法:使用自定义source时,open方法第一个执行,用于配置数据源配置信息

run方法:用于获取数据源中的数据,SourceContext<T>,其中T是你要从数据源获取数据的数据类型。

close方法:关闭各个连接

cancel方法:取消一个 source,调用此方法后,source将跳出该循环。也即将 run 中的循环 emit 元素的行为终止。

run方法和cancel方法的使用方式:就是添加一个标记   isRunning

案例

以自定义source  读取redis为例

public class RedisSource {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<String> source = env.addSource(new MyRedisSource());
        source.print();
        env.execute("redis  source");
    }
   //自定义source
    public static class MyRedisSource extends RichSourceFunction<String> {
        //获取连接池的配置对象
        private  JedisPoolConfig config =null;
        //获取连接池
        JedisPool jedisPool =null;
        //获取核心对象
        Jedis jedis = null;
        //Redis服务器IP
        private static String ADDR = "127.0.0.1";
        //Redis的端口号
        private static int PORT = 6379;
        //访问密码
        private static String AUTH = "518189aA";
        //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
        private static int TIMEOUT = 10000;
        @Override
        public void open(Configuration parameters) throws Exception {
            super.open(parameters);
            config = new JedisPoolConfig();
            jedisPool =new JedisPool(config,ADDR, PORT,TIMEOUT,AUTH);
            jedis = jedisPool.getResource();
        }
         /**
         * 启动一个 source,即对接一个外部数据源然后 emit 元素形成 stream
         * (大部分情况下会通过在该方法里运行一个 while 循环的形式来产生 stream)。
         * @param ctx
         * @throws Exception
         */
        @Override
        public void run(SourceContext<String> ctx) throws Exception {
            String pv = jedis.hget("PVData","pv");
            ctx.collect(pv);
        }
        /**
         * 取消源,大多数源文件都有一个while循环
         * {@link #run(SourceContext)}方法。实现需要确保
         * 调用此方法后,source将跳出该循环。
         */
        @Override
        public void cancel() {
        }
        /**
         * 它是在最后一次调用主工作方法之后调用的, 此方法可用于清理工作
         */
        @Override
        public void close() throws Exception {
            super.close();
            jedisPool.close();
            jedis.close();

        }
}

redis中的数据:

运行结果:

扫一扫加入大数据技术交流群,了解更多大数据技术,还有免费资料等你哦

扫一扫加入大数据技术交流群,了解更多大数据技术,还有免费资料等你哦

扫一扫加入大数据技术交流群,了解更多大数据技术,还有免费资料等你哦

猜你喜欢

转载自blog.csdn.net/aA518189/article/details/88726467