如何构建高性能可视化架构?一个交互式实时数据引擎的架构设计
在分析SecDB、Athena、Quartz几个实时金融与风险分析平台的时候,发现了Perspective——一个FinTech开源基金会FinOS旗下开源的交互式分析和可视化组件库,由摩根大通(J.P.MorganChase)公司开源出去的流式数据可视化组件库。所以,从某种意义上来说也是《金融Python即服务:业务自助的数据服务模式》的后续展开,也可以算是低延迟架构的后续探索。
起初,我只是对其中使用的ExprTk感兴趣,后来发现这个库不简单:使用了C++、Rust、Python、JavaScript、TypeScript等语言。混合语言的项目都特别好玩,于是乎,我便开始探索它了。而我原先感兴趣的x<='abc123'and(yin'AString')or('1x2y3z'!=z)的解析与实现,也就先放在一边了。
开始之前,先复制一下官方的介绍:
Perspective是一个交互式分析和数据可视化组件,特别适合大型数据集或流数据。可以使用它来创建用户可配置的报告、仪表板、Notebook和应用程序,然后在浏览器中独立部署,或与Python和/或Jupyterlab协同部署。
简单来说,就是可以提供实时图形渲染,并支持Jupyter集成。如果是Jupyter的集成,那么从某种来说,它是一种金融工作台,类似于先前定义的架构工作台。
PS:写这样的工具太过复杂了,所以先写篇文章记录一下,等未来有空的时候,再写一个。
初步绘制的Perspective架构图如下所示:
在JavaScript侧,系统可以分为三层:
数据引擎。使用C++与一系列的数据结构库等,进行封装,并提供数据操作API。通过Emscripten构建和封装,以提供WASM接口。
wrapper层。提供对于数据引擎的再次封装,以使API更符合日常的编程习惯,诸如于table、view等,还提供worker、websocket等封装。
UI组件。viewer分为d3fc、datagrid、openlayers等不同的组件,大部分使用纯Rust编写,提供WebComponentAPI等。
在Python侧,除了相同的UI部分,还需要构建Jupyter插件:
数据引擎。结合pybind11来提供FFI(ForeignFunctionInterface,外部函数接口)能力。
wrapper层。结合了Python数据科学生态中的Pandas、Numpy等工具,来进行数据转换。
UI层。结合Lumino对UI组件进行封装。
其中,比较有意思的是ApacheArrow,提供了跨语言的数据支持。
对于将密集型计算下沉到WASM部分,相信大家都比较熟悉了。对于常规的WASM使用来说,需要平衡开发效率和运行效率,FFI在调用的时候也存在性能损失。也因此,一种比较理想的方式是将数据操作,全部委托给C++部分去实现。
如上面的架构图所示,Perspective的计算部分,主要是Table对象实现的,它是Perspective中的基本数据容器。Table是有类型的——它们有一组不可变的列名,每个都有一个已知的类型。每当有对数据的处理时,都会通过WASM来处理。过滤与计算,在这里也是一个非常有意思的问题,即上面说到的ExptTk,便是用来做这部分计算用的。
值得注意的是,Perspective之所以采用C++来构建WebAssembly的方式,大概率是因为原有的一部分基础设施是基于C++的。与此同时,原先采用的是C++的UI,以提供更好的性能。不过,Perspective提供的WASM包,大概有40M左右,在初始化的时候相对慢了一点。
可是,又为什么是Table呢?这就得从ApacheArrow提供的能力说起。
对于序列化的性能优化,相信大家都比较熟悉了。通常来说一次数据传输操作包括:
以某种格式序列化数据
通过网络连接发送序列化数据
在接收端反序列化数据
于是乎,在很多系统中(如ArchGuard),序列化就是系统的瓶颈。既然序列化会带来问题,那么就不应该有序列化。于是乎,我们就可以在上面的架构图中,看到两个工具:
ApacheArrow。一个直接针对数据分析需求的数据层,提供分析所需的数据类型的综合集合。除了语言无关的标准化列式存储格式之外,它还包含三个特性:零拷贝共享内存和基于RPC的数据移动、读取和写入文件格式(如CSV、ApacheORC和ApacheParquet)、内存分析和查询处理。
FlatBuffers。同样的,无需解析/解包即可访问序列化数据。
不过呢,FlatBuffers只是Arrow用来序列化实现Arrow二进制IPC协议所需的模式和其他元数据。随后,我们就可以使用Table来调用Arrow的API来进行计算。
ApacheArrow的相关介绍可以见官方文档:https://arrow.apache.org/
简单来说,只要是以下的两个特点:
无框架。对于一个以渲染为主的项目来说,Perspective不采用任何框架。从某种意义上来说,更小的包大小,也带来了更好的性能。除此,作为一个纯粹的webcomponents组件,它可以非常容易与几大主流框架结合到一起。
虚拟渲染的Table。在Table显示上,Perspective采用的是JMPC的regular-table,同样也是WebComponents组件,可以直接引入项目使用。并且支持虚拟渲染,即仅显示可视区域的数据,减少DOM节点以带来更好的性能。
对于WebComponent和CustomElement部分,相信大家都比较熟悉了。它们使用起来和正常的HTML区别不大,如下是一个不同UI组件之间的关系示例:
每一个组件分别在不同的工程中,倒是挺componentless的。一旦数据发生变化的时候,就会从viewer侧,调用update_and_render从而更新UI部分的render。
参考材料:
《ApacheArrow和Java:大数据传输快如闪电》
《Perspective.js》官网
主题测试文章,只做测试使用。发布者:最新稳定辅助网,转转请注明出处:https://www.744broad.com/13975.html