You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-zh@flink.apache.org by 曾耀武 <51...@qq.com> on 2019/10/13 04:55:20 UTC

flink 1.6.1 RichAsyncFunction 异步请求外部系统导致下游数据大量重复

大家好,


请教大家一个问题, 我在使用flink 1.6 版本去用异步的方式
访问外部系统的时候发现下游的数据,本来应该只有一条的,结果被重复几十条。


我的异步Function 片段如下。


private static class SimpleAsyncFunction extends RichAsyncFunction<String, String> {
    private static final long serialVersionUID = 2098635244857937717L;

    private transient ExecutorService executorService;
    private  transient Client client ;

    private final long shutdownWaitTS=1000;

    @Override
    public void open(Configuration parameters) throws Exception {
        super.open(parameters);

        executorService = new ThreadPoolExecutor(10,30,60,TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000),
                new ThreadPoolExecutor.CallerRunsPolicy());
         client= new Client();
    }

    @Override
    public void close() throws Exception {
        super.close();
        ExecutorUtils.gracefulShutdown(shutdownWaitTS, TimeUnit.MILLISECONDS, executorService);
    }

    @Override
    public void asyncInvoke(final String jsonStr, final ResultFuture<String> resultFuture) {
          result = client.predict(jsonStr);          resultFuture.complete(Collections.singletonList(result));}}
------------------------------
dag构建部分为:
AsyncFunction<String, String> nlpMoaAsyncFunction = new SimpleAsyncFunction();

DataStream<String> source = env.addSource(flinkKafkaConsumer010);

DataStream<String> nlpResult = AsyncDataStream.unorderedWait(
        source,
        nlpMoaAsyncFunction,
        timeout,
        TimeUnit.MILLISECONDS,
        30);

FlinkKafkaProducer010<String> kafkaProducer = new FlinkKafkaProducer010<String>(
        ImmutableConstant.NLP_RESULT_KAFKA_TOPIC,
        new SimpleStringSchema(),
        producerProp
);

nlpResult.addSink(kafkaProducer);

-------------------------整个逻辑其实很简单,程序运行在yarn 上10个taskmanager ,每个tm 一个slot。 有没有哪个碰到类似的问题,还是是bug 或者是我的实现有问题?

回复: flink 1.6.1 RichAsyncFunction 异步请求外部系统导致下游数据大量重复

Posted by 曾耀武 <51...@qq.com>.
额, sorry
忽略测试数据这个是线上 ,异常用户检测的,这样才会命中模型。


图片是这个代码:


封装的task:
private static class MoaTask implements Callable<String> {

    private String jsonStr;
    private JudgeClient client;

    public MoaTask(String json, JudgeClient client) {
        this.jsonStr = json;
        this.client= client;
        System.out.println("===create new task :" + json);
    }
    @Override
    public String call() throws Exception {

        JSONObject jsonObject = JSON.parseObject(jsonStr);
        String business = jsonObject.getString("business");
        System.out.println("====processing asr data: " + jsonStr);
        String result = this.client.predict(jsonObject,"test");
        return result;
    }
}异步函数:private static class SimpleAsyncFunction extends RichAsyncFunction<String, String> {
    private static final long serialVersionUID = 2098635244857937717L;
    private transient ExecutorService executorService;
    private  transient JudgeClient moaJudgeClient ;
    private final long shutdownWaitTS=1000;
    @Override
    public void open(Configuration parameters) throws Exception {
        super.open(parameters);
        executorService = new ThreadPoolExecutor(10,30,60, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000),
                new ThreadPoolExecutor.CallerRunsPolicy());
        moaJudgeClient = new JudgeClient();
    }
    @Override
    public void close() throws Exception {
        super.close();
        ExecutorUtils.gracefulShutdown(shutdownWaitTS, TimeUnit.MILLISECONDS, executorService);
    }
    @Override
    public void asyncInvoke(final String jsonStr, final ResultFuture<String> resultFuture) {
        Future<String> future = executorService.submit(new MoaTask(jsonStr,moaJudgeClient));
        CompletableFuture.supplyAsync(new Supplier<String>() {
            @Override
            public String get() {
                try{
                    return future.get();

                }catch (Exception e){
                    return null;
                }
            }
        }).thenAccept((result)->{
            resultFuture.complete(Collections.singleton(result));
        });
    }
}图构建:AsyncFunction<String, String> nlpMoaAsyncFunction = new SimpleAsyncFunction();
DataStream<String> source = env.addSource(flinkKafkaConsumer010);
DataStream<String> nlpResult = AsyncDataStream.unorderedWait(
        source,
        nlpMoaAsyncFunction,
        timeout,
        TimeUnit.MILLISECONDS,
        30).setParallelism(2);
