最近看《架构即未来》(The Art of Scalability),结合自己目前的工作,发现比很多年前看第一版的 时候有更多切身的体会。很一般的博客、新闻介绍扩展性的结构不同,这本书2/3的篇幅并非教读者如何切分、 如何拆分,水平还是垂直等等,而是再说组织架构,怎样设置团队,怎样规范架构的流程,各个部门的责任等。 在看第一版的那个时候,这部分我可能就直接忽略了,但是现在有了亲身体会之后,发现大部分的问题,即使 表现为技术问题,甚至是低级失误,其实根源都是管理方面的问题:责任分配不清晰,资源不足,决策草率缺 乏长远考虑,等等等等。这些问题,如果没有经验,在解决了我们熟悉的基本的扩展性问题之后就会慢慢遇到, 从宏观角度看这些恰恰是真正制约扩展性的关键因素。
不过今天并不是想写这个。书中后半部分介绍了一个衡量扩展性的 AKF 立方体模型,把关于扩展性的问题抽象 得很精致。这个模型用 X/Y/Z 三个轴表示扩展的三个不同方向。其中
- X 轴表示同等职责、同等分工下的拆分扩展,这种扩展可以通过单纯的拷贝实现业务能力的扩大。
- Y 轴表示通过对职责的细分,将不同的职责拆分到不同的单元,从而实现处理能力的扩大。
- Z 轴表示对客户、来源的切分,实现业务的隔离,从而扩展业务能力。
上面我自己的概括可能比书上的还要抽象,没关系,举一个团队的例子:
- 在公司初创的阶段,所有的工程师除了日常的开发,还要担负技术支持和运维等工作职责。在这个阶段,增加 这样的工程师的数量,就是在 Y=0, Z=0 的方向上,进行 X 轴的扩展。
- 当业务量增加时,引入了专门的技术支持工程师、销售工程师、运维工程师的专业角色,将原来人员的职责细化。 这是在 Y 轴上进行扩展。这时可以根据各个业务类型的需求不同,分别增加工程师的数量,就实现在 X/Y 轴两个 方向上的同时扩展。与单纯的 X 轴扩展相比,这时扩展的粒度更细,针对性更强(并不需要为了引入一个销售工程师, 而按照最初的标准招聘一个全能的工程师)。
- 当业务进一步发展时,可以根据服务客户的地域、行业类型等,对团队进行进一步的划分,这就是在 Z 轴上的 扩展。例如,可以根据市场就近的原则,在广州、上海、北京分别设立办事处,支持附近市场的扩展。
从这个角度说,这套模型并非仅仅描述软件架构的问题,实际也适用于其他方面。重新回到软件结构,用我们都熟悉的语言来说。
X 轴的扩展性解决的是最基本的问题,即一个服务能否扩展。通常,通过一个负载均衡设备就可以将业务分别分配 到后端不同的实例上,就解决了 X 轴扩展的问题。如果在 X 轴都完全无法扩展的话,说明架构有严重的问题, 完全不能工作。单纯的 X 轴扩展,用现在的话说就是 monolithic 的系统,这种系统粒度大,内部耦合性强。
针对这个问题,引入了 Y 轴的扩展,将业务细分。也就是前些年说的面向服务的架构 SOA,和这些年所说的 微服务的架构。这种架构在系统上、业务上、团队上都按照功能职责(动词)进行细分,解除各部分之间的耦合。 在这个基础上,每个细分的模块也必须具备 X 轴扩展的能力。
Z 轴的细分是根据客户细分,将不同个客户隔离开,同时也达到了故障隔离的目的。这样系统的故障不会蔓延到 整个业务上。Z 轴的扩展成本较高,不同的分区负载可能差别很大。
以我们目前的消息系统为例,开发初期我们主要关注的也是单纯 X 轴的扩展,这个阶段业务本身的规模有限, 开发者本身对业务的理解和分析能力也不足。所有的功能都集中在单一的系统上,这个系统不仅负责客户端连接 的管理,消息解包等,还要处理很多业务逻辑。
很快在发展两年后就出现了 monolithic 的弊端:
- 代码变大,还在很快变得更大
- 耦合性强
- 部署规模过大,不灵活
- 扩展粒度太大,浪费资源
这时我们开始未雨绸缪,考虑将业务细分:
- 登录授权子系统,动词 login
- 消息转发子系统,动词 forward
- 消息存储子系统,动词 save
这些子系统的关注点、性能瓶颈都不同,在分别执行 X 轴扩展时,需要的资源也与原先的单一系统不同。同时拆分 后的子系统有了更灵活的部署周期,可以快速修复问题。而这些系统本身,通过我们内部的服务框架、服务发现机制和 资源调度机制,也可以轻松实现基于 X 轴的扩展。
但是 Y 轴的扩展不是一蹴而就的,而是需要一个过程。对于可以归属给子系统的新功能,直接在子系统上开发。 对已有的功能需要逐步地、谨慎地将原先单一系统中剥离。这部分的功能还在进行中,但是主要的障碍都已经解决, 后续的进展是比较乐观的。
而作为一个云服务,在 Z 轴的扩展也是十分必要的。但是目前来说,由于本身灵活没有状态,我们还没有完全 地实现 Z 轴方向的切分。一方面,Z 轴的扩展需要较高的成本,在资源有限的情况下,如果按照 Z 轴切分 会导致比较明显的不均衡和浪费。但是在 Z 轴方向,我们也积累了运维的经验,例如对重点用户的高峰时段进行 专门的隔离,尽可能避免多租户环境下 noisy neighbor 的问题。但是目前的机制仍然依赖手动的调度, 相比 X 轴和 Y 轴目前的进展,Z 轴算是刚刚迈出第一步。
可以说这三个方向的描述,基本上阐明了扩展性这件事的核心。书中也提到,并非所有的业务所有的公司都需要在三个方向上同时扩展。 有的只需要在 X 轴上扩展就可以支撑业务。所以 X/Y/Z 三个轴表示三个潜在的方向,也并非强制需要达到。