Greenplum在企业生产中的最佳实践(上)

本文章转自Pivotal公众号,在此感谢任振中和Pivotal公司的分享,希望对更多的朋友有帮助~

一、GP搭建过程当中硬件的选择和部署建议


GP是一个分布式X86架构,是把多台X86服务器组合成一起做一个大的集群。相比传统单机版的Oracle和MySQL,它的特点是使用比较多的服务器做海量数据处理。

一般在企业客户中,把X86服务器采集过来后会做上机安装,如果企业使用的集群规模比较大,比如国内客户最大的有将近128个节点,数据量有1PB。在部署的时候,X86的服务器会非常多,有超过100台的服务器。为了保证它整个集群的高可用、性能,在部署的时候一般是需要跨多个机柜。

1.服务器部署

(双机柜为一组的部署方式)
对GP来说建议在部署的时候,把服务器放在多个机柜上面,如果企业客户机器非常多,往往是以两个机柜为一组。

对于X86服务器上架之后,接下来就要把X86服务器组网。对于目前市面上看到的2U的服务器,在一个机架里一般都会部署两个万兆交换机。对于单台服务器来说,一块网卡网口出来都会接入相应的交换机里面,那么在主机X86服务器上一般会使用moved4,也就是双active的方式做绑定。当任意的网络故障,就是网口出现故障或者交换机出现故障的时候,都不会对集群的可用性造成影响。

另外,当集群规模比较大的时候,在接入组交换机端口可能是有限的,会把接入层的交换机接入到汇聚层,在汇聚层交换机接入的方式和底下的接入方式是比较像的。在接入层交换机上会分出两个口,分别接入到上层的汇聚层交换机,汇聚层交换机之间也会采用跨设备链路聚合这种方式做绑定。这样就保证了性能和可靠性。

在企业客户现有的案例中,目前可以看到的交换机基本上都是支持双active的绑定方式,一般要在交换机上简单的把端口做一下设置就可以达到这种模式。

(单个机柜的部署方式)
对单个的机柜来说,一般的机柜是44U,在部署的时候三个机柜一般会放16台2U的X86服务器,对于GP架构,需要控制节点,因为它只是负责元数据的存放和请求的解析、分发,所以它一般不需要有非常大的空间,一般建议可以有6块600G的SAS盘,可以做RAID10,也可以做RAID5,做元数据的存放。

对于底下的数据节点,就GP数据库来说,一般会做海量数据的处理和分析,因此数据节点往往需要承担大量的数据存储和计算。建议对于计算节点一般采用2U的服务器,可以采用24块600GB或者900GB的SAS 10K或者15K转的盘,根据企业中自己的实际数据去选用磁盘类型。

目前在国内客户用900G的SAS盘居多一些,在一些电信行业,数据量往往比较大,也有一些客户采用单块2T的硬盘。一个机柜里面也会放两台万兆交换机,用于内部的数据互联,同时也会加一台千兆交换机,用于对于服务器进行管理。

在划分网络的时候,千兆和万兆的交换机一般都会划分成不同的网段。对于万兆交换机的接入,一般采用双active这种方式,只给分配一个IP段就可以。

2.GP软件部署

在GP底层实际是使用了数据库,并行的机制是采用了在X86服务器上部署多台数据库,然后通过软件对它们互联组网,完成整个执行。对于GP来说,它的高可用在企业里面首先是要保证数据的安全可靠。在规划时,在GP默认情况下,可以选择有没有备份的数据,就是有没有mirror。GP只有两种方式,要么有mirror,要么没有mirror。有mirror的话,数据摆放的时候就可以指定mirror具体的摆放方式。对于GP来说,默认的摆放方式是采用Group的方式。

