在当前信息大爆炸的时代,“大数据”已成为互联网行业人人谈论的热词和话题,比如近几年快速发展的基于大数据进行精准用户定向的程序化广告,以及去年马云提出的利用大数据重塑商品的生产 - 流量 - 销售流程的“新零售”模式等。大数据已经渗透到众多的行业,为许多企业带来了变革性影响。那么,何为“大数据”呢?大数据(Big Data),可以简单的理解为无法在一定时间范围内用常规手段进行处理的海量数据集合。所有企业的业务分析都是基于数据的,每家企业对数据的收集、整合及处理能力在一定程度上决定了企业的业务发展水平。因此,提升数据分析性能也是当前许多企业共同面临的重大挑战。目前,行业中的大数据分析架构一般使用基于 Hadoop 体系的分布式计算引擎 + 分布式存储系统架构(如下图)。
Hadoop 体系的架构特点是上层解决计算问题,下层解决存储问题。它可以让开发者在不了解分布式底层细节的情况下,进行分布式程序的开发。但是,这种架构同时也存在一些问题:
整合工作量大
分布式存储目前的标准比较统一,一般使用 HDFS。HDFS 能有效解决海量数据的存储问题,并且有多种方便的工具链。但是,分布式计算引擎为了适应不同场景,会有不同特性的数据仓库工具,仅 Apache 就有 Hive、Spark、Drill、Impala、Presto 等产品,除此之外,还有独立于 Hadoop 体系之外其它产品项目(如 ClickHouse、Kudu、Druid 等)。由于每个产品都有各自的特性,当需要利用多个产品来解决不同问题时,就需要额外的整合工作,降低了工作效率。
数据交换速度慢
由于计算层必然是驻于内存的,从存储层到计算层的速度限制就成了系统的普遍瓶颈。有些系统为了加快速度全部使用内存存储(比如内存数据库、基于 Spark 的 SnappyData),这种方式在数据量较大时会造成巨大的成本压力,因此目前还远未成为主流。
数据实时分析性差
由于文件系统的天然限制,数据一般是批量导入系统的。导入的时间会依据数据量的大小而有所不同,在数据量较大时常会出现入库滞后现象,从而影响了数据分析的及时性。
因此,我们需要一个可以充分解决以上问题的大数据储存格式,也就是笔者接下来要为大家介绍的 IndexR 开源大数据存储数据库。
IndexR 是一个开源的大数据存储格式(下载地址 https://github.com/shunfei/indexr),于 2017 年 1 月初正式开源,目前已经更新至 0.5.0 版本。IndexR 旨在通过添加索引、优化编码方式、提高 IO 效率等各种优化方式来提高计算层和存储层的数据交换效率,从而提升整体性能。同时,IndexR 可以接收实时数据,并对上层提供统一的数据接口。数据一旦到达 IndexR 系统即可立刻进行数据分析。
基于 IndexR 系统的典型架构示例如下:
1.IndexR 为上层计算引擎提供数据,相当于对 IO 层做了整体的性能加速,提升了系统的分析能力。
2.IndexR 为下层数据存储解决了在线分析和数据调用的问题,同时还能解决实时数据和历史数据的分割问题。
IndexR 能实时拉取 Kafka 的数据流,并打包上传到 HDFS。整个数据层对于计算层是透明的。IndexR 通过结合实时数据和历史数据,保证了数据分析的实时性。
数据存放于 HDFS,不同的分析工具可同时分析同一份数据。
利用 Hadoop、Drill、Spark 等的分布式、高可用、可扩展特点,解决海量数据场景的分析问题。
IndexR 从开源至今,历经不同团队从调研、测试到最后部署生产环境的实践,已获得了国内外数十家团队的认可(如尼尔森、佰安信息等),包括广告、电商、AI 等领域的大型互联网公司和创业团队以及政府、咨询、物流等拥有超大数据集且对数据质量有极高要求的行业。其中:尼尔森(Nielsen-CCData)使用 IndexR 产品服务全面支撑了其六大产品线的核心业务,应对海量数据的在线监测、治理、分析以及复杂多变的智能化数据产品输出,专注于全媒体与受众研究业务。佰安信息则使用 IndexR 产品服务进行公共信息的明细查询与统计分析,单表数据量近 2 千亿,每日入库近 4 亿条数据。
下面列举几种常见的使用场景:
替换 Parquet 等存储格式:利用 IndexR 的性能和索引优势,加速查询系统。
替换 Druid 等分布式系统:利用 IndexR 实现实时入库,进行多维数据分析。
替换 MySQL、Oracle 等业务数据库,或 ES、Solr 等搜索引擎:把统计分析工作移交到 IndexR 系统,通过模块分离,提高服务能力。
结合其他开源工具(如 Drill,搭建 OLAP 查询系统):IndexR 基于 Hadoop 生态的特点及支持实时入库、高效查询的优势,能够满足当前或未来对于 OLAP 系统的实时分析海量数据、线性扩展、高可用、多功能、业务灵活等多种需求。数据分析不再被纯预计算的局限性所困扰,且在线分析和离线分析可以使用同一份数据,提高了数据利用率并降低了成本。
作为数据仓库的存储格式:利用 IndexR 存放海量历史数据,同时支持海量数据的实时入库。数据使用方式包括明细查询、在原始数据上做分析查询和定期的预处理脚本。
IndexR 具有六大特性:自带索引、灵活性强、实时性高、速度快、省资源、预聚合。
IndexR 包含三层索引,即粗糙集索引(Rough Set Index)、内索引(Inner Index)和可选的外索引(Outer Index)。
目前的 On Hadoop 存储格式如 ORC、Parquet 等都没有真正的索引,只靠分区和利用一些简单的统计特征如最大最小值等大概满足离线分析的需求。在服务在线业务时 On Hadoop 就显得非常力不从心,需要从磁盘中读取大量无用数据。事实上并不是每次查询都需要获取全部数据,特别是 Ad-hoc 类型的查询。而 IndexR 通过多层索引的设计,不仅极大地提高了 IO 效率,只读取部分有效数据,而且把索引的额外开销降到了最低。
一般传统数据库系统的索引设计是通过索引直接命中具体的数据行,但这种方式只适用于 OLTP 场景,即每次查询只获取少量数据,在 OLAP 场景下并不适合。OLAP 场景下每次查询可能要涉及上万甚至上亿行数据,这样的索引设计开销极大(内存、IO、CPU),并会带来磁盘随机读的问题,很多时候还不如直接对原始数据进行扫描更加快速。
IndexR 的索引设计是分层的。打个比喻,如果要定位全国具体的某个街道,传统的方式是把“省市 - 街道”组成一个索引,而 IndexR 是通过把“街道”映射在相应的“省市”的集合(Pack)里,然后再在具体的集合了里做细致的索引。
Rough Set Index - 粗糙集索引的工作方式类似于熟知的 Bloom Filter,它的特点是成本极低,速度超快,几乎不会对查询有性能损耗。IndexR 数据格式通过粗糙集索引快速定位区域块,所以并不依赖分区。
Outer Index - 外索引目前使用倒排索引和 Bitmap,它的优点是支持丰富的过滤条件,并且非常适合做交、并运算。IndexR 对倒排索引的使用方式做了优化,避免了在 Scan 场景下大量随机读或者巨大内存使用的问题,并且把 Bitmap 的 merge 操作做了加速处理,不会出现范围条件(大于、小于)下的大量 merge 问题。
Inner Index - 内索引由具体的 Pack 内部编码特性决定,支持在压缩状态下对数据进行过滤。具体查询时 IndexR 先进行粗糙集索引过滤,再对剩下的数据集进行倒排索引过滤,然后把命中的 Pack 直接加载入内存,对其进行高效的细致查询。这种方式解决了分布式架构、海量数据场景下索引困难的问题,避免了随机读问题,不管是在需要大范围扫描还是少量数据查询都更加高效。
目前的 Hadoop 生态对于实时的数据分析还是比较困难。Storm、Spark Streaming 等系统属于对数据进行预计算,在业务频繁改动或需要对原始数据进行启发式分析(Ad-hoc)的情况下没法满足需求。而 Druid、Kudu 等系统虽然支持实时写入,但其体系自成,在实际运用中常会出现部署、整合甚至性能方面的问题。
IndexR 支持实时数据写入,比如从 Kafka 导入,并且数据到达系统之后可以立刻被分析。它与 Hadoop 生态的无缝整合也使得它在业务设计上非常灵活。目前 IndexR 单表单节点入库速度每秒超过 3w 条数据,入库速度会随着节点数量呈线性增加,每个表使用单独线程,表间互不影响。此外,对于 OLAP 型的多维分析场景,IndexR 还支持实时、离线预聚合处理,将指标基于维度进行预先组织,大大减少了数据量,数据分析更加快速。
IndexR 使用深度优化的编码方式,大大加快了数据解析,甚至可以媲美一些内存数据库。它的数据组织形式根据向量化执行的特点定制,把全部数据存放于堆外内存,并且优化到各个 byte 的组织方式,把 JVM 的 GC 和虚函数开销降到最低。
IndexR 是基于 Hadoop 的数据格式,意味着文件存放于 HDFS,这样可以非常方便地利用 HDFS 本身的高可用特性保证数据安全,并且可以方便的使用 Hadoop 生态上的所有分析工具。IndexR 对基于 HDFS 的文件读取做了大量的优化,把计算尽量分发到离数据最近的本地节点,HDFS 层的开销基本被剔除,与直接读取本地数据无异。
以下是使用 TPC-H 数据集,IndexR 与 Parquet 格式在相同的 Drill 集群上做的一个性能对比。
最大表 lineitem 数据总量 6 亿,5 个节点,节点配置 [Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz] x 2, RAM 64G(实际使用约 12G), HDD STATA with 7200RPM。
IndexR 与 Parquet 的 Hive 表 schema 都没有设置 TBLPROPERTIES,使用默认参数。
柱状图:
柱状图:
为了避免 Java 中对象和抽象的开销,IndexR 的代码大量使用了 Code C In Java 的编程风格(调侃),通过内存结构而非接口进行解耦。紧凑的内存结构减少了寻址开销,且非常利于优化 JVM 的运行。IndexR 在保证了高性能、有效索引的基础上极大地节省了内存,与使用 Parquet 格式查询时的内存使用量差不多,不会出现像 CarbonData 需要配置超大内存的情况。但是为什么不直接使用 C 或者 C++ 呢?因为目前 Hadoop 生态最适合的开发语言还是基于 JVM,JVM 语言可与其他系统无缝集成,在工具链支持方面也是最全面的。
IndexR 通过与 Hadoop 生态的深度整合,适合用来搭建海量数据场景下的数据仓库。
IndexR 与行业通用方案对比:
Parquet,ORC - 他们与 IndexR 一样都属于存储格式,功能上比较类似。目前 IndexR 还不支持较复杂的数据格式,但额外支持索引、实时导入、预聚合等特性。
CarbonData - CarbonData 也是用于大数据分析场景的数据格式,并且支持索引,官方文档称适用于大量数据扫描和少量数据查询的场景,与 IndexR 在存储格式上的定位非常相近。同样 IndexR 还额外支持实时导入、预聚合等特性。笔者尝试使用 CarbonData 与 IndexR 在相同的 Hadoop 集群上做性能对比,发现 CarbonData 的表现不稳定,特别是 Q9 和 Q10,以下是测试结果,欢迎同行讨论。
使用以上测试相同集群,CarbonData 1.1.0, Hadoop 2.5.2, Spark 2.1.0. Spark 启动参数:bin/spark-submit --class org.apache.carbondata.spark.thriftserver.CarbonThriftServer --num-executors 5 --executor-cores 10 --executor-memory 31G carbonlib/carbondata_2.11-1.1.0-shade-hadoop2.2.0.jar hdfs://rttest/user/hive/warehouse/carbon.storeCarbonData 表 schema 没有设置 TBLPROPERTIES,使用默认参数。
Druid - Druid 属于时间序列数据库,支持流式导入、实时预聚合,适用于 OLAP 场景。从架构上,IndexR 基于 Hadoop,上层使用第三方查询引擎,而 Druid 只是把文件备份到 Hadoop,数据读取并不经过 Hadoop。IndexR 系统支持完整的 SQL,而 Druid 使用自定义 JSON 查询语句,不支持 SQL(目前有实验 feature,但是支持非常有限),无法做 JOIN、UNION 等操作。此外,IndexR 还额外支持表结构更新,且过期数据不会丢弃,在运维方面也更加简单。
Kudu、ClickHouse - IndexR 和他们都可以用来做 OLAP 分析。Kudu 支持 OLTP 的大部分操作,包括数据插入、更新、删除等;IndexR 和 ClickHouse 数据只能使用 append 的模式,并且不支持在线更新,目前只能使用分区管理。Kudu 和 ClickHouse 都独立于 Hadoop 生态之外。
IndexR 项目是由舜飞科技开发的,最早是为了解决公司内部程序化广告业务的大数据实时分析需求。目前,舜飞科技使用 IndexR 支撑了每日近千亿数据的实时入库及在线多维分析系统。IndexR 致力于成为 Hadoop 生态下快速分析查询的标准存储格式。希望它可以获得业界更多的关注和使用及社区的更多积极参与。
作者介绍
韦万(微信号:xilyflow),舜飞科技大数据平台负责人。擅长大数据架构、分析型数据库、OLAP 领域。历经舜飞科技数据中心从 0 到每日近 100TB 增量规模的发展,并主导了 IndexR 项目的研发。
今日荐文
点击下方图片即可阅读
深度访谈:华为开源数据格式 CarbonData 项目,实现大数据即席查询秒级响应