二进制和文本结构(数据包)的高效解码

时间:2012-11-30 16:32:26

标签: java decode network-protocols

背景

有一个名为Wireshark的着名工具。我已经使用了很多年了。这很棒,但性能是问题所在。通用使用场景包括若干数据准备步骤,以便提取稍后要分析的数据子集。如果没有这一步,则需要几分钟才能进行过滤(Wireshark旁边的大痕迹无法使用)。

enter image description here

实际的想法是创建一个更好的解决方案,快速,并行和高效,用作数据聚合器/存储。

要求

实际要求是使用现代硬件提供的所有电源。我应该说有一个不同类型的优化空间,我希望我在上层做得很好,但技术是现在的主要问题。根据目前的设计,有几种类型的数据包解码器(解剖器):

  • 交互式解码器:解码逻辑可以在运行时轻松更改。这种方法对协议开发人员非常有用 - 解码速度并不重要,但灵活性和快速结果更为重要
  • 嵌入式解码器:可以用作库。这种类型应该具有良好的性能,并且足够灵活,可以使用所有可用的CPU和核心
  • 解码器即服务:可以通过干净的API访问。此类型应提供最佳的品种性能和效率

结果

我目前的解决方案是基于JVM的解码器。实际的想法是重用代码,消除移植等,但仍然具有良好的效率。

  • 交互式解码器:在Groovy上实现
  • 可嵌入解码器:在Java上实现
  • 解码器即服务:封装在servlet中的Tomcat +优化+嵌入式解码器(二进制输入,XML输出)

需要解决的问题

  • Groovy提供了更强大的功能和一切,但在这种特殊情况下运气表现力
  • 将协议解码为树结构是一个死胡同 - 太多资源被浪费了
  • 内存消耗有点难以控制。我做了几次优化但仍不满意分析结果
  • 带有各种铃声和口哨声的Tomcat仍然会引入很多开销(主要是连接处理)

我到处都在使用JVM吗?您是否看到了实现最初目标的任何其他优秀和优雅的方法:获得易于编写的高度可扩展且高效的协议解码器?

协议,结果格式等不固定。

3 个答案:

答案 0 :(得分:7)

我发现了一些可能的改进:

互动解码器

通过使用Groovy语法扩展,可以大大提高Groovy表达能力 AST Transformations。因此,有可能简化解码器创作仍然提供良好的性能。 AST(代表抽象语法树)是一种编译时技术。

  

当Groovy编译器编译Groovy脚本和类时,在某些情况下   在这个过程中,源代码将最终被表示出来   以具体语法树的形式存储,然后转换为   抽象语法树。 AST Transformations的目的是让   开发人员挂钩进入编译过程就可以修改了   AST在变为将由JVM运行的字节码之前。

我不想重新发明轮子,引入另一种语言来定义/描述协议结构(它足以拥有ASN.1)。这个想法是简化解码器开发,以提供一些快速原型技术。基本上,将引入某种DSL。

Further reading

嵌入式解码器

Java可能会引入一些额外的开销。有几个库可以解决这个问题:

enter image description here

坦率地说,除了这个图层的Java之外,我没有看到任何其他选项。

解码器即服务

此图层不需要Java。最后我有一个很好的选择,但价格相当高。 GWan看起来非常好。

enter image description here

需要一些额外的移植,但绝对值得。

答案 1 :(得分:3)

这个问题似乎与许多高性能I / O实现问题具有相同的特征,即内存副本的数量在性能上占主导地位。异步I / O的分散 - 聚集接口模式遵循此原则。通过分散 - 聚集,在适当的位置操作存储器块。只要协议解码器将块流作为输入而不是字节流,您就可以消除大量移动内存以保留字节流抽象的性能开销。字节流是一种非常好的抽象,可以节省工程时间,但对于高性能I / O却不太好。

在相关问题中,我只是因为基本类型String而要小心JVM。我不能说我熟悉如何在JVM中实现String,但我确实认为没有办法在不进行内存复制的情况下从块列表中创建字符串。另一方面,本地类型的字符串可以与JVM String兼容地兼容,这可能是分裂差异的一种方式。

<小时/> 这个问题的另一个方面似乎是正式语言。本着不复制内存块的精神,您也不希望一遍又一遍地扫描同一块内存。由于您希望进行运行时更改,这意味着您可能不希望使用预编译状态机,而是使用递归下降解析器,可以在每个下降级别调度到适当的协议解释器。当外层没有指定内层的类型时,涉及一些复杂性。当你甚至没有得到内部内容的长度时,那些复杂情况会更糟,因为那时你依靠内在的内容来形成良好以防止失控。然而,值得注意的是要了解扫描一个块的次数。

答案 2 :(得分:1)

网络流量正在增长(some analytics),因此需要每秒处理越来越多的数据。

实现这一目标的唯一方法是使用更多CPU功率,但CPU频率稳定。只有核心数量在增长。看起来唯一的方法是更有效地使用可用内核并更好地扩展。

enter image description here