举个例子,假如有两个机柜,每个机柜上面有六台X86服务器,在存放的时候,假如在第一台服务器上部署了四个primary实例,会把对应的mirror节点放在相邻的服务器上。第二台primary备份实例就会放在第三台节点。那它就是采用这种轮训打散的方式来做GP的高可用。当任意一台机器挂掉之后,都不会对GP的可用性产生很大的影响。但是带来的问题是,GP在正常情况下,只有primary对外提供服务,假如说这个机器挂掉之后,那它对应的mirror就全部切到另外一台服务器上。这样对于MPP数据库,相当于有一台机器要承担比平时多两倍的计算工作量。

由于MPP这样的短板效应,尤其是在压力比较大的时候,就会发现整个集群因为挂了一个节点,就会对整个集群性能下降40%到50%的影响,因为它受最慢的节点影响。其他节点都已经计算完了,但这个节点没有计算完,它就受这个节点的影响。

另外还有一种方式,这个机器上有四个primary实例,可以把每一个primary实例打散在接下来的四个节点上,相当于每一个机器上只放第一台机器的一个备份数据。这样的好处在于,当这台机器挂了之后,相当于有四台机器分开承担原来一台机器的工作点。整个集群的性能最多情况下相比原来,可能就下降了25%。但是对它来说,采用这种方式,在挂了一个节点之后,如果这四个机器里面再有任意一个节点挂掉,那整个集群就不可用了。就是在GP里面如果是主备数据同时挂掉,那整个集群就会报错,我们发的所有SQL都会异常退出。

一般在企业里面部署的时候,这么去考虑的话,会采用group+spread的方式去部署。举个例子,P1、P2、P3、P4,放在第一个机柜的第一台X86服务器上,可能就是以两个为一组,分开部署在第二个机柜的这两台机器上。这样的话,假如说当第一个机柜的一台服务器挂掉之后,在这边会有两台服务器完成原来有一台机器的工作,对整个集群的性能下降不会造成很大的影响,同时也兼顾了高可用性。

目前在一些大的银行里面,尤其是当集群规模比较多的时候,一般都是采用group+spread的方式。但是在一些只有十几个节点的客户里面,一般还是采用group的方式去做实例的规划。

3.GP硬件选择

刚刚讲过,在X86服务器里,一般企业客户都会采用SAS盘或者SATA盘去做,因为容量会比较大。GP主要的场景是做海量数据的分析。一些电信客户里面也会涉及到一些明细数据的查询,比如说在某省的移动客户,会涉及到用户的一些详单的查询。因为在底层硬件上选用了SATA盘,即使用了24块,它的IOPS还是比较低的,一般SATA盘的IOPS只有100到200左右,当并发的分析,比如跑报表的分析应用和小的并发的查询过来之后,就会发现对于用户详单查询会有很大的影响。当时它做了很多的调优工作,包括底层用了GP的资源队列,甚至还用了操作系统的Cgroup,对IO做了限制。但是效果都不太理想。因为Cgroup也是通用采样的方式,在一个周期里面会控制IO使用。但是对于一些大的查询,如果把IO占满之后,还是会对整个集群使用造成比较大的影响。

一般推荐客户使用一些比较高的并发查询,就是小的IO查询时,一般会推荐使用SSD的设备,在GP层面在建表的时候可以指定哪些表放在SSD上,哪些表放在SATA盘上,真正实现底层的IO隔离,以避免不同的业务之间造成影响。


硬件选择--磁盘

底下这两个就是SSD和SATA盘,在IOPS尤其是在小的IO上面,SSD比SATA盘有非常大的优势,一般情况下来看对于SSD的设备,它的IOPS往往是SATA盘的几十倍甚至到一百倍,但是对于这样一个大的IO查询,比如像海量数据扫描来说,相比传统的SATA盘并没有非常大的提高。对这个数据来说SSD性能比较差,也是属于比较老的SSD设备。

目前在企业里看到的一般的SSD的吞吐能到600MB/s到900MB/s的速度,但是IOPS基本上在30万左右。如果企业里面确实有对于小IO的高并发的查询类的场景,建议在X86服务器里采用SSD和SATA混搭的方式,然后在GP层面真正在底层硬件上隔离物理资源。

