PagerDuty实战分析:将MySQL迁移至XtraDB并成功运行EC2

更新时间:2014-06-26 11:47:15点击次数:923次

PagerDuty数据库迁移EC2XtraDBMySQL

摘要:PagerDuty是一款IT警报系统工具,作者Doug Barth分享了PagerDuty是如何成功地把现有系统MySQL迁移至XtraDB Cluster,以及在这一过程中遇到的利与弊。

【编者按】 PagerDuty是一家新兴的互联网创业公司,它是一款能够在服务器出问题是发送提醒的产品,包括屏幕显示、电话呼叫、短信通知、电邮通知等。目前AdMob、37Signals、StackOverflow、Instagram等均采用了PagerDuty作为消息通知以及突发事件处理工具。本文作者Doug Barth分享了PagerDuty是如何成功地把现有系统MySQL迁移至XtraDB集群,以及在这一过程中遇到的利与弊。

在半年前,PagerDuty公司成功地把现有系统从MySQL迁移至XtraDB集群,并在其上运行亚马逊EC2。

旧系统配置分析

从配置上看,这是一个非常典型的MySQL环境:

一对Percona服务器负责对一个DRBD卷进行数据写入。

以主副EBS双机对DRBD卷进行备份。

设立两个同步复制数据库,当主服务器出现问题时,能把业务系统无缝转移到次服务器。

配置一系列异步复制机,以应对重大灾难、紧急备份、突发变更维护。

存在的问题

兢兢业业的旧系统服务多年后,面对日益突出的可靠性问题,开始显现出力不从心了。此外,每次进行主服务器切换,无疑于是一场悲剧:要进行DRBD主机切换,首先得在主服务器上中断MySQL,脱机DRBD卷,把从服务器状态变更为主服务器,重新载入DRBD,最后重启MySQL。而这一整套过程会导致服务中断,因为MySQL在由中断到重启的过程中,我们设置了一个冷却缓冲池,在系统服务重回正轨前这个冷却机制需要时间预热。

我们尝试通过Percona的缓冲池恢复(buffer-pool-restore)功能来减少中断时间,但这相对于我们体型庞大的缓冲池来说如同蚍蜉撼树。同时该功能会增加额外的系统资源开销。还有个问题是,一旦发生意外的主服务器切换,异步从服务器将停止运作,必须手动重启。

拥抱XtraDB集群的原因

XtraDB集群的特色:相校于之前的双机系统,集群中采用的是三机同时运作,两两进行同步备份。因此连接切换时间大为减少。

支持多主服务器同时在线,每个主服务器拥有一个热缓冲池。异步从服务器可以选择任何节点作为主机,节点间的转移不会中断备份复制进程。

自动化的节点机制与我们目前的自动化系统配合良好。配置新节点后,我们只需提交一个节点地址,新节点将会自动收到一个数据备份集,同步数据后会加载到主服务器群中。

前期准备

将XtraDB集群接入现行系统,需要进行一定的前期准备。部分是简单的MySQL微调,其余的是一些基础化的操作。

在MySQL上的操作:

确保只在InnoDB数据表中设置主键。

确保不使用query cache(查询缓存),由于cluster不支持。

复制方式由基于语句的方式变更为基于行的方式。

除上述MySQL端的操作,为了能在DRBD服务器上进行独立的测试,应用系统端需要进行如下的变更:

采用分布式锁机制,由于MySQL采用的是从本地到集群节点的,例如:执行SELECT FOR UPDATE语句。

用Zookeeper锁替换MySQL锁。

为了检验所有写入的数据能在所有节点上进行数据同步,我们对作业逻辑作出变更,以大量小规模数据处理代替一次性大规模数据处理。

模式变更的选择

在XtraDB集群中进行模式变动是牵一发而动全身的。在集群有两种实现方式,一种是total order isolation (TOI,总序分离式),另外一种是rolling schema upgrade (RSU,滚动模式升级)。

在RSU模式下,允许单独地对节点进行更新。当执行DDL语句时,按序同步各个节点,执行完毕后再重新加入集群。但是这个功能会招致不稳定性,同时数据的大量刷新动作引起的系统问题是不可避免的,由于RSU需要等待DDL语句执行完毕才能进行缓存刷新。

相比之下,TOI的更新操作是一次性同步所有节点,阻断集群通信直到更新完成。我们衡量一番后,决定采用TOI模式。由于系统中断时间较短,所以这次没有对集群进行阻断。

迁移过程

首先,我们在现系统中建立一个集群作为现DRBD数据库的一个从属。当该从属数据库接收到所有写入操作时,我们可以进行压力测试,看看它的承载能力如何;同时会进行相关数据收集和分析。

在进行一系列相关基准测试后,我们发现了两点技术细节是能够帮助实现迁移前后的系统性能趋于一致:

?把innodb_flush_log_at_trx_commit的值设为0或2,可以获得最优写入性能。由于所有变更都是被复制到3个节点的,即使出现失效情况都不会出现数据丢失情况。

innodb_log_file_size的值需要设置成较大数值,我们将其设置为1GB。

进行一番测试后,XtraDB集群的各项指标令人满意,我们接下来开始着手进行实际切换。

首先把所有测试环境下的配置进行备份。因为一旦cluster出现宕机,我们可以快速恢复其至一个单一节点cluster。我们编写了具体的操作程序以及进行了相关压力测试。

在对现有系统的两个DRBD服务器进行从属服务器设置后,我们还设置了其余服务器的从属设置(例如:灾难恢复,备份等)。一切就绪后,我们执行了一次常规的从属升级操作把系统切换到新环境中。

切换后的优点分析

对正在运行的cluster进行重启和更新时,成功避免了之前造成的通信中断影响。成功以TOI模式(pt-online-schema-change)进行模式变更。写入冲突处理能力得到优化提升。当发现一个冲突后,XtraDB Cluster会返回一个死锁错误信息,在以TOI模式执行DDL语句时同样可触发该错误信息返回。之后,冲突错误会导致应用程序服务器返回一个503错误,而我们的负载平衡层设置会捕获该错误,随后会尝试在另外的服务器上重新递交写入请求。

切换后的缺点分析

部分cluster的关键状态计数器是按状态改变的,例如在执行显示全局状态指令后(SHOW GLOBAL STATUS),其值会重设为0。这样会造成很难根据计数器来进行重要的状态监控,例如流控制,因为其值的频繁变更会造成无法准确监控系统的状态(在使用XtraDB Cluster 5.6的Galera 3.x系统中,该问题已得到解决)。当一写入操作冲突发生时,MySQL动态记录适配器会忽略来自交互语句抛出的异常。

对于系统冷却预热问题仍待进一步改进。目前,我们的应用程序服务器是连接到一个本地的HAproxy实例,该实例会把自身的连接数据发送给一个cluster节点。在执行计划维护任务时,我们只能缓慢地把数据推入另一个节点,以在其能完全承载整个系统负荷前进行缓冲池的预热。在将来,我们会按计划完全转变为多主机环境设置,以确保所有节点都有一个就绪的缓冲池。

  • 项目经理 点击这里给我发消息
  • 项目经理 点击这里给我发消息
  • 项目经理 点击这里给我发消息
  • 项目经理 点击这里给我发消息