写点什么

机房容灾:服务部署最佳实践

作者:焦振清
  • 2024-01-16
    北京
  • 本文字数:2351 字

    阅读完需:约 8 分钟

每当新上线系统的时候,如何从部署角度确保障服务的高可用,便成为大家都比较关心的话题。本文从部署角度(在不考虑变更的情况下),给出了一些建议。

1)消除单点

考虑到硬件故障率是一个相对恒定的值,因此单点问题就成为部署中较为常见的服务故障场景。随着大家对稳定性的重视,一个模块仅部署一个实例这种问题虽然还偶尔发生,但整体来说还是在大幅减少。随之而来的,是单点问题开始以更为隐蔽的形式出现

  • 分布不均:3 个实例分布在 2 个机房,服务开启就近访问/流量隔离,此时单机房单实例挂掉,流量可能受损

  • 集群分组:分组中出现单点,例如一个集群 15 个实例,两个实例一个分组承接特定的流量,则会出现某个分组只有一个实例的情况

  • 主备模式:不论是冷备模式还是热备模式,常态下非主如果不处理实际流量,当主故障期间,主备切换可能不生效

2)保持一致性

这里的一致性并非狭义的服务运行环境,其涵盖了整个基础架构,包括但不限于网络、硬件、BIOS、操作系统、内核参数、基础软件、防火墙规则、负载均衡配置、模块的运行环境(如 JDK)等,以及模块自身的相关内容,如程序版本、配置文件、环境变量、数据、SDK 和依赖包等。虽然容器在一定程度上减少了这类问题,但也主要集中在运行环境和程序上,其他环节出现不一致问题后,依然会导致巨大的定位成本。可以通过配置管理工具对运行环境进行管理和周期性维护,确保集群中所有节点的配置始终如一。

3)故障域分组

故障域分组是指将一个系统或网络划分为多个独立的故障域的过程。通过隔离故障点来限制故障的影响范围,从而提高系统的稳定性。当一个故障域内的组件发生故障时,其他故障域应能够继续正常运行,而不会受到故障的影响。通常,我们会按照机房进行故障域分组并在公司内进行统一。任何变更操作(无论是硬件,软件和网络)都不应该同时跨多个故障域进行,故障域才有其存在的意义。

在公司统一的故障域分组之下,不同的场景还可以定义更细粒度的故障域分组和标准故障域进行结合,从而起到更好的效果。以服务部署为例,在保证多 AZ 部署的前提下,在单 AZ 内,还可以定义交换机为故障域分组,同一服务的不同实例,分布在不同的交换机下,还可以避免单个交换机故障导致的服务稳定性问题和风险。

公有云产品的置放群组/高可用组,就是为了提高业务的稳定性,在服务创建时,将实例按照故障域强制打散,以降低底层硬件/软件故障给业务带来的影响。



4)流量隔离

服务部署除去按照故障域分组外,还可以将流量基于租户、重要性、地域、读写特点、队列、资源、数据、环境及机房等特征,进行分组独立部署。通过流量隔离,可以将异常流量限制在一定的范围内,从而避免全局故障的发生,是稳定性保证的重要手段。这些隔离形式可以单独使用,也可以组合使用,以实现更好的效果。

5)弹性伸缩

弹性伸缩从稳定性角度来讲,主要是解决了无状态服务快速扩容的问题。对于大部分服务来讲,如果镜像包体积适中、启动和预热时间可控,一般都可以在 5min 内完成快速扩容,对于大促,机房故障等灾难场景,能够起到很好的保障效果。同时,对于流量具有潮汐特点的服务,启用弹性伸缩也能进一步优化成本。对于无状态服务,推荐把弹性伸缩功能都用起来,通过设置最大实例数避免账单爆掉,设置最小实例数确保必要的实例规模,同时控制扩缩容的步长避免把上下游依赖打垮即可。

6)负载均衡

负载均衡是每个服务都会面对的问题,基于不同的业务场景,会有不同的负载均衡策略如轮询,加权轮询,最小连接数,一致性 hash 策略等。需要正确配置探活机制(不能仅依赖于端口探活)、负载均衡策略、异常实例摘除策略、超时重试配置,并进行验证确保效果符合预期。基于故障域分组的思路,建议最好在两个机房申请两个 VIP,避免单个机房故障的风险。

7)同城双活

目前绝大多数公司均停留在同城双活的水平,同城双活在部署形式上有两种类型,但不论何种形式,一旦发生机房故障,均需要有大量的切换操作,只是组件的切换方式在自动化程度上有所不同而已,对于规模较大的公司来讲,单个机房故障需要执行的切换操作达到数万个。

  • 单集群多 AZ 部署:多见于 Zookeeper、Kafka、HDFS、Mysql 等数据类服务。对于此种部署形式,读操作可以大部分都可以做到同机房访问,写操作还是需要跨机房访问主的。因此,在机房故障的场景下,这类组件都需要进行主从切换。

  • 多集群多 AZ 部署:如 Redis 等对延时敏感的服务,对于此种部署形式,如果是双活集群,那么读写都在本机房进行;如果是热备集群,那么读写都只在其中一个集群,热备集群通过单向数据同步保持一致,在机房故障的场景下,也是需要进行切换的。



8)就近访问

就近访问从稳定性角度来讲,主要是实现机房维度的流量隔离,尽量减少跨机房流量,从而能够很好的应对跨机房网络抖动拥塞,以及机房故障的场景。同时,避免了跨机房交互,网络耗时会降低,因此也会提升系统整体的吞吐能力,进而降低整体的成本。在实际工作中,就近访问的建设往往会作为同城多活的一项关键能力进行落地,从而确保同城多活的效果。

9)N+1 冗余

一个系统做到同城双活或同城多活,和这个系统具备多少冗余度并无直接关系。

N+1 中的“N”指的是处理请求所需要的资源容量,“1”指的是防止任一机房故障所做的资源冗余。N+1 会导致一定的资源冗余,合理设置 N 的数量从而综合考虑稳定性和成本等方面寻求平衡点,因此 N 也并非越大越好。

Google 很早就具备 N+2 冗余,之所以有 2 个冗余机房是因为 Google 会定期的对整机房进行升级维护,在升级维护的过程中,依然还需要一个机房来支撑其冗余度,这是 N+2 的由来。当然了,Google 的全球机房数量足够多,这时候虽然是 N+2 的冗余度,但其冗余的绝对值比例并不高。

10)异地多活

目前国内成熟案例主要是在服务器规模超过百万量级的公司,其异地多活的动力也是因为在一个城市无法在可控成本下找到足够多的 IDC 资源,因此不得不进行异地多活的部署。

发布于: 刚刚阅读数: 5
用户头像

焦振清

关注

让运维因我们而不同! 2018-12-04 加入

架构师

评论

发布
暂无评论
机房容灾:服务部署最佳实践_服务部署_焦振清_InfoQ写作社区