文/温国兵

0x00 背景


A 业务日增 1500W 数据,采用 MySQL 分区存储。该分区表按照时间分区,每天一个分区。随着时间的推移,单表数据越来越多,占用空间越来越大,由此带来如下的不便:第一,单机磁盘容量有限,需要定期清理历史数据;第二,MySQL 对子查询、复杂查询支持不友好,在庞大的数据量下性能急剧下降,导致前端报表得出结果延时。为了永久存储数据,并且提升查询性能,便有了如下的技术方案选型。

0x01 综述


目前的大数据方案纷繁复杂,找到合适的不是易事。我们调研了如下产品:Infobright、InfiniDB、Greenplum、Citus、Presto、Impala、ScaleDB、MemSQL 和 Crate。其中测试了如下产品:Greenplum、MemSQL、Crate。

本文试着用笔者的理解对比如下所述的产品,避免大段引用,否则跟维基百科无异。

0x02 Infobright 和 InfiniDB


Infobright 和 InfiniDB 都属于列式存储。Infobright 基于 MySQL,底层采用了一个新的存储引擎:Brighthouse。从 MySQL 迁移到 Infobright,改造成本不会特别大。Infobright 提供列式存储,无需创建索引和分区。Infobright 最大的两个特性,一个是查询性能高,基本上可以带来数倍的查询性能提升;另一个是超高的压缩比,可以节省磁盘空间。但是,社区版只能使用 LOAD DATA 的模式导入数据,不支持 DML。更为要命的是,Infobright 不支持多核 CPU,这就意味着它不能做并发查询,也会带来性能瓶颈。另外,Infobright 只支持单机部署,高可用、横向扩展都是很头疼的问题。InfiniDB 和 Infobright 类似,提供 MySQL 接口访问,无需创建索引和分区。但 InfiniDB 文档不完善,应用案例较少。

0x03 Citus


Citus 基于 PostrgeSQL,支持 SQL,同时支持行式存储和列式存储,但国内应用较少,并且社区版限制太多,基本没法用。

0x04 Presto 和 Impala


Presto 是一个分布式 SQL 查询引擎,适用于交互式分析查询,但 Presto 不支持 UDF,对表的连接以及 GROUP BY 操作有严格的大小限制,并且扩展能力有限,并不适合我们的应用场景。

Impala 支持 SQL 查询,亮点在于可以和 Hive 结合使用,但它不支持 UDF,不支持 Text 域的全文搜索,对内存要求高,没有提供高可用和横向扩展能力,同样不适合我们的应用场景。

0x05 Greenplum


Greenplum 是我们测试的第一个产品。Greenplum 整合了 SQL 和 MapReduce 功能,利用 MPP 架构提高并行能力。Greenplum 基于 PostgreSQL 开发,支持行列混合存储,支持在线扩展。Greenplum 在大数据量在节点间重分布时,容易导致性能瓶颈,这是提供集群特性的产品普遍存在的问题。比如 Riak 集群,当对 Riak 集群进行扩容或者下线节点,业务会有波动。

MPP(大规模并行处理) 是 Greenplum 数据库最突出的特色。无共享架构下,数据可以分布在很多节点上进行并行处理,可以做到线性扩展。在分布式数据库中,性能好坏的最重要因素是数据分布是否均匀。数据分布是否均匀,这也是我们经常说的数据是否存在倾斜,如果存在,会存在短板效应,对性能造成很大的影响。Greenplum 支持多种数据分布的策略,默认使用主键或者第一个字段进行哈希分布,还支持随机分布。灵活的分布策略,尽可能地减少数据倾斜发生的可能性。

Greenplum 性能卓越的另一个特性是 并行查询计划和执行。主节点(Master)上的调度器(QD)会下发查询任务到每个数据节点,数据节点收到任务后(查询计划树),创建工作进程(QE)执行任务。如果需要跨节点数据交换,则数据节点上会创建多个工作进程协调执行任务。不同节点上执行同一任务(查询计划中的切片)的进程组成一个团伙。数据从下往上流动,最终 Master 返回给客户端。简单地讲,Greenplum 将数据处理的逻辑交给数据节点,数据节点处理完成之后,汇总之后通过主节点返回给客户端。