对PCIeflash这种设备,在企业里面、在数仓里面用到的还不多,因为一个是插槽有限,另外成本也非常高。对于网络互联设备来说,GP一般建议使用普通的以太网络,通过使用万兆交换机,把多台服务器组合在一起来使用。

有的客户,比如某电信用户,已经采购了这样的设备,就想看看能不能在数仓系统里把GP接入进来,当时遇到的情况是,因为GP在底层是使用的TCP/IP通信协议,所以即使有高速网络互联设备,要去接入的话,还需要用一层IPOIP的一些协议去做转换。一方面是会带来一些性能的损耗,另外一方面当时的测试也不是特别稳定,因为网卡驱动的问题,导致服务器经常宕机。所以说在GP里面一般都是根据具体的业务场景,主要的场景就是这种海量数据的大的顺序IO的读写操作,一般是建议采用24块盘的SAS盘或者SATA盘,做底层的存储。对于有这种海量的小的并发查询的时候,也可以采用SSD。

4.RAID的划分与性能比较

磁盘选完之后,就要涉及到RAID的划分,在GP软件层面本身的高可用只是保证了最多有一份数据冗余。在底层,GP和Hadoop不一样,GP一般会建议底层的数据节点采用RAID的方式,在企业里面往往使用最多的两个RAID方式,RAID5和RAID10。

在容量上来说,举个例子,下图是某银行客户当时做了非常详细的RAID组的测试,这是在十块SAS盘做了大的RAID5,另外一个是做了RAID10。RAID5和RAID10相比最大的优势,一个是在容量方面,因为RAID5假如有10块900GB的盘,那只需要丢掉一块盘的容量,还有9T的空间。对于RAID10来说,基本上是需要丢掉一半的存储空间。在具体的性能上来看具体的数据,在读写性能上正常情况下十块盘读写数据RAID5都要好于RAID10。


RAID5 VS RAID10 顺序IO测试对比

但是在真实的业务场景当中就会发现磁盘IO往往不会一直持续100%,繁忙程度不会到100%的程度,所以说根据在企业里具体的观察,跑真正的SQL查询的时候,RAID5和RAID10并没有非常大的明显的差异。

在空间使用率上来说,在底下的磁盘空间,使用率占到70%之后再通过GP check做磁盘性能的检测,就会发现它的性能大概下降了有20%左右,包括读写性能。这是因为在空间使用非常多之后,可能磁盘外侧空间已经使用完,另外一方面,在文件分配上面也会有一些性能的损耗,所以说当你空间使用超过70%之后,对于数仓类的应用也会造成一些影响。所以建议企业客户服务器磁盘空间不要超过70%,一方面是从性能考虑,另外一方面在查询的时候,还会有一些中间的结果也会用一些临时的空间。

二、在企业性能上来说

(1)RAID卡cache对性能的影响

对于做RAID之后,尤其是对企业的性能还是有非常大的影响的,因为RAID卡本身在数据写入的时候,会先写入到RAID卡的cache里面,后面就是通过RAID卡硬件再把它刷到真正的底下的磁盘里面。如果没有RAID卡cache的话,对不管是RAID5还是RAID10,对写的性能都会造成比较大的影响。

比如一个客户它的数据规模比较小,从两个节点扩到四个节点,完成扩容之后发现机器数增加了,并且每个机器上的数据量减少了,但是性能还没有之前两个节点跑得好。原因在于他们新采购的机器没有RAID卡cache,导致新的机器IO性能下降非常严重。因为这个就是MPP短板效应造成了整个集群的性能比较大的下降。

(2)异常情况下对性能的影响

对于RAID5和RAID10来说在坏掉一块盘的情况下,由于在读的时候,RAID5需要通过其他盘去重新构建数据,所以当坏掉一块盘之后,RAID5比RAID10性能会下降非常多。对写的性能也会有一些下降,但没有读的性能下降得厉害。

