什么是分布式架构(一) - youngperson/study-100 GitHub Wiki

  • 分布式介绍
    • 概念:单机已经无法处理,把服务拆分成了多个服务,组成一个分布式的服务来完成之前单个服务的功能

    • 举例:搜索引擎、搜索服务是一个标准的分布式场景


  • 对代码的认识
    • 代码由数据结构 + 算法组成,用来处理数据。可以认为代码就是函数。

    • ps:有函数式编程,并且从数学上也证明了纯函数式编程也能完成所有的算法。

    • 代码做的事情是,给一个数据作为函数的输入,通过函数计算,返回一个数据作为输出

    • ps:在输入、处理、输出的过程中可能会需要存储一些数据到外部存储器中,提供给日后使用


  • 对服务的认识

    • 服务是由代码片段(函数)组合起来 + 外部的存储数据

    • 如果一个代码片段(函数)抽象为y=f(x),那么服务可以抽象为y= f(g(h(u(x))),代码片段的组合

  • 小结:

    • 服务 = 代码片段的组合(函数) + 外部的存储数据

    • 代码片段(函数) = 输入、处理、输出

    • 一个服务,必定可以拆分成一个一个的子服务,子服务还可以继续拆分,拆分到最后会成一个函数。

    • 我们把一个或者一组函数拆出去单独变成一个服务,那找个服务就变成了一个分布式的服务了(微服务)


  • 为什么要引入分布式
    • 分布式和集群的区分概念

      • 集群是一组协同工作的服务实体,单位时间内提高执行的任务的数量,实现同一业务
      • 将不同的业务分布在不同的地方,缩短单个任务的执行时间来提升效率的,分布式中的每一个节点都可以做集群
    • 一般情况下,集群就已经够用了。集群基本上都是高可用的。

    • 当新增机器组集群的效果不明显的时候,功能耦合较多的时候,我们需要把一个大的服务去拆分成一个一个的小的服务,这个时候就需要分布式


  • 设计分布式架构的2个切入点
    • 服务的功能分布式,比如把一个1000行的函数变成两个500行的函数

    • 数据的分布式,数据太多了导致单个节点放不下,或者是单个节点处理能力不足了。比如对数据分库分表就是一种数据的分布式


  • 业务功能的分布式拆分的3个原则
    • 尽量减少网络开销:分布式的初衷是将计算能力分布到多个节点上而提高整体的响应时间。如果数据传输量大导致网络耗时久,得不偿失。

    • 各个子服务应该是无状态的:调用服务的时候不需要去考虑状态,为了方便调用。编程语言上就是这个服务应该是一个纯函数的服务,一个输入只会有一个输出,不会因为不同的状态产生不同的输出

      • 如果需要考虑状态的话,一般这个状态会存储在某个位置(比如用户的会话状态session存储在Redis中),服务本身并不保存这个状态,用的时候去取
    • 每个子服务都应该是可横向扩展的:分布式的系统一般都得能满足集群的部署,如果每个子服务能满足无状态的话,那么横向扩展就没什么问题了,因为无状态,所以对外来说每台机器都是一样的,调用谁结果都一样,自然就能横向扩展了

    • 小结:拆分的话按照2个大方向去拆,拆好后的每个子系统都能做到上面3个原则的话,基本上会是一个比较好的分布式系统


  • 数据的分布式拆分
    • 单机的数据处理、存储能力达到瓶颈了

    • 数据按照某个唯一标识去hash分布式储,按照业务数据分布式存储等

    • 完全是静态的数据,从始至终都不喝变化,怎么拆都好弄

    • 完全是动态数据,会经常变化,那么这种情况就要考虑各个节点的数据同步


  • 数据拆分和业务功能拆分比较
    • 业务拆分就是一堆函数,不会变化,拆分到哪里都一样,横向扩张没毛病

    • 数据拆分,数据是会变化的。数据拆分需要解决的问题是横向扩展后怎么保证各个相同的节点数据一致性。所以会有很多一致性的理论


  • Log处理数据节点的同步
    • 一致性理论、paxos这种自行去了解,这里讲接地气的基础

    • 这里的Log不是我们服务的日志,日志是用来记录服务的一些信息的,主要用来进行错误排查的,是给人看的,而这里的Log是给机器看的,用来同步数据到各个节点的

    • Log是什么,一条Log是一个带时间戳的消息,这里的消息可以任何东西,比如数据变化啊,某个事件啊,甚至是某个函数操作,任何东西都可以是Log的消息。大家熟悉的数据库的binlog,就是一种Log形式,记录的是数据的变化

    • Log记录了整个系统最关键的东西,那就是这个系统在某个时刻干了什么

    • 作用:数据的重放

      • A节点进行了一系列的操作,产生了5条Log,输出了一个结果R,那么将这5条Log输入到B节点,B节点最后也将输出结果R,这就是重放
      • 任何状态都是由一个事件和一个时间产生出来的,而Log这种简单的数据结构恰好完美的记录了时间和事件,那么任何状态都可以用Log还原出来

  • Log怎么实现
    • 设计:参考MySQL的binlog,结合自己的数据。业务

    • 推荐kafka,是一个高级的Log服务。它支持offset、多订阅模式。比如某个节点同步到一部分数据后挂了,在重启会根据上次记录offset也能重放并同步数据


  • 节点之间通讯
    • 一般很多分布式系统使用RPC这种远程调用再加上一种序列化算法来节省带宽来进行节点间通讯。比如gorpc

    • http也行,但是分布式服务调用中很少这样用