ColumnStore在大数据中的应用实践

随着企业数据量急速增长,为了满足业务需求,大数据统计早已成为迫切的需求。在引擎排行榜上MySQL已经长期处于第二,但大数据统计并没有明显突破。

MySQL解决方案包括Infobright、Greenplum、Spark等,与之更为密切的是Infobright,但是多表连接场景下,性能会大幅下降(且特殊功能需要付费)。而ColumnStore的出现则弥补了此处的空缺,是MariaDB在OLAP领域解决方案的突破。ColumnStore是InfiniDB与MariaDB 10.1的结合体,目前已经GA,拥有计算能力及存储线性扩展、高压缩比、MySQL协议兼容、自动水平和垂直分区、扩展窗口函数等特点。如果你正在寻找性能及存储线性扩展、学习成本低、易维护且兼具数据安全及审计的数据仓库解决方案,相信ColumnStore会给你带来不小的惊喜。

图1是来自官方的ColumnStore结构图。

ColumnStore在大数据中的应用实践

图1 ColumnStore架构图

UM:MariaDB SQL FRONT End(User Module);

PM:Distributed Query Engine(Performance Module);

整体架构分为计算层和存储层,都是可扩展的,计算层需由以下几项主要进程构成:

  • MariaDB(mysqld):收集用户请求的一个SQL入口,存储元数据信息;
  • Execution Manager:解析语法树,转化成任务列表(JOB LIST),包括优化、取数据、(HASH)JOIN、汇总、分组;
  • DMLProc/DDLProc:将DML/DDL语句发送到指定的PM执行;
  • Performance Module:接受Execution Manager发送过来的任务调度,分布式扫描,(HASH)JOIN与汇总。

由此,我们能清晰地理解整个处理流程:MariaDB收到用户的SQL请求后,通过执行管理器将SQL转化为任务列表,再由DMLProc/DDLProc发送任务给PM,最后PM将结果返回给UM进行汇总,返回结果给客户端。

优势

存储、性能、兼容、扩展

为了解决在大数据统计性能上的问题,对比了Infobright和ColumnStore两种解决方案,最终选取了ColumnStore,对比如下:

表1 数仓方案对比表

ColumnStore在大数据中的应用实践

  1. 对于存储而言,InnoDB本身的压缩率并不高,有1倍左右。相比之下,Infobright的压缩率相对最高,有20倍之多;而ColumnStore则比较适中,为5倍左右。如果为了追求高压缩比的历史数据存档,很明显使用Infobright社区版是很好的方案。

  2. InnoDB自身的扩展性并不高,需要外部中间件来实现分库分表,因此给予扩展性低的评价;Infobright也可以部署集群,因此扩展性给予高评分;同样ColumnStore也是易于扩展的分布式方案。

  3. 在性能方面,InnoDB的OLTP性能远高于后两者,在数据仓库中提供在线服务,可以考虑用InnoDB来存储,但统计性能则相差甚远;由于Infobright中存在Knowledge Grid(知识网格),又使用了列式存储来压缩数据,在数据量超过内存容量的情况下,对单列的统计表现卓越,100倍性能提升就成了极轻松的事,但如果统计字段增加或多表查询,性能也就极速下降;ColumnStore不仅拥有单列高速统计的优势,而且在多表连接的场景下也表现不俗,当然字段越多性能同样会下降,但下降后的速度仍可以接受。

  4. Infobright的社区版不支持DML,因此语法兼容性存在很大问题,对查询的支持尚佳;ColumnStore本身开源,但语法也略有不同,例如多表连接时,不能对同一个表进行多次连接,分组查询字段(SELECT COLUMN LIST)必须要在分组列表(GROUP BY LIST)中。

窗口函数

窗口函数(Windowing Function)在数仓的场景下非常有用,当分析App中的行为路径时,很简单地就能把用户的使用路径串联起来。

性能优势