另外,比如坏了一块盘,又拿了一块新盘顶上去之后,在review的过程当中,对RAID5读和写的性能也会有一些比较大的影响。现在一般的RAID卡做得比较智能,前台有正常的IO操作,后台就会把review的操作暂停掉,等正常的IO下来之后,后台再做。但是对于RAID5和RAID10,以具体的测试情况,大的顺序IO来说,RAID5的读写性能还是要好于RAID10,但在异常情况下,它的性能会掉得比较厉害。所以具体到企业客户,还是根据这样的场景去选择RAID5和RAID10。

如果对性能包括容错性要求比较高,不管在任何情况下都要对性能不会造成非常大的影响,这时候一般建议还是用RAID10;如果没有这样严格的要求,往往是从成本和容量、性能来考虑的话,在GP这边还是推荐使用RAID5。目前国内客户中,采用RAID5是最多的方式。

(3)从不同故障场景下比较性能影响

刚刚对于底层磁盘RAID5和RAID10的性能进行了比较,对于GP来说,具体可以看一下在不同的故障场景下,对性能到底有多大的影响。


RAID5 VS RAID10 故障场景下对GP性能的影响
这是在X86服务器上装了四个实例。
第一

对于在cache失效的情况下,对于RAID10来说,它的性能大概只有3%、4%的性能下降。但是对于一块硬盘坏掉之后,因为它对读的性能会有一些影响。当RAID10有一块硬盘坏掉的话,它的性能大概下降了20%左右。对于RAID5来说,一块盘坏掉之后,有这样大量的IO读写的话,整个集群的性能将近下降了一倍还要多一点。

第二

在36个节点上有60万张表,做的测试是分别模拟,先把mirror的事例给停掉,测了一下它的性能,只是把mirror停掉的话,对性能影响基本上没有太大的影响。但当一个节点挂掉之后,如果采用group这种方式,因为它的压力完全会有另外一台机器去承担。当这个集群本身的负载非常高的时候,就会看到整个集群的性能可能就要下降一半还要多一点。

第三

很多客户认为在硬件异常的过程当中发现底下的数据节点不同步,要执行GPrecoverseg的话,还要跑作业。因为在做recoverseg时,底下的节点已经有一些问题了,那它在做同步时,本身也会有一些大的IO和资源的消耗,所以它对集群的性能会下降得比较多。因此在真实的生产环境里面,比如说节点挂掉之后,一般会建议客户在有空闲的时间窗口,比如大的批量跑完之后,再去赶紧把GPrecoverseg做一下同步。因为GP底层是做的增量块的复制,同步的速度还是比较快的。

第四

当有一个节点宕机之后,在跑的性能。整个建议是,在真实的业务场景中,RAID5在跑数仓类的场景里面,真实的业务IO不会一直持续100%,所以RAID5和RAID10对真实的业务影响并不是特别大。但是当硬件坏掉之后,RAID5的性能下降比较多,会对集群有比较大的影响。另外,系统空间使用尽量不要超过70%,超过70%之后也会有一些影响。

对于RAID卡的cache来说,建议在采购的时候,还是要采购有cache的RAID卡设备。另外,尽量要使用压缩表,因为在GP里面使用压缩表的话,一般情况下根据数据的规律性,压缩级别一般是在3到5左右,这样的话就可以通过CPU换IO的方式去节省底下的一些IO。在企业中基本上使用这种压缩表在大的查询里面,往往会带来性能的提升,因为CPU的计算性能相比IO是要快很多很多倍的。

三、GP高可用原理

下面重点讲GP的同步原理。这个图是用了阿里云之前的blog里面的一个图案。在GP里面它是有master这种架构,在master节点上,用户连到GP之后,后台会起相应的back进程的处理用户的请求。当比如有建表或者删表或者更新数据字典的操作的时候,是通过Postgres的WAL日志流复制的方式,比如说新建一个表,就会先把这个日志写到buffer里面,然后再刷盘。这边会有新的进程然后同步到standby节点,standby节点也会把日志刷到磁盘上。


