Scala 处理非密封特征层次结构数据流的最佳方法

Scala 处理非密封特征层次结构数据流的最佳方法,scala,apache-flink,Scala,Apache Flink,我知道,对于ADT(密封特征),有一些正在进行的努力,以克服kryo回退造成的性能下降(请参阅)。例如: 密封特征事件{ 定义id:Int } 案例类Pageview(id:Int,page:String)扩展事件 案例类单击(id:Int,url:String)扩展事件 然而,除了未密封的特征之外,还有什么方法可以处理类似的情况吗?也就是说,设想一种情况,事件未被密封,因为您事先不知道将要处理哪些特定事件,或者您正在开发一个通用框架,该框架将用于以后开发特定的应用程序,每个框架处理一组特定事

我知道,对于ADT(密封特征),有一些正在进行的努力,以克服kryo回退造成的性能下降(请参阅)。例如:

密封特征事件{
定义id:Int
}
案例类Pageview(id:Int,page:String)扩展事件
案例类单击(id:Int,url:String)扩展事件
然而,除了
未密封的
特征之外,还有什么方法可以处理类似的情况吗?也就是说,设想一种情况,
事件
未被密封,因为您事先不知道将要处理哪些特定事件,或者您正在开发一个通用框架,该框架将用于以后开发特定的应用程序,每个框架处理一组特定事件。因此,基本上,这种特征是无法被封闭的。在每个特定的应用程序中,可以处理从协议缓冲区定义自动生成的案例类,而不是像
Pageview
Click
这样的简单案例类,可以说,在一个能够将更多类型的事件添加到混合中的系统中

明确地说,主要的想法是在
DataStream[Event]
的术语,其中
Event
将是捕获 所需的共性。在每个特定的应用程序中,都可以使用一个 具有不同类型的事件,但最终将执行联合,以便在
数据流[Event]
中组合它们


如果要优化序列化性能,应该如何解决这个问题?一般的建议是不要首先将Flink与异构类型一起使用,因为它将无法派生高效的序列化程序。但是所描述的用例对我来说是合法的,那么处理它的最佳方法是什么,或者换句话说,如何最大限度地减少由于序列化而导致的性能下降?

有两种选择:

  • 实现您自己的序列化程序:此序列化程序有一个可能类型的字典,并通过它对该类型进行编码。这也有点类似于在注册类中使用Kryo,但是您可以为负载使用更高性能的序列化程序
  • 泛化您的框架-理想情况下使用具体化类型:您只需编写一次共享代码,但它以非常特定的方式应用于每个应用程序。然而,这对最终的工会来说并不奏效。它更适用于跨不同应用程序(验证、数据清理、接收器)共享的联合步骤
  • 重新思考您的数据模型:如果事件最终被写入Kafka或Pulsar,则无论如何都需要使其独立于应用程序。你可以用一个。它的动态性较低,但对于严肃的应用程序,我发现模式优先的方法工作得更好(更好的模式兼容性、更快、更清晰的API=其他团队的模式)

就我而言,卡夫卡已经有了不同的事件类型。它们对应于协议缓冲区生成的案例类。我想要的是一种方法,以某种方式对所有数据流进行规范化,然后将所有不同的数据流合并成一个数据流,以便基于一些常见的必填字段进行统一的数据处理。我现在要做的是调整每种特定类型的事件,使其符合
事件
特征。因此,我将原始事件包装到类中,这些类基于底层(原始)事件的数据(可以说是有效负载)实现公共接口。