Greenplum 的高可用是怎么做到的?

484 阅读6分钟

什么是高可用

高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。假设系统一直能够提供服务,我们说系统的可用性是100%,很多公司的高可用目标是4个9,也就是99.99%,这就意味着,系统的年停机时间为0.876个小时。

如何做到高可用

高可用系统最大的劲敌就是单点故障。任何一个单点故障都是不可避免的,如果系统是单点架构的,当单点出现故障则会导致系统不可用。所以,实现高可用的本质就是冗余。冗余部署服务,当单点出现故障后,及时发现并用备份系统替换。

Greenplum高可用的实现

Greenplum是一个高可用数据库系统,同样是通过冗余部署来实现高可用。

Greenplum系统中包含了一个主节点和若干个子节点。Greenplum正是通过对每个节点提供冗余来实现高可用。在数据库系统里,通过复制技术来实现冗余。

复制

Greenplum通过复制来实现冗余。在执行写操作时,会产生xlog事务日志。xlog既可以作为数据库Crash时进行数据恢复的依据,同时也可以作为增量更新传递给从节点。xlog存储在数据目录的pg_xlog目录下。

在主节点上会存在wal-sender进程,从节点上会存在wal-receiver进程,wal-sender进程会将产生的写日志同步给wal-receiver进程来实现冗余。

Primary节点和Mirror节点上的wal sender和wal receiver进程可以通过ps命令看到

同步复制、异步复制

复制只是将xlog拷贝到从节点,复制分为同步复制和异步复制。

对于同步复制来说,commit操作在xlog同步到从节点后才返回。

对于异步复制,xlog刷新到本地磁盘即返回,并不等待从节点提交完,所以xlog同步到从节点是异步的,可能立刻完成,也可能有很大延迟。

同步复制保证了主从的一致性,但是增加了事务提交的延迟,另外如果从节点出现了故障,则事务将一会hang住无法提交。异步复制降低了延迟,但是可能存在主从不一致。

为了保证高可用性,目前Greenplum采用的是同步复制。通过GUC synchronous_commit和synchronous_standby_names来控制。其中synchronous_standby_names配置设置同步的子节点信息,通常设置成’*’来表示在所有从节点上使用同步复制(目前最多只支持一个从节点)。synchronous_commit则必须设置成on。

Greenplum 高可用部署图

综上,对于一个高可用的greenplum集群,master节点会对应备份的standby节点,每个primary子节点会有与之对应的mirror子节点。目前的greenplum只支持一主一从,暂时不支持一主多从。

gp_segment_configuration(节点元数据的catalog表)

Greenplum通过catalog表gp_segment_configuration来维护包括master,standby在内的,所有节点的信息。这也是DBA了解集群状态最直观的方式。

下面是一个实例,该集群包含3个节点。

Primary-Mirror的故障恢复— FTS

FTS(Fault Tolerance Service)是greenplum提供的对于子节点的故障检测与恢复的服务。FTS是一个隶属于master的子进程,通过定期轮询每个primary的状态来获取每个primary-mirror组的状态。该进程只在master上存在,进程名为ftsprobe process。

这里需要注意的一点是,FTS并不直接连接mirror,对于mirror的状态,FTS也是通过primary来获取。Primary则通过wal-sender进程的状态来获取mirror存活和同步状态。

FTS在满足如下三个条件的时候会触发轮询

1. 到时间了,gp_fts_probe_interval

2. 用户手动执行select gp_request_fts_probe_scan()

3. 查询执行过程中发现节点异常

轮询过程图如下:

对于每个primary-mirror组来说一般会有如下几种状态。

1. primary正常,mirror正常

2. primary正常,mirror异常

3. primary异常,mirror正常

4. primary异常,mirror异常

Greenplum目前是一主一从架构,所以对于第四种primary-mirror都出故障的情况是解决不了的,在这种情况下只能通过人工干预解决。对于第一种都正常的情况也不需要做任何处理。所以下面对二三两种情况做详细介绍。

故障1:primary挂掉

这是最常见,也是高可用解决的最主要的问题。一旦FTS发现某个primary已经宕机,此时,如果Mirror是同步的,则将把对应的Mirror Promote成primary,并更新catalog。

Promote后catalog可以看到如下更新。

通过role可以看出,mirror成了primary,preferred_role没有变,同时原primary被标记成了mirror,但status是d。mode也被标记成了n。

故障2:mirror挂掉

如果mirror挂掉了,意味着primary与mirror的复制不可能同步了,所以primary会hang住,直到FTS来通知primary执行Sync-off来关闭同步复制。关闭同步复制的方法即将synchronous_standby_names设置成空。

可以看到catalog表的变化,mode已经变成不同步,mirror的状态也标记成down。

注意:FTS在轮询的时候,如果Primary节点发现Mirror存活并且复制方式是非同步,则会强制设置为同步复制,即更新synchronous_standby_names为’*’。

FTS相关GUC

Master的故障恢复

FTS与实现了segments节点的故障自动恢复,那么Master如何恢复呢。在Greenplum6里并没有实现Master故障的自动切换机制,Master节点如果出故障,只能通过手动方式运行gpactivatestandy来Promote standby。

同时,在Master节点上,synchronous_standby_names配置一直为空,即使Standby挂掉或网络故障造成同步延迟,请求不会被阻塞。因为没有自动通知Master做关闭同步复制的服务。

高可用相关运维工具

  • gpactivatestandby

gpactivatestandby会激活standby成master。

例如:

gpactivatestandby -d /gpdata/standby

该命令会激活运行在/gpdata/standby目录下的standby为master。

  • gpinitstandby

gpinitstandby会基于当前master初始化一个新的standby。通常是在master挂掉,standby提升成master后,来生成一个新的standby作为master的备份用。

例如:

gpinitstandby -s myhost -S /gpdata/standby -P 2222

该命令会在myhost机器上的/gpdata/standby目录,生成一个运行端口为2222的standby节点。

通过运行如下命令也可以在standby宕机后,重新启动standby

gpinitstandby -n

  • gprecoverseg

gprecoverseg工具可以恢复一个已经宕机的mirror。

可以通过执行gprecoverseg -F来彻底重建已经宕机的mirror。