FlinkKafkaProducer010<String> kafkaProducer = new FlinkKafkaProducer010<String>(
        Constant.topic2,
        new SimpleStringSchema(),
        producerProp
);
nlpResult.addSink(kafkaProducer);


整体就是比较简单。






------------------ 原始邮件 ------------------
发件人: "Kurt Young"<yk...@gmail.com>;
发送时间: 2019年10月14日(星期一) 晚上6:14
收件人: "user-zh"<us...@flink.apache.org>;

主题: Re: flink 1.6.1 RichAsyncFunction 异步请求外部系统导致下游数据大量重复



这位朋友你的测试数据文明一点呀。。
ps:图片看不到

Best,
Kurt


On Mon, Oct 14, 2019 at 12:11 PM 曾耀武 <51...@qq.com> wrote:

>
> 作业是没有failover 。执行是正常的。但是官方文档上不是说那个是保证exactly-once么?
> 我稍微改了一下代码,还是有同样的重复问题,好像在new task 的时候被重复new 了多次。这个不知道是为何,
> 而且是在同一个slot里面。
>
> 异步函数:
> 然后我在执行的时候,往kafka 打了一条数据,在yarn 上起了两个  TM,每个TM 一个slot
>
> 然后在一个TM 上打印了这个日志: 我的日志是有编号的[0]  这个,一条输入是一个需要外部检测的json。
>
> ===create new task :{"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"}
> ====processing asr data: {"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"}
> === the moa resonse is: {result={s_id=userid, hit_details=操你, words=操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47, status=1, hit_logic=basePoliticsWords}, em=OK, ec=0}
> ===create new task :{"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"}
> ====processing asr data: {"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"}
> === the moa resonse is: {result={s_id=userid, hit_details=操你, words=操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47, status=1, hit_logic=basePoliticsWords}, em=OK, ec=0}
>
>
>
> 有时候这些记录在flink 里经过处理之后, 日志打印了两边,好像是处理了两遍,但是 写到下游的kafka 可能只有1个。
> 理论期望值是一条输入对应一条输出。
>
> 但是在一百万的测试数据上,上游发送肯定是只发送了100万条,带编号递增的。 但是下游去重之后是100万,不去重就有一百多万,可能
> 会多好几万的样子。比较奇怪。
>
>
>
>
>
> ------------------ 原始邮件 ------------------
> *发件人:* "Jark Wu"<im...@gmail.com>;
> *发送时间:* 2019年10月14日(星期一) 中午11:23
> *收件人:* "user-zh"<us...@flink.apache.org>;
> *主题:* Re: flink 1.6.1 RichAsyncFunction 异步请求外部系统导致下游数据大量重复
>
> Hi,
>
> 从代码上看,并没有发现什么问题,给一些排查建议:
> 1)作业在这期间有 failover 过吗?Flink 写入 Kafka 目前默认不是端到端exactly once的。
> 2) “重复几十条”是怎么判断出来的呢? 会不会 kafka 源中的数据有重复呢?
>
> Best,
> Jark
>
> On Sun, 13 Oct 2019 at 12:55, 曾耀武 <51...@qq.com> wrote:
>
> > 大家好,
> >
> >
> > 请教大家一个问题, 我在使用flink 1.6 版本去用异步的方式
> > 访问外部系统的时候发现下游的数据,本来应该只有一条的,结果被重复几十条。
> >
> >
> > 我的异步Function 片段如下。
> >
> >
> > private static class SimpleAsyncFunction extends
> RichAsyncFunction<String,
> > String> {
> >     private static final long serialVersionUID = 2098635244857937717L;
> >
> >     private transient ExecutorService executorService;
> >     private  transient Client client ;
> >
> >     private final long shutdownWaitTS=1000;
> >
> >     @Override
> >     public void open(Configuration parameters) throws Exception {
> >         super.open(parameters);
> >
> >         executorService = new
> ThreadPoolExecutor(10,30,60,TimeUnit.SECONDS,
> >                 new LinkedBlockingQueue<>(1000),
> >                 new ThreadPoolExecutor.CallerRunsPolicy());
> >          client= new Client();
> >     }
> >
> >     @Override
> >     public void close() throws Exception {
> >         super.close();
> >         ExecutorUtils.gracefulShutdown(shutdownWaitTS,
> > TimeUnit.MILLISECONDS, executorService);
> >     }
> >
> >     @Override
> >     public void asyncInvoke(final String jsonStr, final
> > ResultFuture<String> resultFuture) {
> >           result = client.predict(jsonStr);
> > resultFuture.complete(Collections.singletonList(result));}}
> > ------------------------------
> > dag构建部分为:
> > AsyncFunction<String, String> nlpMoaAsyncFunction = new
> > SimpleAsyncFunction();
> >
> > DataStream<String> source = env.addSource(flinkKafkaConsumer010);
> >
> > DataStream<String> nlpResult = AsyncDataStream.unorderedWait(
> >         source,
> >         nlpMoaAsyncFunction,
> >         timeout,
> >         TimeUnit.MILLISECONDS,
> >         30);
> >
> > FlinkKafkaProducer010<String> kafkaProducer = new
> > FlinkKafkaProducer010<String>(
> >         ImmutableConstant.NLP_RESULT_KAFKA_TOPIC,
> >         new SimpleStringSchema(),
> >         producerProp
> > );
> >
> > nlpResult.addSink(kafkaProducer);
> >
> > -------------------------整个逻辑其实很简单,程序运行在yarn 上10个taskmanager ,每个tm
> 一个slot。
> > 有没有哪个碰到类似的问题,还是是bug 或者是我的实现有问题?
>

