131

聊聊Apache Arrow

 6 years ago
source link: http://www.infoq.com/cn/articles/apache-arrow?amp%3Butm_medium=popular_widget&%3Butm_campaign=popular_content_list&%3Butm_content=homepage
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

聊聊 Apache Arrow





基本介绍

Apache Arrow 是一种基于内存的列式数据结构,正像上面这张图的箭头,它的出现就是为了解决系统到系统之间的数据传输问题,2016 年 2 月 Arrow 被提升为 Apache 的顶级项目。

在分布式系统内部,每个系统都有自己的内存格式,大量的 CPU 资源被消耗在序列化和反序列化过程中,并且由于每个项目都有自己的实现,没有一个明确的标准,造成各个系统都在重复着复制、转换工作,这种问题在微服务系统架构出现之后更加明显,Arrow 的出现就是为了解决这一问题。作为一个跨平台的数据层,我们可以使用 Arrow 加快大数据分析项目的运行速度。下面这张图概括了 Hadoop 生态系统,本身就分为 4 层,每层又有若干组件,而且还在不断扩大系统范围,如果各个系统之间都需要进行序列化和反序列化,消耗巨大。

相关技术

  • 适配器模式

适配器模式是经典的 23 种设计模式之一,它的主要作用是在新接口和老接口之间进行适配,可以让客户方便使用,不需要改造自身的产品,如下图所示。

虽然 Apache Arrow 的实现细节远不止适配器模式,但是它从功能设计思路来看,还是有点像的,有了 Arrow 之后,它的一部分功能就相当于所有系统的适配器了。

我们假设数据表有 session_id、timestamp、source_ip 等三个字段,在行式存储的时候,按照每一行形式包含 3 个字段,而多行之间是互相分开的,没有关联,而到了列式存储概念,我们按照每一列对数据进行聚集,例如 session_id 包含了“1331246660”等 4 个值。

从上面这张摘录自 Arrow 官网的图可以看出,传统的内存数据格式以每一行作为各个字段的分布,相同字段没有被集中在一起,造成了计算时的不必要浪费。通过列式存储格式约束,可以将相同字段集中排列在一起。而官网也给出了一条 SQL 语句,代表使用 SQL 语句很容易查询得到数据。

  • SIMD 指令

即单指令流多数据流(SingleInstruction Multiple Data),是一种采用一个控制器来控制多个处理器,同时对一组数据(又称“数据向量”)中的每一个分别执行相同的操作从而实现空间上的并行性的技术。在微处理器中,单指令流多数据流技术则是一个控制器控制多个平行的处理微元。

技术深入

需要明确的是,Apache Arrow 不是一个引擎,也不是一个存储系统,它是用来处理分层的列式内存数据的一系列格式和算法。它不是一个独立的软件,而是系统中用来加速数据分析的一个组件。很多开源项目都已经支持了 Arrow,而且其他商业化的项目也有这个趋势。对于已经支持 Arrow 的项目来说,这些项目不再需要序列化和反序列化各种数据,从而以极小的成本来共享数据资源,对于同一集群下的系统则完全不需要进行任何的数据格式转换。

对于 Apache Arrow 的期望:

  • 列式存储:大数据系统几乎都是列式存储的,类似于 Apache Parquet 这样的列式数据存储技术自从诞生起就是大家的期望。
  • 内存式:SAP HANA 是第一个利用内存加速分析流程的组件,随着 Apache Spark 的出现,进一步提升了利用内存加速流程的技术可能性落地。
  • 复杂数据和动态模式:当我们通过继承和内部数据结构呈现数据的时候,一开始有点麻烦,后来就有了 JSON 和基于文档的数据库。

Arrow 的列式存储有着 O(1) 的随机访问速度,并且可以进行高效的 Cache,同时还允许 SIMD 指令的优化。由于很多大数据系统都是在 JVM 上运行的,Arrow 对于 Python 和 R 的社区来说显得格外重要。

Apache Arrow 是基于 Apache Drill 中的 Value Vector 来实现的,而使用 Value Vector 可以减少运算时重复访问数据带来的成本。

举个例子,有一个 people 数组:

复制代码
<pre data-anchor-id="zzw4">

people=[
{
name:’mary’,age:30,
placed_lived:[
{city:’Akron’,state:’OH’},
{city:’Bath’,state:’OH’}
]
},
{
name:’mary’,age:31,
placed_lived:[
{city:’Lodi’,state:’OH’},
{city:’Ada’,state:’OH’}
{city:’Akron’,state:’OH’}
]
}
]

复制代码

其中,对于 people.places_lived.city,在 Arrow 中是这样存储的:

这种存储方式有 O(1) 的访问速度,可以有效地缓存,而且,在 Value Vector 中的信息可以直接在不同的项目之间传递,不依赖于所使用的编程语言。

而从代码层面分析,Apache Arrow 类的设计采用了设计模式里的建造者模式,封装了基础类 Array、Buffer 以及 ArrayBuilder,具体类图如下图所示:

从 GC 的角度来看,Arrow 基于一种有规划的内存使用理念。传统的 GC 面对的程序数据是很多细粒度的、频繁诞生与消亡的对象。而 Arrow 的内存使用体现了基于较粗粒度的按需分配,有良好的线性关系,要处理的数据都是大块的,本身不具高频新生与删除的数据。(而这种数据特性刚好很切合我们的内存表所要处理的数据。)由于数据本身块头大,变化频率低,为进一步规划更稳健和高效的内存分配策略提供了可能。系统启动时需要预锁定一片区域;当删除数据时,瞬时归还系统,但会留存一块;几乎没有内存碎片。

总结

Apache Arrow 之所以会流行,是因为它不针对特定产品,而是可以为大数据整个生态系统带来便利。有了 Arrow 作为标准数据交换格式,各个数据分析系统和应用之间的交互性有了全新的方式,我们不再需要把 CPU 资源花费在数据的序列化和反序列化上了,实现了不同系统之间数据的无缝连接,官网发表的文章显示,它的目标是提升数据之间的 100 倍交换速度,这样才能真正对数据分析流程进行加速。

作者介绍:周明耀,2004 年毕业于浙江大学,工学硕士。13 年软件研发经验,近 10 年技术团队管理经验,4 年分布式计算、大数据技术经验。著有《大话 Java 性能优化》、《深入理解 JVM&G1 GC》、《技术领导力 - 码农如何才能带团队》。个人微信号 michael_tec,个人公众号“麦克叔叔每晚 10 点说”。

感谢蔡芳芳对本文的审校。

划线
评论
复制

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK