Apache Arrow 是列式内存分析的事实标准,由来自Drill、Hadoop、HBase、Impala、Storm等13个顶级开源项目的工程师们开发和完善。Apache Arrow 是一种基于内存的列式数据结构,它的出现就是为了解决系统到系统之间的数据传输问题,2016 年 2 月 Arrow 被提升为 Apache 的顶级项目。

在分布式系统内部,每个系统都有自己的内存格式,大量的 CPU 资源被消耗在序列化和反序列化过程中,并且由于每个项目都有自己的实现,没有一个明确的标准,造成各个系统都在重复着复制、转换工作,这种问题在微服务系统架构出现之后更加明显,Arrow 的出现就是为了解决这一问题。作为一个跨平台的数据层,我们可以使用 Arrow 加快大数据分析项目的运行速度。

相关技术

适配器模式

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


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

传统的访问各个数据模型中的数据以及使用 Arrow 后的图,如下所示:

通过上图可以总结出以下观点:

  • 每个系统都有属于自己的内存格式。
  • 70~80% 的 CPU 浪费在序列化和反序列化上。
  • 在多个项目都实现的类似的功能(Copy & Convert)。


而在看上述使用 Arrow 后,得出以下结论:

  • 所有的系统都使用相同的内存格式。
  • 没有跨系统通信开销。
  • 项目可以贡献功能(比如,Parquet 到 Arrow 的读取)。

列式存储

我们假设数据表有 session_id、timestamp、source_ip 等三个字段,在行式存储的时候,按照每一行形式包含 3 个字段,而多行之间是互相分开的,没有关联,而到了列式存储概念,我们按照每一列对数据进行聚集,例如 session_id 包含了“1331246660”等 4 个值。
从上面这张摘录自 Arrow 官网的图可以看出,传统的内存数据格式以每一行作为各个字段的分布,相同字段没有被集中在一起,造成了计算时的不必要浪费。通过列式存储格式约束,可以将相同字段集中排列在一起。使 SQL 语句更容易查询得到数据。

SIMD 指令

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

技术深入

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

业界对于 Apache Arrow 的期望:

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

目前已有的大多数系统几乎没有支持上述两点以上的,许多只支持其中之一。而这就是 Apache Arrow 脱颖而出的地方,它能够无缝支持以上三点。

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

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

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

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默认使用Little-Endian,在Apache Arrow的Schema元数据中有一个endianness 字段来表示是Little-Endian还是Big-Endian,edianness的典型值是生成Arrow数据的系统的所使用的的字节顺序,也就是说具有相同字节顺序的平台可以交换数据。在最开始的实现中,如果是不同的endianness,则直接返回错误。在本文中Apache Arrow主要考虑Little-Endian,所有的测试也是围绕着Little-Endian。最终也许会考虑实现在Little-Endian和Big-Endian无缝转换。

字节对齐和填充

如上所述,所有缓冲区必须在8字节边界的内存中对齐,并填充为8字节倍数的长度。 对齐要求遵循优化内存访问的最佳实践:

  • 数字数组中的元素将保证通过对齐访问来检索。
  • 在某些体系结构上,对齐可以帮助限制部分使用的缓存行。
  • 对于超过64字节的数据结构,英特尔性能指南建议使用64字节对齐(这将是箭头阵列的常见情况)。

建议填充为64字节的倍数,允许在循环中一致地使用SIMD指令而无需额外的条件检查。 这样可以写出更简单,高效、CPU缓存友好的代码。

选择这个特定的填充长度是因为它可以匹配截至2016年4月可用的最大的已知SIMD指令寄存器(Intel AVX-512)。换句话说,可以将整个64字节缓冲区加载到512位宽的SIMD寄存器中,并在使得64字节缓冲区中的所有列值获得数据级并行性。通过填充还可以让一些编译器直接生成更优化的代码。

总结

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

参考:
1.http://www.sohu.com/a/165358653_470008
2.http://arrow.apache.org/
文章资源来源于网上,若有侵权请联系删除。