之前提到了 Greenplum 支持行列混合存储,实际上这个特性被称为 多态存储,支持行存储、列存储、外部表(比如 HDFS 中的数据)。灵活的存储模式,让 Greenplum 可以根据数据热度、访问模式决定使用对应的存储模式。

另外,大规模并行数据加载 也是 Greenplum 的特性之一。

真实的测试过程中,Greenplum 表现并不理想,和 MySQL 对比,查询效率差了两个数量级。

为此,我们做了查询效率低效的分析,如下:

  • 查询期间 Segment 节点 CPU 平均使用率峰值 14.67%,IO until 100%,内存使用率峰值 3.05%,网络流量峰值 0.03 Mbit/s,问题在于单机 IO 上;
  • 导入数据时间间隔为 4 月 1 号到 4 月 25 号,而查询时间间隔同样为为 4 月 1 号到 4 月 25 号,手动做了分区消除;
  • 分布键分布数据集中在单机,无法发挥 Greenplum 性能。

于是,我们放弃了 Greenplum 方案,原因如下:

  • 导入数据慢;
  • 查询执行效率低;
  • 机器成本高,部署维护较复杂。

The Seine at lavacourt

© Claude Monet/The Seine at lavacourt, Oil on canvas, 1880/Saatchi Gallery

0x06 MemSQL


MemSQL 是一个内存数据库,兼容 MySQL。MemSQL 支持并行 GROUP BY,这个特性可以说是大数据方案的一大福音。MemSQL 不进行数据压缩,这会导致存放在内存中的数据很有限。真实的测试过程中,3 台 64G 的机器,导入上亿条数据就提示内存不足。MemSQL 提供开发版、全功能试用版和付费版,这也是 MemSQL 得不到广泛应用的原因之一。

真实测试过程中,MemSQL 单次查询和 MySQL 接近,但略高于 MySQL。查询效率低效原因,初步分析是因为 COLUMNSTORE 索引和普通索引不能共存,导致部分查询无法用到正确的索引。

海量数据完全存放在内存,这在设计上就是不合理的。假如有这样的折中方案,热度数据存放在内存,历史数据存放在磁盘,再好不过。可惜的是,MemSQL 并没有提供这样的支持。

0x07 Crate


Crate,基于 ElasticSearch 构建的开源大数据解决方案,它封装了 SQL 接口。Crate 目前开源,社区活跃,产品尚未完全成熟,还有很好的发展空间,当前版本 0.56。

在真实的测试过程中,我们对比了 SAS、SSD 下的 Crate 和 MySQL 的性能差异,Crate 整体表现良好,平均比 MySQL 快了一个数量级。Crate 还支持在线横向扩展、支持高可用。

最终初步确定选用 Crate 方案进行试点,原因如下:

  • 支持 SQL,查询性能高;
  • 继承 ElasticSearch 的优良特性:全文索引;
  • 部署简单,维护便捷;
  • Web 界面访问,可以查看集群整体健康及负载状况、Crate 中所有 Table 及 Schema 的情况、Crate 集群的节点列表及每个节点的健康状况;
  • 支持 Sqoop 导入数据;
  • 支持横向扩展;
  • 支持高可用。

不过,Crate 本身存在一些缺陷,比如 SQL 和函数支持不够丰富、数据重现分布会触发 GC。Crate 社区活跃,新功能不断完善,相信这会是一个比较完善的产品。

0x08 小结


确定一个方案是否可行,有很多维度,比如:读写性能、数据可用性、改造成本、场景匹配度、机器成本、运维成本、系统容错性、高可用能力、横向扩展能力等等。重要的一点是,给出的测试报告要用数据说服别人,其中测试的维度设计就是需要下功夫的地方。

由于应用场景复杂多变,很难找到一个通用的解决方案。某一个解决方案只能无限趋近特定的需求,某些功能很有可能需要定制。也就是说,一个大数据团队的研发能力也就决定了对业务需求的掌控能力。

–EOF–

版权声明:自由转载-非商用-非衍生-保持署名(创意共享4.0许可证)