Greenplum数据同步原理

元数据和底下数据节点的安全性

对于GP元数据的同步,是采用了Postgres原生的流复制的方式,是强同步的方式,就是元数据这种变更的时候,一定是它这边真正刷盘成功之后,才会认为写入的动作成功。所以在元数据这块,是能保证绝对的可靠性,假如master挂掉之后,那这个standby进程会读Postgres进程,做回访,应用到standby数据。当异常情况的时候,集群会重新拉起来的时候,也会用xlog做恢复,这样就保证了元数据的安全和可靠。

对于底下节点来说,GP是采用自己的一套块数据的复制方式,怎么来理解呢?当有数据插入或者变更的时候,当这个数据要真正刷盘之前,在写入磁盘之前,它会截获到数据的变化,然后会把这个变化同样是通过这个进程发到对应的mirror节点,mirror节点后台会有相应的consumer的进程,包括heap表,来做相应的写盘动作。对于整个来说,只有mirror节点,把这个数据写成功之后,才会返回给primary节点,告诉它数据已经写成功了,就是真正后台会有一个刷盘的动作。

在GP整个的数据库里面,不管是从master节点还是底下的数据计算节点,是能保证数据的强一致性的。在任何情况下,比如机器突然掉电的情况下,不会出现切到mirror之后发现已经提交的事物丢失的情况。后面具体讲一下它后台的进程。


Greenplum主节点同步原理

这个就是说对于master和standby节点,当一个事物在提、把WAL刷盘的时候,它就会先把数据同步到standby节点,standby节点会写到本地盘上,然后再返回,告诉它表示已经写成功了,最后会传达到客户端请求已经成功,整个在元数据这块是通过WAL的流复制保证数据的安全可靠。

对于底下的计算节点,同样是当有大的数据插入或者更新来说,有一个WAL replication的进程,当这个数据要写盘的过程当中,会根据AO表还是heap表,会从不同的buffer里面会纳入到块的变化。比如说要刷盘的时候,这个replication的进程会通过新的进程把数据通过TCP/IP这个协议发到mirror节点,mirror节点拿到这个数据之后,也会先把它放到它的内存里面,然后有相应的consumer进程把它写到对应的底下的文件系统上,之后会有一个act进程,告诉primary节点,说数据已经写入成功了,通过这样的一个完整的链路,告诉primary节点,说这个时候也可以把事物提交,完成整个的动作。


Greenplum数据节点同步原理

它就是通过这种方式,类似管道的方式,在数据真正写盘之前,在primary节点写盘之前,就是通过这种强一致的刷盘的动作,不管是AO表还是heap表,都会通过强制的刷盘动作,保证数据的绝对安全、可靠,就是任何情况下机器断电等等情况下都不会造成数据的丢失。这也是为什么GP在金融客户有非常非常多的应用案例的原因,就是它不管是从原数据还是底下的数据节点,都能保证数据的绝对的安全可靠。

底层的同步进程

在一个节点上看一下它对应的mirror节点。mirror节点是它只负责底下计算的数据的冗余,正常情况下是不承担任何的计算负载,只有当primary节点挂掉之后,它会自动切到这边做相应的激活,就是切换成primary的角色。

它其实有三个最重要的进程:

1.一个是consumer进程

mirror consumer process主要负责xlog的写入和控制文件,因为在写入之后,比如做检查点之后,会更新相应的控制文件。它主要是负责xlog的写入。

2.一个是write process

负责heap表的写入,对于heap表的写入是通过xlog日志,就是通过xlogdump提供的工具,当数据写入之后,比如在heap表里插入之后,会解析它后台到底是做了什么样的动作。解析后可以看到当有heap表插入时,会马上在对应的mirror把WAL日志写到相应的磁盘上。对于底下来说,去跟踪刚刚提到的heap表的consumer进程,真正的数据文件的写入,在write的时候,底下并没有看到有think的动作。因为write的时候,它只是把数据从buffer里写到文件系统cache里面,并没有确定数据一定是刷到磁盘上的。

