• 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[]字节数组,这样通过每一个算子时就几乎没有序列化和反序列化的开销了,可以极大提高性能

  • 相关阅读:
    Unity界面介绍:场景视图
    【云原生 | Kubernetes 系列】K8s 实战 配置 Pod 的服务质量(QoS)类
    MySQL查询优化之order by 与 group by优化
    Maven
    Mybatis笔记框架(持续更新~~~)
    Spring Cloud Gateway实现限流
    与创新者同行,Apache Doris in 2023
    gin-gonic/gin使用详解
    文章本天成|跟我一起来一场简洁易懂的servlet的过滤器Filter的学习吧
    题解——01背包问题例题(装箱问题、宠物小精灵之收服)
  • 原文地址:https://blog.csdn.net/lixia0417mul2/article/details/133110099