Apache Arrow:列式内存相关推荐

  1. Apache开源列式存储引擎Parquet和ORC比较

    相比传统的行式存储引擎,列式存储引擎具有更高的压缩比,更少的IO操作而备受青睐(注:列式存储不是万能高效的,很多场景下行式存储仍更加高效),尤其是在数据列(column)数很多,但每次操作仅针对若干列 ...

  2. Apache Arrow 内存数据

    1.概述 Apache Arrow 是 Apache 基金会全新孵化的一个顶级项目.它设计的目的在于作为一个跨平台的数据层,来加快大数据分析项目的运行速度. 2.内容 现在大数据处理模型很多,用户在应 ...

  3. Apache Arrow 内存数据交换格式

    Apache Arrow是Apache基金会下一个全新的开源项目,同时也是顶级项目.它的目的是作为一个跨平台的数据层来加快大数据分析项目的运行速度. Apache Arrow 是 Apache 基金会 ...

  4. Apache Arrow 简介

    arrow主要focus在帮助 data 序列化, 以便在各种system之间transfer. arrorw还解决了类型共享计算格式不统一的问题,是高性能计算的基础. 背景 https://arro ...

  5. 深入分析Parquet列式存储格式

    深入分析Parquet列式存储格式 Parquet是面向分析型业务的列式存储格式,由Twitter和Cloudera合作开发,2015年5月从Apache的孵化器里毕业成为Apache顶级项目,最新的 ...

  6. 为什么 OLAP 需要列式存储

    为什么这么设计(Why's THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点.对具体实现造成的影响 ...

  7. ClickHouse数据分析列式数据库概述

    一. 概述 随着物联网IOT时代的来临,IOT设备感知和报警存储的数据越来越大,有用的价值数据需要数据分析师去分析.大数据分析成了非常重要的环节.当然近两年开启的开源大潮,为大数据分析工程师提供了十分 ...

  8. 用户关系表 存储_列式存储系列(一)CStore

    作者:辛庸,阿里巴巴计算平台事业部 EMR 技术专家.Apache Hadoop,Apache Spark commiter.对 Hadoop.Spark.Hive.Druid 等大数据组件有深入研究 ...

  9. 两种列式存储格式:Parquet和ORC

    背景 随着大数据时代的到来,越来越多的数据流向了Hadoop生态圈,同时对于能够快速的从TB甚至PB级别的数据中获取有价值的数据对于一个产品和公司来说更加重要,在Hadoop生态圈的快速发展过程中,涌 ...

最新文章

  1. GDPR:我们将如何对待你的数据?
  2. 人工智能克服了类脑硬件的绊脚石
  3. D3-栈[Java数据结构和算法]
  4. ZYNQ7000-GPIO EMIO中断实验 程序烧写后自动进一次中断的怪现象
  5. 摆放家具-家具类以及创建家具对象
  6. IDA Plugin 编写基础
  7. Unity3D研究院之Android同步方法读取streamingAssets
  8. java调用oracle存储过程_做一点,记一点 ~ Java调用Oracle存储过程
  9. 更改Mysql5.7的默认编码为utf8解决database为latin1无法修改问题
  10. paip.java桌面开发应用与WEB RIA应用
  11. 基于OpenCV的银行卡号识别系统实现(一)----- 银行卡号识别步骤
  12. STM32 Cubemax(十五) —— 串级PID以控制电机角度值为例
  13. 将旧硬盘的内容克隆到新硬盘
  14. 公司邮箱精选-国际通用的电子邮箱有哪些?
  15. 数据脱敏,你会了吗(二)
  16. 2021 ACM杰出科学家揭榜:清华刘奕群、上科大虞晶怡等19位华人学者入选
  17. 程序员练级攻略(2018):前端基础和底层原理
  18. 深入理解CDC原理与Debezium数据接入流程和原理
  19. BSP -- 图书共享系统(Book Sharing Platform)
  20. 文件服务器建立,文件服务器建立

热门文章

  1. 漫谈函数式编程:聊聊 OCaml
  2. 视频教程-PostgreSQL数据库管理(三)-其他
  3. 获取token和token的过期时间后不断刷新过期时间的处理方式
  4. scrapy框架爬取古诗文网的名句
  5. count(*)、count(1)和count(列名)的区别
  6. python集合中可以包含相同的元素_Python 集合可以包含相同的元素
  7. Vue2双向绑定,Object.defineProperty、Observe、Compile、Watcher、Dep各显神通,相辅相成
  8. 超800万辆「巨量」市场,谁在进攻智能驾驶「普及型」赛道
  9. 练习java文档Locale.Category
  10. 模板详解 --- 函数模板与类模板