我们使用protobuf编码的消息处理kafka / samza作业管道。对于某些数据集,管道可能非常冗长,我们希望为管道中的每个阶段添加时间戳/ id,以监控效率和服务运行状况。
附加信息将添加到称为接触点的模式中的重复字段中。显然在java / samza中解码消息,添加附加消息并再次序列化会产生开销随着消息的大小而增加(有些可能会增加反序列化时间),管道的某些部分只是检查消息的过滤器密钥甚至可能根本不需要反序列化,因此这些开销越少越好。
是否可以在没有反序列化的情况下将第二个序列化消息注入到现有消息中,如果是这样,这样做是非常糟糕的做法(我只能认为它会这样做)并且是否有更好的解决方案来不必反序列化/ add / serialize用于监视消息路径/流动时间
答案 0 :(得分:3)
通常,这将非常棘手,并且由于以下原因无法以“流式”方式完成:子消息的前缀是以可变长度整数编码的大小。因此,注入某些东西意味着递归调整所有父级大小直到根,并且由于大小的可变长度编码,大小更改可能再次移动内容。
要避免此问题,您可以做的一件事可能是使用固定大小的字段作为时间戳,并确保在第一阶段构建protos时填充了一个值,因此您已经分配了相应的原型中的空间。这应该允许您使用CodedInputStream
扫描原型(理想上唯一的)时间戳字段ID,并使用CodedOutputStream
写回修补的流。要使其正确,仍需要了解内部格式。我建议首先从空的pass-trough“过滤器”开始,检查输出是否与输入匹配(如果遇到任何问题,请更新问题)