Re: flink 1.6.1 RichAsyncFunction 异步请求外部系统导致下游数据大量重复

Posted by Kurt Young <yk...@gmail.com>.
这位朋友你的测试数据文明一点呀。。
ps:图片看不到

Best,
Kurt


On Mon, Oct 14, 2019 at 12:11 PM 曾耀武 <51...@qq.com> wrote:

>
> 作业是没有failover 。执行是正常的。但是官方文档上不是说那个是保证exactly-once么?
> 我稍微改了一下代码,还是有同样的重复问题,好像在new task 的时候被重复new 了多次。这个不知道是为何,
> 而且是在同一个slot里面。
>
> 异步函数:
> 然后我在执行的时候,往kafka 打了一条数据,在yarn 上起了两个  TM,每个TM 一个slot
>
> 然后在一个TM 上打印了这个日志: 我的日志是有编号的[0]  这个,一条输入是一个需要外部检测的json。
>
> ===create new task :{"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"}
> ====processing asr data: {"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"}
> === the moa resonse is: {result={s_id=userid, hit_details=操你, words=操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47, status=1, hit_logic=basePoliticsWords}, em=OK, ec=0}
> ===create new task :{"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"}
> ====processing asr data: {"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"}
> === the moa resonse is: {result={s_id=userid, hit_details=操你, words=操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47, status=1, hit_logic=basePoliticsWords}, em=OK, ec=0}
>
>
>
> 有时候这些记录在flink 里经过处理之后, 日志打印了两边,好像是处理了两遍,但是 写到下游的kafka 可能只有1个。
> 理论期望值是一条输入对应一条输出。
>
> 但是在一百万的测试数据上,上游发送肯定是只发送了100万条,带编号递增的。 但是下游去重之后是100万,不去重就有一百多万,可能
> 会多好几万的样子。比较奇怪。
>
>
>
>
>
> ------------------ 原始邮件 ------------------
> *发件人:* "Jark Wu"<im...@gmail.com>;
> *发送时间:* 2019年10月14日(星期一) 中午11:23
> *收件人:* "user-zh"<us...@flink.apache.org>;
> *主题:* Re: flink 1.6.1 RichAsyncFunction 异步请求外部系统导致下游数据大量重复
>
> Hi,
>
> 从代码上看,并没有发现什么问题,给一些排查建议:
> 1)作业在这期间有 failover 过吗?Flink 写入 Kafka 目前默认不是端到端exactly once的。
> 2) “重复几十条”是怎么判断出来的呢? 会不会 kafka 源中的数据有重复呢?
>
> Best,
> Jark
>
> On Sun, 13 Oct 2019 at 12:55, 曾耀武 <51...@qq.com> wrote:
>
> > 大家好,
> >
> >
> > 请教大家一个问题, 我在使用flink 1.6 版本去用异步的方式
> > 访问外部系统的时候发现下游的数据,本来应该只有一条的,结果被重复几十条。
> >
> >
> > 我的异步Function 片段如下。
> >
> >
> > private static class SimpleAsyncFunction extends
> RichAsyncFunction<String,
> > String> {
> >     private static final long serialVersionUID = 2098635244857937717L;
> >
> >     private transient ExecutorService executorService;
> >     private  transient Client client ;
> >
> >     private final long shutdownWaitTS=1000;
> >
> >     @Override
> >     public void open(Configuration parameters) throws Exception {
> >         super.open(parameters);
> >
> >         executorService = new
> ThreadPoolExecutor(10,30,60,TimeUnit.SECONDS,
> >                 new LinkedBlockingQueue<>(1000),
> >                 new ThreadPoolExecutor.CallerRunsPolicy());
> >          client= new Client();
> >     }
> >
> >     @Override
> >     public void close() throws Exception {
> >         super.close();
> >         ExecutorUtils.gracefulShutdown(shutdownWaitTS,
> > TimeUnit.MILLISECONDS, executorService);
> >     }
> >
> >     @Override
> >     public void asyncInvoke(final String jsonStr, final
> > ResultFuture<String> resultFuture) {
> >           result = client.predict(jsonStr);
> > resultFuture.complete(Collections.singletonList(result));}}
> > ------------------------------
> > dag构建部分为:
> > AsyncFunction<String, String> nlpMoaAsyncFunction = new
> > SimpleAsyncFunction();
> >
> > DataStream<String> source = env.addSource(flinkKafkaConsumer010);
> >
> > DataStream<String> nlpResult = AsyncDataStream.unorderedWait(
> >         source,
> >         nlpMoaAsyncFunction,
> >         timeout,
> >         TimeUnit.MILLISECONDS,
> >         30);
> >
> > FlinkKafkaProducer010<String> kafkaProducer = new
> > FlinkKafkaProducer010<String>(
> >         ImmutableConstant.NLP_RESULT_KAFKA_TOPIC,
> >         new SimpleStringSchema(),
> >         producerProp
> > );
> >
> > nlpResult.addSink(kafkaProducer);
> >
> > -------------------------整个逻辑其实很简单,程序运行在yarn 上10个taskmanager ,每个tm
> 一个slot。
> > 有没有哪个碰到类似的问题,还是是bug 或者是我的实现有问题?
>

