度可以提升到 GB 每秒。
基于此产品架构,我们在高可用方面又有哪些相应改进?
我们先看看在常规主备模式下的常见高可用方案。在常规主备模式下,主备都是通过数据流复制方式来完成数据同步,其中同步数据流复制模式下,主实例的每一次提交都要等到备实例完成日志落盘之后才能够返回,这样才能够强行保证主备数据一致性。但同样也带来了,备实例异常时,会影响主实例可用性的问题。而在异步数据流复制模式下,主实例是可以不担心备实例的日志落盘情况。这样虽然可以避免可用性问题,但也会造成主备实例数据的一致性问题。
基于此,我们会使用额外的 Warm Standby,和主实例之间保持同步数据流复制。同时我们的 Warm Standby 不会对外提供服务,尽量减少 Warm Standby 实例影响主实例的情况发生,而其他提供对外服务的备实例则通过异步数据流复制方式来实现和主实例数据同步。当主实例出现异常时,可以使用和主实例保持数据强一致的 Warm Standby 实例来进行备提主,快速恢复主实例可用性。之后我们会再异步进行 Warm Standby 实例重建,最终将整个集群恢复成正常状态。这种处理流程虽然尽可能保障了可用性,但仍然存在一些问题是没有办法解决的,例如 Warm Standby 实例虽然没有提供对外服务,但还是可能会存在比如机器、网络等硬件故障导致不可用的风险,从而影响主实例的可用性。
另外,Warm Standby 实例重建也需要时间,当其没有完成重建时,如果新的主实例再次出现异常,就没办法快速恢复可用性。除此之外,一个不提供对外服务的 Warm Standby 实例也要占用资源,所以必不可少会带来多余的成本开销。
那么在 TDSQL-C PG 版计算存储分离架构下,这个问题是否有更好解决方式?得益于我们做了计算存储分离,主备实例会使用同一份远端存储数据,它们之间不存在数据同步的前置依赖。而在数据可靠性方面,我们交由单独存储服务来实现。当在主实例上进行数据写入时,我们会把日志发给存储服务,存储服务完成日志落盘后,就可以返回响应给客户端,同时存储服务再自己以异步日志回放方式去更新磁盘数据,而备实例接收主实例日志只用于更新缓存,在异常时也可以直接使用远端存储服务数据。这样下来主备之间就没有数据同步依赖,从而也就不存在备实例异常影响主实例情况。
另外在这个架构下,也不需要额外 Warm Standby 实例。集群当中,每个备实例都可以在既提供给业务使用的同时,也成为主实例异常时的备份。同时每增加一个备实例,不仅能够提升集群整体读取性能,也能够更高地保证整个集群的高可用。当主实例出现异常时,会选取任意备实例来做备提主操作,快速恢复主实例可用性。在备实例被提成主之后,得益于存储计算分离架构,我们无需数据同步就能够快速完成新的备实例补充。最后,会通过上层负载均衡的路由切换,来保证业务访问数据链路正常,在极短时间内将整个集群恢复成故障之前的样子。
在产品能力方面,业务使用方也可以按照自己流量分布来设置备实例切换优先级,从而尽可能减少异常时对于业务的影响。在内部管控实现上,原来的高可用管控也就拆分成了独立两部分,其中存储管控是负责存储节点的高可用,它会负责对于基础的存储组件 Store Node、内部 Segment 存储单元、以及备份回档等模块进行健康状态检查及异常处理。总体来说,其会站在存储角度,来保证整个分布式存储服务的可用性。在实例管控方面,更多是负责计算节点的可用性,它会通过多种手段去实时检测计算节点健康状态。当出现某些涉及到存储读写异常场景时,会结合存储管控健康信息来综合决策我们的高可用 HA 执行逻辑,结合起来保证整个数据库产品服务的高可用。
除了上述优化,接下来还有已经计划的优化空间,比如当前做 HA 切换时,必不可免会涉及到时间重启、主从切换这些操作,这些操作都会导致业务对实例的连接断开。虽然目前通过上层负载均衡服务来避免切换影响业务访问地址问题。但单一的负载均衡服务是没办法做到连接保持,所以需要验方来做重连机制,才能够在 HA 发生之后恢复对数据库的访问。现在有计划在增加 Proxy 模块来实现连接保持,从而解决 HS 用户连接断开问题。再往前一步,Proxy 加入也为后续实现自动读写分离等特性提供基础。另外,跨可用区、跨地域容灾也在计划中进一步提升数据库服务可用性特性。
保障业务高可用
在介绍完利用计算存储分离架构优势带来的高可用优化之后,接下来聚焦快速扩展这个产品特性给业务高可用带来的价值。
在通常的在线业务服务上,最容易碰到的场景是超出预期的流量突增,从而给整个系统带来非预期的请求压力,这种压力很容易会传导到数据库服务上,从而造成数据库性能的瓶颈。出现这样场景时,对于业务方来说,可能最迫切的需求就是快速加大数据库实例规格,或者增加备实例来应对数据库压力,解决业务可用性问题。这个时候数据库实例扩展的耗时就会极大影响业务的可用性。
在常规主备模式下,加入一个新备实例或进行主实例跨机迁移时,是需要串行完成两个步骤,第一个是通过 basebackup 去同步数据,另一个是同步后的数据恢复。这两个步骤,尤其是同步数据耗时是和数据量的大小呈正比。例如用 1TB 数据量的一个数据库来举例,在机器带宽为 25G 前提下,需要至少 5 分钟才能完成数据同步,而伴随着数据库数据量越大,这一步花费时间会变得更长。另外在云上,一个宿主机上往往不只会部署一个数据库实例,考虑到对于整个宿主机的影响,我们不可能满带宽进行数据同步,所以真实时间往往会变得更长,这样同时也就意味着我们恢复业务可用性的耗时会变得更长。
在 TDSQL-C PG 版产品下,这里会有什么样改善?在 TDSQL-C PG 版产品下,我们的主备实例会共用远端存储,这意味着新增实例时,只需要增加计算节点,而无需经历耗时最长的数据同步过程。同时不需要数据同步,就意味着集群数据量增长并不会导致整个耗时增加。整个新增实例耗时等同于启动一个新的 PG 实例进程。我们可以将整体的耗时缩小到秒级,以最快的速度来满足业务对于快速扩展的需求。另外,TDSQL-C PG 版最大是支持 15 个备实例,备实例可以按照业务需要分配到不同负载均衡组提供给业务使用,最大满足业务对读取性能的灵活要求。
基于以上特性,可以快速满足业务对数据库的性能调整要求,但在整个过程中,还需要依赖于业务方对于数据库使用情况的监控以及时的介入操作来完成扩容,从整体上来说,还是要靠人工来保证可用性。那么是否有更好方案可以在无需人工介入操作的情况来解决这种问题?答案就是 Serverless。
Serverless 是云原生发展的一种高级形态,能够充分展现云原生能力,让用户更专注于业务上,而无需关心资源情况。在 Serverless 模式下,我们计算节点性能会跟随业务流量进行自动调整,当业务流量上升,对于数据库计算资源需求增加时,会自动提高计算节点资源规格。而当业务流量下降时,对于资源需求减少的时候,会自动降低计算节点的资源规格。
在存储方面,TDSQL-C PG 本身就是按 Segment Group 来分配存储资源,当发现现有的存储资源不够用时,就会自动新分配 Segment Group 来满足业务对于数据存放的需求。从而在整个数据库服务上,实现了资源自适应,用户完全无需关注资源情况,避免需要人为介入才能保证业务高可用场景。另外在使用成本上面,Serverless 是完全按需使用收费的。流量低时,实际规格低,费用自然也就跟着下降。相比于人为去调整实际规格,在费用上面也会有大幅度节省。