flink中cpu消耗的大户-序列化和反序列化

背景

故事的起源来源于这样一篇关于序列化/反序列化优化的文章https://www.ververica.com/blog/a-journey-to-beating-flinks-sql-performance,当把传输的对象从String变成byte[]数组后,QPS直接提升了50%

flink的网络数据交换优化

在flink中对于每个算子之间的跨网络数据交换,序列化和反序列化都是不可以避免的一环,上游算子需要把对象序列化成字节数组后通过网络进行数据传输,而下游算子收到字节数组的数据后对字节数组进行反序列化操作,当有多个这样的shuffle算子操作后,序列化和反序列化占用的cpu就会非常大,对程序性能造成极大的影响,所以问题就变成了如何最大化的减少序列化和反序列化的开销?

我们这里只是用Tuple类型序列化器作为例子,假设都是Tuple1类型,其泛型类型分别为String和byte[],可以在本地使用jmh对于这两者的序列化反序列化性能进行测试,你会发现巨大的性能差距,差异的来源在于对于String,序列化时需要先把String转成byte[],然后反序列化又要再把byte[]转成String,这样当有几千万的String要处理时,这是一批很大的开销.相反,对于byte[]来说,它可以作为字节数组进行网络传输,序列化和反序列化的开销几乎没有,所以可以节省大量的cpu资源

总结:

当有一条消息经过很多个算子才到达最终的sink算子时,如果这个消息里面的类型是String,每经过一个算子就有一次String–>byte[]的序列化和byte[]–>String反序列化的开销,N个算子就会有N次这样的序列化/反序列化操作,可想而知,这是一个非常低效的操作,我们可以这样优化:在消息进来之后新增一个map操作,先把String转成byte[]数组,后面传递的时候一直是传递的byte[]字节数组,这样通过每一个算子时就几乎没有序列化和反序列化的开销了,可以极大提高性能

你可能感兴趣的:(flink,flink,大数据)