作者简介
郜德光,携程技术保障中心高级数据库经理,负责数据库相关的运维工作,参与了SQL Server和MySQL的高可用以及数据库容灾建设。喜欢钻研技术,对数据相关的技术一直保持着浓厚的兴趣。
网站稳定性对任何一家公司来说都至关重要。业务长时间中断,不仅仅意味着收入的损失,更可能会失去客户。数据库的稳定性和HA/DR建设是网站高可用建设非常重要的一个环节。
本文分享了携程数据库(SQL Server,MySQL和Redis)的高可用和容灾的重构历程,以及重构的原因。也会简单分享一下DR切换工具,该工具可以一键将主站数据库切换到DR站点,用于在主站IDC故障时,快速恢复数据库服务。
1.0时代【1999~2008】
自携程1999年成立到2008年左右,公司数据库产品主要是SQL Server。
这个阶段是公司初创和快速发展时期,以优先发展业务为主。数据库的架构设计比较简单。高可用通过数据库的镜像技术来实现。镜像主要的架构如下图所示。甚至为了节省服务器资源,我们采用多个主数据库共享一个辅助数据库服务器的方式。
这种镜像方式搭建和运维都比较简单。主机如果出现故障,先尝试重启能否解决,如果不能恢复,则通过镜像切换的方式,切换数据库服务到从机。
这种HA架构比较简单、粗糙,优点是不需要群集和共享存储等资源,成本低。缺点是主机故障时没法自动转移,业务恢复速度较慢,严格来讲还不具备HA的能力。
前期对于支撑当时业务发展来说已经够了,随着后期业务快速发展,已经无法满足业务稳定性的需要。
2.0时代【2008~2012】
这一阶段,业务进入快速发展阶段,对数据库的依赖也越来越重。开始大量采用SAN共享存储来存放数据。单台数据库已无法支撑业务的压力,因此,也对数据库架构进行调整,引入了复制分发,用于读写分离。
架构如下图所示:产品的价格首先录入到录入数据库。通过SQL Server自有的表级别的复制分发技术,把数据传递到多个产品数据库,以供业务访问。如果业务访问压力大,则通过添加产品查询服务器的方式来进行扩容。
对于非读写分离场景的数据库,高可用是通过Failover Cluster群集方式。DR依旧采用数据库镜像的方式。
如下图所示:一旦服务器主节点硬件故障,则会通过自动故障转移,转移业务到服务备节点,切换时间大概在2分钟左右。主备服务器都连接后台共享存储。
同时,还对数据库服务搭建了镜像,一旦存储发生故障,主备服务节点都不可用的情况下,则通过切换镜像到镜像服务器上,镜像服务本身也是一个Failover Cluster群集,也做了高可用。
由于SQL Server的镜像服务器平时是不可读的,我们还通过一个日志传输服务,搭建了只读数据库,以供BI取数或查询。这个只读数据库也用于验证数据库备份的有效性。
由于业务的需求越来越复杂,数据库的架构开始逐渐复杂起来,主要体现在:
1、复制分发架构过于复杂,如城市表,基本上所有部门都需要使用,通过拉复制分发链路,把城市列表信息传递给其他部门的数据库,能快速解决问题,但随之而来,使得数据库的关系变成蜘蛛网状。维护起来相当困难。
2、过于依赖底层的SAN存储。SAN存储内含相当复杂的存储技术和网络技术,复杂一点的问题就需要依赖供应商来解决。
2012年,微软推出了AlwaysOn高可用性组,可以不依赖于共享存储。AlwaysOn高可用性组同时也具备读写分离的功能,而且也能做容灾。所以,我们逐渐朝AlwaysOn这个架构演进,并用SSD来代替SAN存储。
3.0时代【2012~2014】
在2014年左右AlwaysON技术已经非常成熟,对于多IDC环境下支持也已经非常好,是SQL Server主流的HA/DR方案解决方法。
因此在2014年后,我们开始逐步把SQL Server改造为Always ON架构。架构如下图所示:写还是一个节点,但可提供多个节点的读。并且其中的一个节点是同步模式,用于做写节点的高可用。
纯AG架构
上面新的架构非常灵活。由于2014版本已经支持8个只读副本,AlwaysOn延迟又低,因此完全解决了群集 镜像架构中遇到的复制分发读写分离架构瓶颈的问题,同时也不在需要为离线查询和ETL取数部署单独的只读数据库。读副本的备份功能也大大降低了备份时主机的压力。
在推进Always ON新架构过程中,我们也逐步用SSD来取代原有的SAN。除了SSD的价格越来越便宜容量越来越大,相比SSD,SAN存储对DBA基本是黑盒子,需要专业的运维团队支持,运维成本更高。
4.0时代【2014~2018】
SQLServer AlwaysON技术比较成熟,但其存在一个关键的问题,在于AlwaysON技术是闭源的。DBA难以深入了解该技术的底层细节。虽然脱离了SAN存储的依赖,但还是依赖于Windows的Failover Cluster集群。
因此,2012年开始在携程内部逐步推广开源的MySQL和Redis 。在推广MySQL的时候,我们意识到MySQL的性能比不上SQL Server, 所以同时推广数据库分库分表方案和前端Redis缓存。
MySQL的高可用和DR是通过MHA(Master High Availability)来实现的。具体架构如下:
通过MHA管理节点,来监听主节点的可用性情况,一旦发现主机不可访问,则切换到slave节点。MHA的高可用模式,既兼顾到高可用,也兼顾到DR。对于读写分离的需求,主要是通过分库分表方案来进行的。部分有采用读写分离。
对于MHA的方式,是通过域名/虚拟IP的方式,提供给业务使用。其最大的风险的是脑裂。主机没完全挂死,同时主从切换后,新的主机开始提供业务访问,就产生了脑裂。为了解决这个问题,我们在数据库访问层,引入了动态数据源技术,不通过域名/虚拟IP的方式,而是通过实IP的方式。提供业务访问,有效的降低了脑裂的风险,同时不通过域名解析,能加快主从/DR切换时间。
随着MySQL的引入,Redis也逐渐广泛使用起来。由于Redis的Key/Value访问速度非常快,目前携程对Redis的依赖比对数据库还重要。Redis本身需要有高可用和DR的方案。
对于Redis,借助框架部门开发的中间件CRedis,用于Redis的访问和高可用控制。
简要架构如下图所示:
说明如下:
1、业务访问的时候,通过引用框架的客户端组件读取配置信息。Redis切换由哨兵发起,并且Credis配置能及时捕获,并通知客户端IP和端口的变化。
2、对Redis拆分多个Group,以避免访问热点。每个Group包含多个Redis实例。
3、Redis实例Master/Slave在一个机房, 另外两个实例Slave-DR在另个机房。
4、访问请求通过CRedis配置路由到指定的分片。
5、Slave-DR实例和主实例的数据同步通过框架同步工具XPipe来实现。XPipe 已经开源,更多信息请访问:https://github.com/ctripcorp/x-pipe。
为应对日常DR演练以及硬件故障时快速恢复业务的场景,DBA设计开发了集中、一键式DR自动化切换工具,支持所有数据库产品。用来帮助DBA快速、安全的完成数据库切换。
DR切换工具支持不同的切换维度,覆盖了所有的场景:
1、单个或多个数据库群集,应对单机故障或日常维护等场景;
2、单个业务线下所有数据库群集,应对DR切换演练场景;
3、IDC下所有数据库群集,应对主IDC故障场景;
目前为止已经利用DR工具成功完成了200 次的切换演练。下面是用DR工具准备单群集切换的一个例子:
如上图所示,工具中搜索到对应的群集后,工具会根据元数据信息展示群集的整体架构:节点(名字、IP地址等)、IDC、复制关系。
每个节点提供2种切换方式:
1、强切工单,强制切换。主机或主站down时,可能有数据丢失;
2、演练工单,正常切换。主机可用时,演练或计划内主机维护时使用;
生成的工单后续可以自动执行。
DBA把DR复杂的切换恢复流程全部集成工具里面,工具同时支持API根据不同维度快速批量生成切换工单,支持并发切换,可以快速完成业务的切换恢复。
为保证DR工具的高可用性,在设计DR工具时也消除了工具对单个IDC的依赖。只要保证一个IDC可用,就可以通过工具发起切换。
从以上架构的演变过程,我们可以看到是从简单à复杂à简单的一个演变趋势,但是稳定性和可用性有了质的飞越。数据层本身变得越来越简单,而扩展了大量的辅助架构,来提升自动化运维能力。
希望以上的分享对大家有所帮助。