分布式技术1:概述和历史

😀
前言:本文总结主要描述分布式技术是什么和发展的历史。

分布式系统概述

为什么需要分布式系统

  • 增加系统容量:随着业务量越来越大,为了应对愈来愈大的业务量,单台机器无法满足,就需要多台机器。同时需要采用垂直或水平的方式拆分业务系统,让其整个系统变成分布式的架构。
  • 加强系统的可用:系统业务越来越关键,需要提高整个系统架构的可用性,这意味着架构中不能存在单点故障。整个系统不会因为一台机器故障而导致整个系统不可用。所以需要通过分布式架构冗余系统来达到消除单点故障,从而提高系统的可用性。
🎤
不过所有的技术都不是“完美的”,都只是一种权衡。所以,我们在遇到分布式系统的问题A尝试解决时,也可能带来了问题B、C等。因此这就需要我们非常清楚的知道分布式系统所带来的问题。

分布式架构和单体架构的优缺点

notion image
总的来说,分布式系统架构难点在于系统设计,以及管理和运维。所以,分布式架构解决了最初的“单点”和“性能容量”问题,但是新增了一堆问题,同时还会衍生更多的子问题,然后这就需要我们不断的使用各种不同的技术手段来权衡解决这些问题。

分布式系统的发展历史

  • 20世纪70年代:模块化编程
  • 80年代:面向事件设计
  • 90年代:基于接口/构件设计
  • 演化出了SOA-基于服务架构:构造分布式计算计算应用程序的方法
    • SOA架构将应用程序功能作为服务发送给最终用户或者其他服务。它采用开放标准与软件资源进行交互,并采用标准的表示方式。开发、维护和使用 SOA 要遵循以下几条基本原则:
    • 可重用,粒度合适,模块化,可组合,构件化以及有互操作性。
    • 符合开放标准(通用的或行业的)。
    • 服务的识别和分类,提供和发布,监控和跟踪。
  • 后面SOA思想一直延续发展,现在叫分布式服务架构
    • notion image
    • 20 世纪 90 年代前:是单体架构,软件模块高度耦合。当然,这张图同样也说明了有的 SOA 架构其实和单体架构没什么两样,因为都是高度耦合在一起的。就像图中的齿轮一样,当你调用一个服务时,这个服务会调用另一个服务,然后又调用另外的服务……于是整个系统就转起来了。但是这本质是比较耦合的做法。
    • 而 2000 年左右出现了比较松耦合的 SOA 架构,这个架构需要一个标准的协议或是中间件来联动其它相关联的服务(如 ESB)。这样一来,服务间并不直接依赖,而是通过中间件的标准协议或是通讯框架相互依赖。这其实就是 IoC(控制反转)和 DIP(依赖倒置原则)设计思想在架构中的实践。它们都依赖于一个标准的协议或是一个标准统一的交互方式,而不是直接调用。
    • 而 2010 年后,出现了微服务架构,这个架构更为松耦合。每一个微服务都能独立完整地运行(所谓的自包含),后端单体的数据库也被微服务这样的架构分散到不同的服务中。而它和传统 SOA 的差别在于,服务间的整合需要一个服务编排或是服务整合的引擎(可以是工作流引擎,也可以是网关。当然,还需要辅助于像容器化调度这样的技术方式,如 Kubernetes。在 Martin Fowler 的 Microservices 这篇文章中有详细描述)。就好像交响乐中需要有一个指挥来把所有乐器编排和组织在一起。
  • 微服务的出现使得开发速度变得更快,部署快,隔离性高,系统的扩展度也很好,但是在集成测试、运维和服务管理等方面就比较麻烦了。所以,需要一套比较好的微服务 PaaS 平台。就像 Spring Cloud 一样需要提供各种配置服务、服务发现、智能路由、控制总线……还有像 Kubernetes 提供的各式各样的部署和调度方式。

分布式系统的实践案例

亚马逊的实践,有哪些难点

💡
在 2002 年的时候,亚马逊 CEO 杰夫·贝索斯(Jeff Bezos)就向全公司颁布了下面的这几条架构规定(来自《Steve Yegge 对 Google 平台吐槽》一文)。
  • 所有团队的程序模块都要通过 Service Interface 方式将其数据与功能开放出来。
  • 团队间程序模块的信息通信,都要通过这些接口。
  • 除此之外没有其它的通信方式。其他形式一概不允许:不能直接链结别的程序(把其他团队的程序当作动态链接库来链接),不能直接读取其他团队的数据库,不能使用共享内存模式,不能使用别人模块的后门,等等。唯一允许的通信方式是调用 Service Interface。
  • 任何技术都可以使用。比如:HTTP、CORBA、Pub/Sub、自定义的网络协议等。
  • 所有的 Service Interface,毫无例外,都必须从骨子里到表面上设计成能对外界开放的。也就是说,团队必须做好规划与设计,以便未来把接口开放给全世界的程序员,没有任何例外。
  • 不这样做的人会被炒鱿鱼。
采用分布式系统后会有很多的问题,比如
  • 一个线上故障的工单会在不同的服务和不同的团队中转过来转过去。
  • 每个团队都可能成为一个潜在的 DDoS 攻击者,除非每个服务都要做好配额和限流。
  • 监控和查错变得更为复杂。除非有非常强大的监控手段。
  • 服务发现和服务治理也变得非常复杂。
亚马逊通过多年实践让其可以运维和管理极其复杂的分布式服务架构。陈浩叔认为主要有下面的点。
  1. 分布式服务的架构需要分布式的团队架构。在亚马逊,一个服务由一个小团队(Two Pizza Team 不超过 16 个人,两张 Pizza 可以喂饱的团队)负责,从前端到数据,从需求分析到上线运维。这是良性的分工策略——按职责分工,而不是按技能分工。
  1. 分布式服务查错不容易。一旦出现比较严重的故障,需要整体查错。出现一个 S2 的故障,就可以看到每个团队的人都会上线。在工单系统里能看到,在故障发生的一开始,大家都在签到并自查自己的系统。如果没问题,也要在线待命(standby),等问题解决(我在《故障处理最佳实践:应对故障》一文中详细地讲过这个事)。
  1. 没有专职的测试人员,也没有专职的运维人员,开发人员做所有的事情。开发人员做所有事情的好处是——吃自己的狗粮(Eat Your Own Dog Food)。自己写的代码自己维护自己养,会让开发人员明白,写代码容易维护代码复杂。这样,开发人员在接需求、做设计、写代码、做工具时都会考虑到软件的长期维护性。
  1. 运维优先,崇尚简化和自动化。为了能够运维如此复杂的系统,亚马逊内部在运维上下了非常大的功夫。现在人们所说的 DevOps 这个事,亚马逊在 10 多年前就做到了。亚马逊最为强大的就是运维,拼命地对系统进行简化和自动化,让亚马逊做到了可以轻松运维拥有上千万台虚机的 AWS 云平台。
  1. 内部服务和外部服务一致。无论是从安全方面,还是接口设计方面,无论是从运维方面,还是故障处理的流程方面,亚马逊的内部系统都和外部系统一样对待。这样做的好处是,内部系统的服务随时都可以开放出来。而且,从第一天开始,服务提供方就有对外服务的能力。可以想象,以这样的标准运作的团队其能力会是什么样的。
 
声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

Previous

RAG的三个阶段:Naive RAG、Advanced RAG和Modular RAG

Next

理解:高内聚、低耦合