一、并行数据库的定义和架构特点
在*上,并行数据库被定义为通过并行使用多个CPU和磁盘来将诸如装载数据、建立索引、执行查询等操作并行化以提升性能的数据库系统。其中最重要的关键词是并行。
在组成大规模计算机集群的时候,通常有两种特性要考虑:并行和分布式。并行强调多节点同时执行,共同解决一个大问题,通常在严格的高性能网络环境中,有严格的执行要求和反馈时限。因此,并行和并发大多数时候是矛盾的两面,您不应该指望并行数据库能在极短的时间处理大量的请求,因为它是为了解决大问题而设计的,而不是大量的小问题。
分布式则是另外一个特性,它强调数据或计算分布在不同的节点,并对上提供透明性。它可以是分布在一个广域网上,提供位置透明性,比如CouchDB那样;也可以像Mysql网关那样,提供任务透明性。
因为目的不一样,通常在设计运行在大规模集群的软件的时候,不会同时追求这两者。MPP数据库被设计为最求极致的并行,即使仅查询一条数据的SQL,也会被扔给所有的数据节点来执行;而HDFS则不是这样,它不会要求一个文件块完全分布在所有的数据节点上,并同时提供访问,它只需要将一个文件按照顺序分成几个块分布在数个节点上即可,一个接一个地被访问。因此一个HDFS数据节点失效影响不了全局;但是一个MPP的数据节点失效会影响全局。这是两种特性的典型差别。其它的软件分布在中间,按照应用的需求,或者偏并行一些,或者偏分布式一些。理解了这个“并行”的特点对理解并行数据库的设计非常重要。
通常我们构建一个数据库集群的时候,可以采取Share Nothing、Share Disk和Sharding三种方式,其中前两个都可以视为并行数据库的范畴,其中Share Disk不属于极端的并行;后一个其实是分布式的范畴,它被普遍应用在构建事务处理型系统(OLTP)上,我们在这里不做展开讨论。
Share Nothing因为基本没有“共享”的环节,因此非常适合做“并行”。1983年的Teradata、1984年的DB2就是典型的Share Nothing并行数据库架构。当前典型的MPP数据库,比如Gbase 8a、Vertica、GP、ParAccel仍旧采用这样的架构。
Share Disk因为共享了磁盘,其实不适合做“并行”。因此其传统的产品,比如Oracle、Sybase什么的并行其实不是太好。以前都是通过任务间的并行把负载拉起来,后来任务内读的并行部分解决了,但任务内写的并行仍旧很难,Oracle在保证执行节点之间信息同步的开销很大。
最近几年出现的SQL over Hadoop方案在架构上也可以视为Share Disk,不过这个Disk不是一个集中的磁盘阵列,而是一个分布式的文件系统而已。
如果是SQL over Hadoop的情况下,这个SQL引擎本身又是并行的,而且直接跑在Hadoop集群之上,看起来似乎和典型的MPP架构一样,都是Share Nothing的。但是实际上,还是有很重要的差别。因为HDFS是一个分布式文件系统,因此通常情况下它对SQL引擎(或称为执行引擎、查询引擎)的集群是透明的,SQL引擎的集群既不能控制一个表分散在所有的节点上,也不能控制可能会被同时访问的几个表放在一个节点上以便执行控制在一个节点内的join操作。它唯一能利用的就是HDFS的数据本地性特性,类似Hbase一样,SQL引擎自己写入的数据可以优先写本节点的磁盘。这种透明性使得SQL over Hadoop的方案可扩展性很好,或者说分布式的特性展现得不错。但是并行性能就稍微差一些,这个后面有所分析。
虽然Hadoop被视为处理大数据的首选工具,但不应该忽视并行数据库的作用。eBay、Facebook、Twitter把典型的并行数据库作为它们大数据工具箱中的一种。在中国移动的集中化大数据平台中,因为我们有大量的结构化数据,也有大量的即席查询,因此我们也使用了MPP数据库,目前单个集群最大规模为300节点。
很明显,因为并行数据库的技术特点是为了某类需求设计的,因此它有自己的适用环境。首先因为它采用关系理论,因此它仅适合结构化数据,非结构化或者说某些半结构化数据当然也可以在其中存和取,但是实际上有很多更好的解决方案可以选择。其次还是因为它采用关系理论,关系代数和关系演算是其擅长的,因此它在并行计算,特别是复杂的多表关联、流水线等一系列操作中特别擅长,如果只是存入和取出的话,NoSQL会更加适合。再次,因为并行数据库的SQL语言是一种申明式的语言,甚至当初设计的目的并不是给程序猿使用,而是给业务人员用的,因此在处理日常重复性任务的时候有更好的解决方案,比如MapReduce和Spark。最后一点因为并行数据库需要在数据分布(计算Hash)和存储格式(比如列存、压缩、索引、页面统计信息等)方面进行较多的处理以便为查询进行优化,因此装载数据是比较耗费精力,时间较长的。因此入库后只会被读取少数次的任务最好不要麻烦它来做。
并行数据库目前的主要问题来自于它的设计目的,因为要实现完美的并行,因此它大多被设计为计算和存储紧密耦合,这样计算可以控制每行数据的存储位置和每个数据块的存储格式,这样对大任务提供了很好的性能(类比于“鱼”)。同时也使得系统鲁棒性不高,这体现在一个节点退服后性能下降严重,两个节点退服有全库停止的可能。另外系统扩展性也收到了限制,一是规模不能太大,二是基本需要对等性能的机器,三是重新计算Hash并移动数据是非常麻烦和缓慢的(类比于“熊掌”,目前是鱼与熊掌不可兼得)。
二、并行数据库技术要点分析
并行数据库主要由执行引擎、存储引擎和管理功能模块组成。它们的不同技术风格形成了各个有特色的并行数据库产品。
因为是大规模集群的数据库,所以首要要面对的就是节点的风格。其中最重要的就是主节点,类似HDFS中的NameNode,主节点要承担入口、元数据管理、SQL Parser、生成执行计划和任务调度、管理两阶段提交等功能。目前有两种方式:有专职Master和无专职Master。
从开源的PostgreSQL演变来的并行数据库多为有专职Master的,因为这样代码最易分开,比如GP等。这种架构比较简单,因此数据节点的对等性比较容易维护,不会形成性能短板。它们的Master形成了主备模式,切换的时候影响比较大,而且主节点的动态伸缩也是问题。
从头设计的并行数据库多为无专职Master的,比如Gbase 8a和Vertica。数据节点和Master节点代码部署到一台物理机,被连接上即充当此次连接的Master。其优点是足够的扩展性和更好的高可用,但是缺点在于Master的进程可能拖慢数据节点,形成性能短板。而且Master之间的元数据同步也是一个负担。
两种方式各有优劣,在大规模集群下,无专职Master架构优势更加明显,其向“多Master”架构发展也很容易,比如Gbase8a已经支持这种模式,Vertica在大集群模式下支持这样的部署方式。我认为多Master是未来方向,这样在提供良好的扩展性和高可用的同时,也保持了数据节点的对等性。
在存储引擎中最为关键的就是数据分布。按行进行Hash分布是并行数据库的重要特征。其它数据分布方式无法精确控制数据摆放,也无法提供足够的用于查询优化的存储信息。
就像之前说的那样:这种紧密耦合的非透明的方式带来了巨大的好处(同样分布的表的高效关联),同时也带来了麻烦(扩展性、高可用等)。鱼与熊掌不可兼得。
一些改进的SQL over Hadoop方案借用了这一点,比如HDFS Colocation、Pivotal HAWG、Vertica VIVE等。注意前者和后两者不一样。前者在NameNode中加了一个表用来存储Hash元数据;后两者自己实现Hash表的管理,主要用到的是HDFS的目录功能,利用数据本地性原则来优化。
没有解决Hash分布的解决方案都难以处理多个大表关联(Join)的问题,它们多通过预关联的方式来规避这个问题,形成某种类似OLAP多维立方体的解决方案(比如Google Dremel、Mesa,eBayKylin等);或通过shuffle实现重新分布(比如Hive或者SparkSQL)。
解决了数据分布以后,就要思考计算好Hash后的数据在一个节点中怎么存。通常三种方式:行、列或者行列混合。
它们有各自的适用场景。值得一提的是“仅列存储”与“列存储+针对性优化的执行引擎”有很大差别。如果存储引擎和执行引擎进行了联合的深度优化,那么原则上,如果列已经排序好后重复的行是可以消除的。比如记录“第一行到第五亿行为男”,“第五亿到第十亿行为女”,这样只用两行数据即可,Vertica和Gbase 8a可以做到这点。而仅将列存储作为存储引擎的一种是无法做到这点,只能存储十亿行进行字典压缩后的“男”和“女”。现在几大老牌的数据库提供商还提供行列混合的方案,比如Oracle、IBM和Teradata都提供,不过似乎在生产系统中,很少看到这样的例子出现。
行存储、列存储方式的测试结果显示了不同的存储方式的不同特性,行存装载普遍比列存储快,但是查询起来一般都要慢许多。因此需要根据应用访问的需要来选择存储方式。如果是一次装载、多次查询的分析型应用,基本是选用列存储的方式。
选择了行列存储格式和压缩算法等,接下来就要考虑到底存储到什么“存储系统”上。最早数据库多选用裸设备,因为当时的存储很贵,性能又不行,因此要努力减少哪怕一点点的性能损失。但是在类似X86的开放硬件环境中,这会使得软件很复杂。这种用软件复杂度换取硬件成本的方式随着摩尔定律的不断作用而变得不经济。因此现在数据库大多就直接使用操作系统文件系统,这样屏蔽了很多不同硬件和操作系统的细节问题。
HDFS等分布式文件系统出现后,又多了一种选择。这是一个新的方向,提供了多一些可能。可以有两种使用方式:作为一个本地文件系统看待,或者以外部表的方式,后面有具体的情况分析。
最后要考虑的是硬件问题。目前典型的并行数据库多使用SAS磁盘,而HDFS使用的容量更大、价格更便宜但性能和可靠性稍差的SATA磁盘。使用这种慢速的磁盘是并行数据库目前最大的瓶颈,使得它无法实现效率和可扩展高可用的兼得,也就是鱼与熊掌不可兼得的难题主要来源就在于此。磁盘IO的速度难以匹配摩尔定律要求的速度,但是电子盘和内存是可以的。随着后两者的价格快速下降、性能快速提高,并行数据库可能又将面临一次重大的变革,并解决那个难题。
并行数据库目前主要的数据存储仍然使用磁盘,电子盘和内存盘最多只能作为缓存来使用。我认为接下来的1到2年,我们很快就将面对以SATA接口的SSD替代SAS磁盘的过程。现在一些高端的并行数据库一体机已经可以采用全SSD的配置了。目前的并行数据库几乎不用任何代码的改动,就可以运行在SSD之上。
但是,因为硬件特性的不一样,只有全新设计一个并行数据库系统才能最佳发挥SSD的作用。因为现有的并行数据库系统是为了旋转磁盘的特性设计的,为了将随机的读写转换为顺序的读写,用了非常多复杂的机制和复杂的代码。比如用内存来缓存写入或更新的数据,到达一定的块容量后再顺序写入磁盘,但是这给事务处理带来了麻烦,因此内存是断电后数据无法持久,所以数据还有“活动”和“非活动”之分。当然事务日志也有“活动”和“非活动”之分,为了保证数据和日志的一致性,它们还得互相配合,这样就多了很多代码。如果单个数据或者一小块数据的随机访问速度和顺序访问相当,那么就没有必要这样做,节省下的代码将提高效率、提高系统的稳定性、可用性和扩展性。
我认为未来是内存为王的时代,天下武功为快不破。内存是数据存储的终极目标。目前柏睿Rapids DB和HANA等产品就是将内存作为数据的实际存储地方,SSD只是拿来做快照和日志的存储而已。这种方式,将解决MPP面临的“鱼与熊掌不可兼得”的问题。在短期内,这种方案不能成为所有数据存储的选择,但是我坚信硬件的发展是持续的,用硬件来解决软件的问题是最直接有效的方式。因为内存的易失性,并不能简单的将数据存储从SSD转移到内存中,这将面临一次更多的、更彻底的并行数据库软件平台的重新设计。
存储引擎的关键技术点分析就是这些。接下来分析查询引擎。查询引擎因为它是面向计算的,已经发展得比较充分。典型的MPP和新型的SQL over Hadoop都大量借用了传统数据库的这些功能。比如基于成本的优化器、流水线、多版本的并发管理等。
接下来是高可用。这里的高可用指节点失效的情况下,通过机制(一般是副本)屏蔽对数据库的影响。不包括为了保证数据安全所做的备份。容灾、双活可以视为远端高可用。
不同的数据库有不同的副本策略。比如有的采用数据同步的方式,有的采用同步操作本身;有的几个副本都执行完才算成功,有的完成两个就可以,第三个可以异步完成,异步检查。
不同的数据库有不同的副本分布。比如有的以节点为单元形成副本,有的以进程为单元形成副本从而形成了逻辑节点。逻辑节点的方式比较容易,这样一个物理节点的副本可以分散在数个物理节点之上,出现问题后的负荷也是得到了数个物理节点的分担。
同样,不同的数据的高可用等级是不一样的。有的数据库出现故障以后,应用侧基本没有感知,故障恢复过程中也没有感知。有的数据会阻断当前应用,但是重新连接后马上又可以用了(秒级切换)。有的数据库需要等数据库重启一下以后,副本才生效。在并行数据库技术发展尚不成熟的时候,甚至有在故障情况下或故障恢复过程中不允许写数据,只能读的情况出现。这些在选择内存数据库的过程中都需要了解和测试。
考大家一个问题。如果有一台24个节点的数据库,其中一台节点出现故障,这个时候应该启用副本吧。那么在数据不分布的情况下,这23个节点(带病工作状态)上执行的任务时间相比原来要延长多少?4%、10%还是100%?
答案是取决于系统的负荷和不同的产品,不过有一点可以确定的是,超乎想象。这是一个我们的测试结果。24个节点退服一个的情况下,不同产品的读的性能下降和写的性能下降的情况。
注意这不是满负荷(CPU BOUND或IO BOUND)的情况,这不是一个成比例的下降。100个节点和1000个节点会面临与此类似的情况,不能增加节点来解决这个问题。因此节点的退服影响很大,这和Hadoop非常不一样。具体的原因和解决办法可以参考我之前写的博客。
简单的说产生这个问题的原因就在于Hash分布。Hash分布带来了极致的并行(鱼),同时破坏了存储和执行之间的透明性(熊掌),因此深度的绑定导致出现问题的节点的任务无法分散在所有节点,只能由备机所在的节点承担。
同样影响的是线性扩展性,目前世界上最大的MPP生产集群是300个节点。而且大家都倾向用性能更好的胖节点来减少节点的数目。比如我们的设备就有24个SAS盘位。扩展的时候移动数据也是一个花费很大的开销。
因为并行数据库是大数据基础设施中的一部分,所以与Hadoop的集成就变得很重要。我列举了一些典型的方式。比如作为MR的数据源或者目的地,通过InputFormat\OutputFormat像Hbase那样被MapReduce访问;或者通过连接器实现数据的双向互通;或者并行数据库将HDFS作为一个文件系统,在这种方式下不同的节点的数据写入HDFS的不同目录,在HDFS尽量提供数据本地化放置的时候甚至可以像HBase那样绕过DataNode的进程直接访问操作系统的文件块;以外部表又是另外一种方式,在这种方式下只能通过HDFS的接口来访问数据,没有数据本地化的可能,因为数据不是通过执行引擎写入的,而是本来就是HDFS上,其放置方式执行引擎一点也无法控制。其它的方式还有表函数以及在数据库上提供一个MR框架,现在已经很少使用。
其它的关键技术点也很有意思,这些都很重要,今天时间有限就不一一展开了。
小结一下。目前我们可以看到三类典型的并行数据库架构风格:
最左侧是以Gbase8a、Vertica、GP为代表的典型的MPP数据库。数据采用Hash分片,存储引擎和执行引擎紧密耦合,数据完全的本地化,支持完整的SQL,基于成本进行SQL优化。
最右侧是以Impala为代表的典型的SQL over HDFS。存储引擎HDFS与查询引擎完全透明,数据不是由查询引擎写入的,实际上它们就不叫执行引擎,大多只支持“查询”。因为不能控制存储,所以没有统计信息,大部分只能实现基于规则的SQL优化。
存在一个中间的状态,请允许我用MPP over HDFS来命名它。以GP HAWG和Vertica刚推出的VIVE为代表。虽然它也利用HDFS,但是写入的数据均是通过它自己的存储引擎写入的,因此是要计算Hash的,有自己的文件格式和压缩格式,不同节点的文件写到不同节点的目录中,类似Hbase那样。当然也有完整的统计信息,因此可以实现基于成本的SQL优化。它通过HDFS的本地化机制部分实现了数据本地化。MPP节点(也就是执行节点)出现故障以后可以快速启动一个新的执行节点,因为执行节点并不带数据,当然这个时候要损失掉数据本地化的收益。这种中间方案的性能和扩展性也处于中间。
比如最典型的中间方案就是HAWG。它基本上就是把GP DB的数据存储从本地磁盘的文件系统迁移到HDFS上,使用了一个自己扩展的HDFS接口(gphdfs,Vertica的VIVE使用的是webhdfs的接口)。典型的SQL over HDFS方案比如IBM的BigSQL。
典型的MPP性能肯定比中间方案的MPP over HDFS高。Vertica自己的一个测试,大概是高一倍左右。我问过GP的测试结果与这个类似。
三、并行数据库未来展望
在我的实践中,我感受到了云计算给IT带来的颠覆,虽然云计算热炒已经过了,但是它已经润物细无声地改变了业态。我认为数据库也是这样,以后以云的方式提供的数据库会越来越多。无论是企业内部的私有云还是对外的公有云。比如AWS RedShift和Openstack Trove (DBaaS)。这给数据库软件带来的变化是它需要支持越来越大的集群,技术难度加大但经济性更好。这也要求要具备更好的管控能力。数据库软件需要越来越为大规模集群设计。
因此我认为,在上述趋势的发展之下。并行数据库的软件模块或者叫组件的分工会越来越细化。以前只有主节点和数据节点两类。有的数据库找一些空的数据节点来作为装载节点。那么未来接入节点、协调节点、元数据节点、日志节点、安全节点、SQL解析和优化节点、数据装载和导出节点、数据节点可能会被单独分析出来(数据节点的对等性必须得到保护)。并且这些组件的实例均需要支持通过软件的方式灵活配置数量等,而不是写到代码之中。在架构设计之初就考虑并行、负载分担和可扩展等。组件之间通过Zookeeper之类的方式进行协调,实现高可用,松耦合,屏蔽内部细节。Gbase 8a就采用了Zookeeper协调的设计。
在节点分工完成后,更加可以通过硬件的方式进行针对性的优化。比如像NameNode那样把元数据全部放入内存提供更好的性能。另外一些工作,甚至可以放到其它更加便宜,更加适合的大数据基础平台,比如MR和Spark之上进行运算。
存储硬件的发展趋势以及对数据库软件的影响之前已经分析了,计算的硬件后续可能会随着分工的细化而并不采用一种。比如ARM也许适合某些计算要求不高的节点。
更加重要的是网络,存储的瓶颈一旦通过电子盘和内存的方式解决,网络就变得很为关键。虽然典型的MPP架构对网络通常要求不高,但是一些特殊的场景,例如装载和非分布键查询。因此基于Infiniband的RDMA变得很有必要。
之前已经反复提到一些已经发生或我认为即将发生的事情,都有一个原则。因为硬件性价比提升很快,不要用提升软件的复杂度的方法去省硬件。KISS法则提供了更好的性能、扩展性和高可用。另外,因为硬件环境真的是很复杂,因此如果不采用私有云或者公有云的话,那么一体机是对小规模购买者的一个好选择。
这是我对新型并行数据库的一个构想。
它通过快速的RAM实现计算和存储分离和透明(类似Hadoop)。因此具有高扩展、高可用的特性。保留了精确的数据划分(Hash)以实现高效的关系型操作,特别是多表JOIN比MR高效。这个时候是鱼有了,而且还是好的鱼。
它的多个数据分区承载于数据节点上(类似region之于regionserver)。数据分区拥有一定的副本。通过一个由SSD实现的网络服务来快速保存快照和日志,以便所有副本失效后重建(数据分区足够小,分钟级载入)。这个时候熊掌有了,虽然不能做到按比例的性能下降,但是至少把带病工作的时间缩小到了分钟级别。
另外由于只需要CPU和内存,数据节点可以软件的形式运行在VM、LXC上,可以通过Openstack、Docker、YARN或mesos进行分配和管理。这是另外的一个收益,这样并行数据库不需要独立的物理机集群了。完全可以构建在IaaS之上。
展望企业级大数据平台的发展,虽然我们现在已经很好解决了软件定义的计算,使得计算框架可以构建在计算资源管理之上。但是并行数据库仍然要自己管理存储,因此存储无法打通。按照上述的设想,也许我们可以把存储完全打通,实现完美的软件定义存储,并构建在存储资源管理之上。使得企业级大数据平台架构更加简洁。解决混搭架构麻烦的是软件定义的架构。
小结一下今天的分享的主要内容:
1、如有您有大量的结构化数据,并行数据库将是您大数据工作箱中不可或缺的部分。并行数据库最好能与其它大数据工具统一进行管理,例如安装、监控、运维、资源池申请与分配等。
2、无论在公有云还是私有云,并行数据库可能会发展得越来越大,专业性更强,经济上的考虑也将变得不一样。
3、天下武功,唯快不破。随着趋势的发展,内存可能会成为数据存取的主要发生地,将有效解决当前计算和存储紧密耦合的并行数据库难题。
4、软件定义的架构是未来趋势。从设计上必须考虑灵活地配置各个组件的位置和数量,任何环节皆可以并行,各个组件间通过zookeeper之类软件实现高可用和松耦合。
这是我作为一个并行数据库使用者的一些经验和体会,希望能对大家选择和使用并行数据库有所帮助。我作为使用者对于其中很多技术细节专研并不深刻,如有不正确的地方请帮我指正,期望能有更多的机会跟大家进行交流和学习。下面是我的联系方式。谢谢大家的聆听。