回复: flink 1.6.1 RichAsyncFunction 异步请求外部系统导致下游数据大量重复

Posted by 曾耀武 <51...@qq.com>.
作业是没有failover 。执行是正常的。但是官方文档上不是说那个是保证exactly-once么?
我稍微改了一下代码,还是有同样的重复问题,好像在new task 的时候被重复new 了多次。这个不知道是为何,
而且是在同一个slot里面。



异步函数:

然后我在执行的时候,往kafka 打了一条数据,在yarn 上起了两个  TM,每个TM 一个slot


然后在一个TM 上打印了这个日志: 我的日志是有编号的[0]  这个,一条输入是一个需要外部检测的json。


===create new task :{"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"} ====processing asr data: {"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"} === the moa resonse is: {result={s_id=userid, hit_details=操你, words=操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47, status=1, hit_logic=basePoliticsWords}, em=OK, ec=0} ===create new task :{"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"} ====processing asr data: {"business":"test","src":"test","words":"操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47","sid":"test"} === the moa resonse is: {result={s_id=userid, hit_details=操你, words=操你妈的傻逼卧槽 [0] 2019-10-14 17:57:47, status=1, hit_logic=basePoliticsWords}, em=OK, ec=0}




有时候这些记录在flink 里经过处理之后, 日志打印了两边,好像是处理了两遍,但是 写到下游的kafka 可能只有1个。
理论期望值是一条输入对应一条输出。


但是在一百万的测试数据上,上游发送肯定是只发送了100万条,带编号递增的。 但是下游去重之后是100万,不去重就有一百多万,可能
会多好几万的样子。比较奇怪。










------------------ 原始邮件 ------------------
发件人: "Jark Wu"<im...@gmail.com>;
发送时间: 2019年10月14日(星期一) 中午11:23
收件人: "user-zh"<us...@flink.apache.org>;

主题: Re: flink 1.6.1 RichAsyncFunction 异步请求外部系统导致下游数据大量重复



Hi,

从代码上看,并没有发现什么问题,给一些排查建议:
1)作业在这期间有 failover 过吗?Flink 写入 Kafka 目前默认不是端到端exactly once的。
2) “重复几十条”是怎么判断出来的呢? 会不会 kafka 源中的数据有重复呢?

Best,
Jark

On Sun, 13 Oct 2019 at 12:55, 曾耀武 <51...@qq.com> wrote:

