flink实时流与scala程序开发实用经验 - 十年磨两贱人

本文是作者在用 flink 开发实时流数据的时候,对 flink 的一些总结经验,其中会重点讲到 “数据倾斜” 的解决方案 + 源码

文章结构:

1:flink本地如何模拟topic的实时流

2:flink在遇到数据倾斜的时候,应该怎么样写代码解决

一、先模拟topic发送数据的例子

1:在idea这个编译器上启动你的flink程序,这个程序里面最开始需要有个代码是设置你消费的数据从本地的某个端口得来

val env = StreamExecutionEnvironment.getExecutionEnvironment
env.enableCheckpointing(5000)

val text = env.socketTextStream("127.0.0.1", 9998).map(x => (
            x.split(",")(0), x.split(",")(1), x.split(",")(2), x.split(",")(3), x.split(",")(4)
        ))

然后你在本地开个shell,按照下面输入命令即可

linux shell > nc -L -p 9998 -v
listening on [any] 9998 ...
connect to [127.0.0.1] from username 
kuaishou,001,asaqwdw,1574653642,0
kuaishou,001,asaqwdw,1574653642,0
kuaishou,001,asaqwdw,1574653642,0

这一步具体可以参考这篇文章:https://www.cnblogs.com/limaosheng/p/10434848.html

只有在掌握了本地如何调试数据的办法,自己在解决一些问题的时候才会很方便,比如遇到数据倾斜的问题的时候,自己想到一些办法,在本地试代码正确性的话会很方便,接下来我就来讲解如何写数据倾斜的代码

二、数据倾斜原理 + 代码

具体原理可以参考这篇文章:https://blog.csdn.net/it_lee_j_h/article/details/88641894

遇到的需求:统计过去1天内,某个key的出现次数

在写这个代码的时候,主要就是由两步骤组成,第一步是先给key加个随机数将大key给随机分成几百、几千份,减少这种倾斜key的问题,这一步需要窗口完成,然后在末尾还原真实的key。第二步在用个窗口统计下即可

所以关键是两步分别选什么样的窗口,这里我直接说结论。我起先选的是两个滑动窗口,但是这样存在一个问题,统计值会把上一次的计算值给加进来,这样统计值就不断的在累加,这个很明显不符合要求;最后确定了先用滚动窗口,再用滑动窗口。接下来我会把两次尝试的代码、数据输入case、统计结果都进行展示出来,以方便大家更深入了解

val outputStreamV1 = text
            .map { x => (getRandomInt(1000).toString + "_" + x._1, Array(x._2).length) }
            .keyBy(_._1)
            .window(SlidingProcessingTimeWindows.of(Time.minutes(10), Time.seconds(5)))
            .sum(1)
       
val outputStreamV2 = outputStreamV1.map(x => (x._1.split("_")(1), x._2)).keyBy(0)
            .window(SlidingProcessingTimeWindows.of(Time.minutes(10), Time.seconds(5)))
            .sum(1).map(x => ("dada", x._2))

     

如果输入是一次性按照上面的办法输入下面这3条的话

kuaishou,001,asaqwdw,1574653642,0
kuaishou,001,asaqwdw,1574653642,0
kuaishou,001,asaqwdw,1574653642,0

按照我们的想象,这个程序里面 outputStreamV2 应该会一直输出累加为3的数据,但是实际上会因为两个 slidingWindow连在一起会把上一次的计算结果累计到下一次,所以会是下面一种输出

(1575115280,dada,3)
(1575115280,dada,6)
(1575115280,dada,9)

但是如果把第一个窗口类型换成翻滚窗口的话,就能解决这个问题。原因也很简单,翻滚+滑动,不会造成上面说的那个问题,而且要保证滑动的周期必须是翻滚的倍数,这样才能保证滑动消费翻滚窗口的时候能够把最原始的数据都消费完全

下一篇文章:flink有数据倾斜,但并不是最常见的倾斜,下一篇蚊帐里我会讲解spark处理数据时候遇到的倾斜问题的代码应该怎么写

 

你可能感兴趣的:(AI爱好者社区)