2017-04-01 postgres用户会 欢迎大家踊跃投稿,投稿邮箱:[email protected] 联想数据库团队(卢俊峰、刘虎城、王凯) 1背景介绍身处大数据时代,在数据库领域,我们要分析处理的数据越来越多,我们分析处理数据的速度也要越来越快,但是传统数据库基于磁盘的计算模型,已经难以满足我们的需求。幸运的是随着硬件的发展,内存设备的性能在不断提高,而价格却在不断下降。内存计算技术将带着我们“飞”起来! 内存计算(In-Memory Computing),实质上是CPU直接从内存而非硬盘上读取数据,并对数据进行计算、分析。在数据库上引入内存计算技术,意味着去除磁盘IO的消耗,利用内存随机访问的特性可以制定更高效的算法等等。这都极大的提高数据的处理速度。 目前很多商业数据库已经拥有了内存计算功能,如SAP HANA、DB2 BLU、Oracle 12C、SQL Server 2014。但是商业数据库的价格毕竟不菲,在开源产品飞速发展的今天,利用开源的内存计算产品是一个好主意。 图1数据库产品使用排名 从图1我们可以看到,目前开源的数据库使用比较多的是MySQL、Redis、PostgreSQL等等。Redis、MemCached是KV类型的内存数据库,不支持关系模型,仅作为关系型数据库的缓存。MySQL支持In-Memory引擎,但是不支持数据的持久化,不支持列存储。基于这种情况,我们打算开发一套基于开源关系型数据库之上的内存计算引擎,实现支持内存计算,数据持久化,并行计算等特性。 2为什么选择PostgreSQL虽然决定自开发,但是站在巨人的肩膀上是一个好主意!我们决定基于PostgreSQL开发一个内存计算的引擎,具体理由如下: 1、PostgreSQL的许可证非常开放(BSD协议),简单来说,你可以忘记许可证的问题。 2、PostgreSQL提供完善的外部表(FDW:Foreign Data Wrapper)扩展开发机制,可以很容易的开发满足自身需求的插件。 3、PostgreSQL的自身稳定性很高,基于PostgreSQL开发产品,不用担心稳定性的问题。 4、在开源社区上有很多PostgreSQL的扩展插件,可以借鉴。 5、可以随着PostgreSQL的社区版本进行迭代。 6、由于PostgreSQL的学院派风格。PostgreSQL的代码质量很高,便于阅读学习。 3内存计算引擎的设计思路数据需要存储在内存上,由于PostgreSQL提供了外部表(FDW)概念,可以通过API来对数据进行管理,普通思维是外部表对应的是远程数据库或者其他数据来源,但是我们提出一个概念是将这个FDW对应成内存,这样通过开发扩展插件来实现,不影响PostgreSQL升级带来的迭代问题,也不需要修改内核源码。数据常驻内存,只是简单的解决了数据库IO的问题,只能节省IO的时间,并不能带来计算上质的飞跃,我们测试过,只是将数据Cache到内存中,性能只有1-2倍的提升。如果说设计好存储,利用列式存储将数据分条带分块,通过多线程对数据进行计算,每个线程互不干扰的扫描并计算所分配的条带,这样对内存计算来说能够达到质的飞跃,这也是所有常见数据库所追求的。 3.1外部表(FDW)图2外部表透明访问 外部表:在PostgreSQL内部提供一种表类型,能够提供用户访问外部源数据的一种方式,这是PostgreSQL作为学院派设计比较优美的地方,努力打造成世界的中心,提供给开发人员遐想的空间。 3.2列式存储如图3所示,将一张表进行横向切割产生了stripe,stripe是由多个块数组构成,blockArray是多列的block数据,block是由单列的多个行数据组成,在对数据进行索引时,只需要通过stripeNum、blockArrayNum、blockRowNum能索引到行,这样组成了RowID,。 图3内存列式存储 注:blockArrayNum:DEFAULT is 15 blockRowNum:DEFAULT is 10000 RowID = stripeNum blockNum blockRowNum(“ ”号是拼接) 对字符串存储使用了Hash字典表,字符串存储过程中会在Hash表中对应一个8字节的MapCode,在进行字符串比较过滤或者对字符串进行Join计算时,只需要对MapCode值进行比较或者对MapCode值进行排序而不是对字符串进行比较或者排序,这样不仅带来了效率上的提升,而且还节省了空间。在存储中采用分条带分块的概念,这样的存储模型为多线程计算做好了完美铺垫。 3.3内存计算在对内存计算分析之前需要提出一个概念,对数据列单个的取出或者两个列的取出都称之为序列(Time Series),序列是自定义的一种类型,我们打造是所有类型皆序列,如下面的例子:
|
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|