对于heap表的写入,只是保证了xlog在mirror节点的写入,但是对于真正的数据文件并不是一个强同步的过程。但是在做checkpoint时会发现heap表也会刷到这个磁盘上,但是通过这种方式已经能保证对于heap表的写的操作一定是一致的,因为对于heap表的xlog已经写到磁盘上,那就是挂掉之后,大不了再用xlog做一下恢复就可以了。这样的话,对于heap表写入操作完成之后,数据在mirror上绝对是不会丢掉的。

3.还有一个是appendonly process

负责AO表的写入动作。AO表的插入跟heap表有不一样的地方。因为在GP里面,AO是用了自己另外一套机制去实现的,所以它可以做压缩等等。但是它里面对于appendonly表另外还有一些heap表作为辅助的数据字典,比如pg-fastsequence和aoseg,就是它上面的一些索引和原数据的记录信息。对于AO表的这些辅助的一些数据结构,在GP里面也是采用heap的存储方式。

当在AO表里面去插入的时候,去跟踪一下刚刚提到的xlog的写入进程会发现它也会写xlog日志,但是它写入的是AO表,就是appendonly表对应的heap的数据字典的一些信息,真正的数据是通过mirror consumer appendonly process去写到磁盘上的。就是对于AO表的写入,比heap表要稍微复杂一点,就是它在写入的过程当中,同步是要包括一些xlog的一些写入,同时也包括一些本身的数据写入。

对于AO表来写入的话,把AO表插入的时候不用做commit去跟一下进程,它在写入的时候,把数据文件写到文件系统cache之上,会马上调一个fsync,这样的话对于AO表的数据是会马上写到底下的磁盘上的。所以对于AO表来说,它也是通过自己内部的机制,保证了数据在写入的过程当中是强同步的刷盘动作,保证了数据的可靠。

另外,对于刚刚提到的写xlog的consumer进程,不管是对heap表还是AO表写入,都会有相应的写入,写入之后紧接着会有一个fsync的动作。对于AO表的话,也是写入之后马上就会有一个fsync的动作。所以说对于GP来说,对于底层的数据存储,不管是heap表还是AO表,通过xlog日志和本身的appendonly表的写入机制,保证了两边数据的绝对安全可靠。

四、企业客户遇到各样问题应如何分析

对于GP来说,一般遇到的问题归纳起来主要可以分为两类。一类就是性能的下降,还有一类是异常情况。比如说在做一些操作报错的情况。一般情况下在做问题定位分析,相比传统的Oracle、MySQL的单机的数据库来说,因为它的集群规模比较大,往往涉及到几十甚至上百台规模,定位起来可能还是需要一些技巧。比如这个集群突然慢了,原来跑十几分钟的SQL,现在跑一个小时都还没有结束。那这个时候怎么去定位分析这个问题呢?

第一步就是首先要确认这个慢到底是慢在什么地方,在检查的时候,因为有的节点执行快的话,最后的进程的状态是不一样的。通过outSQL的视图查看一下,看这个SQL还有哪个节点没有执行结束,或者通过GPssh也可以跳到所有的节点上,去看一下它的负载,看一下它的连接状态。就先定位到哪个也点慢了,影响到机器。

接下来可以看一下这个图上的工具,基本上是自带的一些工具,比如说通过vmstat看内存,通过top看进程,通过iostat看IO的,就是通过Linux系统的一些命令,再具体的去分析,这个进程hang是因为什么,是不是底下硬件损坏导致性能下降,还是其他的一些情况导致的。

另外,比如跑了一段时间,发现跑所有的SQL都会有这样的性能下降,在集群跑了一段时间之后,可以用GP自带的一些工具,比如说GPcheckperf、GPcheckcat等工具检查一下整个集群之间的性能,包括网络、磁盘、IO等等,去定位是不是有硬件性能的下降。

你可能感兴趣的:(Greenplum在企业生产中的最佳实践(上))