想了解ColumnStore的性能表现,请移步 Percona的性能测试对比(https://www.percona.com/blog/2010/01/07/star-schema-bechmark-infobright-infinidb-and-luciddb/

限制

数据类型不一致

InnoDB支持的数据类型有:

  • TINYINT/SMALLINT/MEDIUMINT/INT或INTEGER/BIGINT
  • FLOAT/DOUBLE/DECIMAL
  • CHAR/VARCHAR/TINYBLOB/BLOB/MEDIUMBLOB/LOGNGBLOB/TINYTEXT/TEXT/MEDIUMTEXT/LONGTEXT/VARBINARY/BINARY
  • DATE/TIME/YEAR/DATETIME/TIMESTAMP
  • ENUM/SET

ColumnStore支持的数据类型为:

  • TINYINT/SMALLINT/INT或INTERGER/BIGINT
  • FLOAT/DOUBLE/DEAL/DECIMAL或NUMBER
  • CHAR/VARCHAR
  • DATE/DATETIME

通过对比可知,ColumnStore不支持的数据类型有:MEDIUMINT、BLOB、TEXT、BINARY、TIMESTAMP/TIME/YEAR、ENUM/SET

不支持的数据类型,我们通过类型转换来保证兼容,规则如表2所示:

表2 类型转换对照表

ColumnStore在大数据中的应用实践

字符类型长度限制

ColumnStore的字符串类型字段长度最长为8000,否则报语法错误。也许在ColumnStore工程师的眼中,过长的字符不具有很好的分析意义,加之如果文本过大,应该不利于列式存储发挥压缩统计的优势,这可能正是8000长度限制的由来(纯属个人猜测)。大多数场景下,需要把过长的文本截断以保证系统之间的兼容性。如果业务对此类文本内容依赖较强,建议在原数据中拆分为多行处理。

表总字段总长度限制

对于长度的限制,不仅字段的长度有限制,一个表中多个字段长度总和也有限制。虽然碰见的情况比较少,但也不容忽视。

中文字符长度的限制

MySQL的老司机都知道,MySQL在早期版本里字符串长度的定义为字节长度(一个汉字占用三个字节),后面的版本才定义为字符数(一个汉字占用一个长度),但ColumnStore或者InfiniDB都占用三个字节。如果你的中文字符串莫名其妙地被截断了,很可能是出现了这个问题,即VARCHAR(3)类型字段只能存储一个汉字。

窗口函数的视图

如果SQL中包含了窗口函数,那么在创建视图时会报错。

建表限制

不支持primary key/auto_increment/index等DDL语句,表名不支持关键字。

建议

由于碰到了ColumnStore如此多的限制,使用者很容易出错,建议自己写脚本将建表、数据抽取做到自动化,省时省力,其中可能包含的功能建议:

  • 创建表结构
  • 字段数据类型转换
  • 字段长度转换
  • 数据库/表名称变更:

有了以上四点,就不用人工审核每个字段应该用什么类型和多大的长度,如果表名字还是个关键字(那就更糟糕了),只有把名字改掉了,比如可以加个前缀。

  • 多线程数据抽取
  • 数据增量抽取

当数据量到一定程度,从原数据库抽取数据会成为瓶颈,此时如果能多线程抽取,那可谓如虎添翼。之前等2个小时才能抽取完的任务,现在10分钟就搞定。如果再加上增量抽取,那便可以再节省5分钟。

  • 字段忽略

前面讲过,ColumnStore的字段长度和表总宽度有限制,但我们不能控制业务表设计,因而只能适应,所以如果有了字段忽略的功能,把没有分析统计意义的字段直接忽略掉,数据就可以很愉快地抽取起来了。

参考

窗口函数

https://www.percona.com/live/mysql-conference-2014/sessions/windowing-functions-mysql-infinidb

性能对比

https://www.percona.com/blog/2010/01/07/star-schema-bechmark-infobright-infinidb-and-luciddb/

https://www.percona.com/blog/2017/03/17/column-store-database-benchmarks-mariadb-columnstore-vs-clickhouse-vs-apache-spark/

结构简介

http://mt.sohu.com/20161216/n476022933.shtml


作者:陈兴隆,从事MySQL DBA超过5年,曾使用MariaDB ColumnStore构建数据仓库,精通复杂SQL优化,熟悉Python和Shell脚本开发,曾就职于凡普金科集团/爱前进,担任DBA Team Leader,致力于数据仓库解决方案的架构设计、优化、业务支持。
责编:仲培艺([email protected]
本文为《程序员》原创文章,未经允许不得转载,更多精彩文章请订阅2017年《程序员》