天天看点

《大数据系统构建:可扩展实时数据系统构建原理与最佳实践》一3.3 序列化框架的局限性

序列化框架只检查所有必需的字段是否存在以及是否是预期的类型。它们无法检查更丰富的属性,如“年龄应该非负”或“真实的时间戳不应该是未来的时间戳”。在系统中,与这些属性不匹配的数据会提示出现问题,而你不想让它们写入主数据集。

这看上去不像是一个限制,因为序列化框架似乎有点类似于关系型数据库模式的工作方式。事实上,你可能已经发现了使用关系型数据库模式的痛苦,并且担心更严格的模式会令人更加痛苦。但是我们要求你不要混淆使用关系型数据库模式附带的复杂性与模式本身的价值。当应用序列化框架来表示使用图模式的不可变对象时,用关系型数据库表示嵌套对象和做模式迁移会更加容易。

思考一个模式的正确方式是,将模式作为能获取一段无论是否有效的数据并返回结果的函数。apachethrift的模式语言可以让你把只有字段存在和字段类型被验证过的函数表述为一个子集。理想的工具会让你实现任何可能的模式函数。

这样一个理想的工具—尤其是语言中立的—是不存在的,但你可以采取两种方法来解决序列化框架(如apache thrift)的这些限制:

将生成的代码封装为额外的代码,用来检查你所关注的附加属性,如“年龄非负”。只要你只使用一种语言读/写数据,这种方法是适用的—如果你使用多种语言,你必须用多种语言重复该逻辑。

在批处理工作流的最开始检查额外的属性。这一步将把数据集分成“有效数据”和“无效数据”,如果没有任何无效的数据将会发送一个通知。这种方法使得实现工作流的其余部分更加容易,因为任何通过有效性检查的数据可以被认为拥有你所关注的更严格的属性。但是这种方法并能不阻止无效的数据写入主数据集,也不能帮助确定损坏发生时的上下文。

这两种方法都不是很理想,但如果你的结构使用多种语言读/写数据,你会发现很难做得比这更好。所以你必须决定是更愿意用多种语言保持相同的逻辑,还是失去损坏发生时的上下文。唯一完美的方法是,一个序列化框架也是一类通用的编程语言,可以将本身翻译成任何目标语言。虽然这样的工具在理论上是可能的,但在现实中是不存在的。