> 大家好,
>
>
> 请教大家一个问题, 我在使用flink 1.6 版本去用异步的方式
> 访问外部系统的时候发现下游的数据,本来应该只有一条的,结果被重复几十条。
>
>
> 我的异步Function 片段如下。
>
>
> private static class SimpleAsyncFunction extends RichAsyncFunction<String,
> String> {
>     private static final long serialVersionUID = 2098635244857937717L;
>
>     private transient ExecutorService executorService;
>     private  transient Client client ;
>
>     private final long shutdownWaitTS=1000;
>
>     @Override
>     public void open(Configuration parameters) throws Exception {
>         super.open(parameters);
>
>         executorService = new ThreadPoolExecutor(10,30,60,TimeUnit.SECONDS,
>                 new LinkedBlockingQueue<>(1000),
>                 new ThreadPoolExecutor.CallerRunsPolicy());
>          client= new Client();
>     }
>
>     @Override
>     public void close() throws Exception {
>         super.close();
>         ExecutorUtils.gracefulShutdown(shutdownWaitTS,
> TimeUnit.MILLISECONDS, executorService);
>     }
>
>     @Override
>     public void asyncInvoke(final String jsonStr, final
> ResultFuture<String> resultFuture) {
>           result = client.predict(jsonStr);
> resultFuture.complete(Collections.singletonList(result));}}
> ------------------------------
> dag构建部分为:
> AsyncFunction<String, String> nlpMoaAsyncFunction = new
> SimpleAsyncFunction();
>
> DataStream<String> source = env.addSource(flinkKafkaConsumer010);
>
> DataStream<String> nlpResult = AsyncDataStream.unorderedWait(
>         source,
>         nlpMoaAsyncFunction,
>         timeout,
>         TimeUnit.MILLISECONDS,
>         30);
>
> FlinkKafkaProducer010<String> kafkaProducer = new
> FlinkKafkaProducer010<String>(
>         ImmutableConstant.NLP_RESULT_KAFKA_TOPIC,
>         new SimpleStringSchema(),
>         producerProp
> );
>
> nlpResult.addSink(kafkaProducer);
>
> -------------------------整个逻辑其实很简单,程序运行在yarn 上10个taskmanager ,每个tm 一个slot。
> 有没有哪个碰到类似的问题,还是是bug 或者是我的实现有问题?

Re: flink 1.6.1 RichAsyncFunction 异步请求外部系统导致下游数据大量重复

Posted by Jark Wu <im...@gmail.com>.
Hi,

从代码上看,并没有发现什么问题,给一些排查建议:
1)作业在这期间有 failover 过吗?Flink 写入 Kafka 目前默认不是端到端exactly once的。
2) “重复几十条”是怎么判断出来的呢? 会不会 kafka 源中的数据有重复呢?

Best,
Jark

On Sun, 13 Oct 2019 at 12:55, 曾耀武 <51...@qq.com> wrote:

> 大家好,
>
>
> 请教大家一个问题, 我在使用flink 1.6 版本去用异步的方式
> 访问外部系统的时候发现下游的数据,本来应该只有一条的,结果被重复几十条。
>
>
> 我的异步Function 片段如下。
>
>
> private static class SimpleAsyncFunction extends RichAsyncFunction<String,
> String> {
>     private static final long serialVersionUID = 2098635244857937717L;
>
>     private transient ExecutorService executorService;
>     private  transient Client client ;
>
>     private final long shutdownWaitTS=1000;
>
>     @Override
>     public void open(Configuration parameters) throws Exception {
>         super.open(parameters);
>
>         executorService = new ThreadPoolExecutor(10,30,60,TimeUnit.SECONDS,
>                 new LinkedBlockingQueue<>(1000),
>                 new ThreadPoolExecutor.CallerRunsPolicy());
>          client= new Client();
>     }
>
>     @Override
>     public void close() throws Exception {
>         super.close();
>         ExecutorUtils.gracefulShutdown(shutdownWaitTS,
> TimeUnit.MILLISECONDS, executorService);
>     }
>
>     @Override
>     public void asyncInvoke(final String jsonStr, final
> ResultFuture<String> resultFuture) {
>           result = client.predict(jsonStr);
> resultFuture.complete(Collections.singletonList(result));}}
> ------------------------------
> dag构建部分为:
> AsyncFunction<String, String> nlpMoaAsyncFunction = new
> SimpleAsyncFunction();
>
> DataStream<String> source = env.addSource(flinkKafkaConsumer010);
>
> DataStream<String> nlpResult = AsyncDataStream.unorderedWait(
>         source,
>         nlpMoaAsyncFunction,
>         timeout,
>         TimeUnit.MILLISECONDS,
>         30);
>
> FlinkKafkaProducer010<String> kafkaProducer = new
> FlinkKafkaProducer010<String>(
>         ImmutableConstant.NLP_RESULT_KAFKA_TOPIC,
>         new SimpleStringSchema(),
>         producerProp
> );
>
> nlpResult.addSink(kafkaProducer);
>
> -------------------------整个逻辑其实很简单,程序运行在yarn 上10个taskmanager ,每个tm 一个slot。
> 有没有哪个碰到类似的问题,还是是bug 或者是我的实现有问题?