如何构建分布式系统的知识体系

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lijingyao8206/article/details/82319941

对于开发工程师们来说,相信对于这种招聘要求的描述并不陌生:”熟悉分布式系统的设计和应用;熟悉分布式、缓存、消息、搜索等机制;能对分布式常用技术进行合理应用,解决问题”。
现在基本上大多数大、中型企业都会要求工程师们,除了要能在分布式环境中进行开发,还要了解其中的原理、机制,对于架构师来说还需要能够独立设计分布式系统。

分布式(计算机)系统的概念起源很早,目前已经基本涵盖了大多数系统架构设计。无论是SOA架构,或者微服务、Serverless架构,都是基于分布式环境的。掌握分布式系统的知识体系是理解很多架构的基础。比如日益盛行的微服务架构,也是基于分布式计算环境。设计分布式系统中需要解决的问题,对于微服务架构也是一样。如果基于容器技术,比如Docker容器来部署微服务实例,那么还需要了解跨容器平台的服务治理。

本文主要谈谈,分布式架构体系的几个核心内容。开发工程师们可以根据这些内容,逐渐积累和构建自己的知识体系,并往技术架构方向迈进。

分布式知识的核心模块

分布式系统最开始是起源于分布式计算机的概念,随着信息技术的发展,需要处理的数据以及计算已经超过了单台计算机能够扩展的系统资源。将数据、程序分散到多台计算机,通过一定的通信机制进行数据传输、共享,便产生了分布式的计算机系统。分布式计算发展至今,衍生了SOA、微服务等架构模型。

在资源的利用方面,最早期的分布式计算是无共享系统资源的,机器与机器之间通过网络通信进行分布式数据共享。后期随着虚拟机技术的发展,一台机器可以运行多台虚拟机,它们可以共享机器的硬件资源,节约维护成本。而今,更加流行的容器技术可以只基于一个操作系统内核,而不需要整个操作系统的资源,一台机器可以部署更多的容器实例(比如Docker,一台机器可以部署上千个Docker容器实例),并且实例之间像独立的操作系统一样独立运行、计算。

可以看出,随着数据和计算规模的增长,分布式系统是朝着越来越轻量级的资源利用,以及越来越细粒度和松耦合的服务化方向发展的。

分布式系统发展至今,从技术架构的角度来说,核心模块主要是: 存储服务通信和服务治理 以及 分布式事务。这三个模块的每一部分都涉及到很多知识点以及实践中需要解决的分布式问题。设计一个分布式系统,在技术架构上只要能处理好这三个模块,其余部分便是具体的 架构模型选择(如: SOA、微服务、Serverless等)、架构思想选择(如: 分层的思想、事件驱动的思想、DDD思想等)以及应用层面的中间件和框架的选择(如:会有哪几种开发语言,基于哪种服务间通信协议、用什么框架集成)。如下图简单列举:

分布式系统知识体系

核心知识模块

  1. 分布式存储
    在分布式系统中,尤其是数据密集型应用会涉及到很多分布式存储技术。分布式的存储主要有两个方向的知识模块,一个是数据复制,也即一个数据在多个节点(Data Node)有相同的数据副本。另一个是数据分区,将大数据模型拆成多份到多个节点(Data Node)。这两个方案都可以提高系统的吞吐量,并且也是一种容灾备份的考量。不同的存储引擎、技术中对于复制、分区实现各有不同,但是核心的算法和分布式计算模型是相通的。
    一般来说开发工程师很少去自己研发一套类似Redis、MongoDB、DynamoDB这样的存储系统,但了解这些技术的共通的原理和机制,可以帮助我们更好地使用,以及分析各种分布式问题。

    1.1 复制
    数据复制有两种复制模型:同步,以及异步同步复制一般是阻塞的,可以保证所有的数据节点都保持有一致的数据副本,但是吞吐量低;异步复制是非阻塞的,在数据保存到主库后请求便立即返回,主库和其他从库之间的数据采用异步的方式进行同步,一致性模型上保证了最终一致性
    从数据节点的角色分配来说,最简单的数据复制方案即是“主-从”复制。通过数据复制,可以使存储服务拥有备份,当主库挂掉时可以将数据读写请求切换到从库。如果遇到网络故障,主,从节点都无法提供服务时,基于“主-主”复制的多数据中心便可以解决。但是,越复杂的数据节点结构需要处理的问题也越多,比如不同数据节点的读写一致性问题,多个主节点都接受写请求时,写数据冲突的解决等。
    不同的存储技术的数据复制的实现,以及支持的复制策略会有所区别,学习数据复制相关的知识可以通过不同存储引擎的官网以及找一些经典的论文资料。这里举个简单的例子,比如Mysql的集群方案,可以看看Mysql 数据复制实现细节mysql集群数据复制方案

    1.2 分区
    数据复制相当于同一个数据源的相同副本存储在不同的数据节点中,数据分区是将一份数据源以一定的规则拆分成多份,也是分布在不同的数据节点中。简单来说,复制等于将数据文件copy到不同机器上,分区是将大的数据文件以一定的规则拆成一个个小的文件,分散到不同机器上。数据分区往往可以和数据复制结合使用。
    很多数据存储引擎都自带分区功能(如PostgreSQL,Mysql,Oracle),分区功能对开发者是透明的。除了分区,另外一个常用的将大数据拆成小数据集的方式就是分表,一般是基于索引设置一个路由规则,比如取模,将一个数据表进行拆分。分表和分区的实现上以及场景上有所区别,也可以同时使用。这两者都可以提高数据访问的速度,并且扩展性高。

    总结来说:在分布式环境下,随着数据量增大,性能的压力以及扩展性的需求,在存储服务层可以做的技术方案主要是数据复制、分区。复制和分区一般都是很多存储服务内置的功能。从应用层或者中间件层来说,还可以采用分表(有的存储服务也自带分表,或者通过插件的方式支持分表),分表属于水平拆分,在业务上还可以做垂直拆分,比如将一个大表拆成有外键关联的子表,将占用数据空间大的字段拆到其它表等方式。
    分区中重要的知识点主要是分区策略的实现,不同的存储引擎支持的策略不同,但是基本的分区方案策略实现是大同小异的,学习分区时可以先以一个数据库为切入点,比如Mysql 5.7 分区概要。想要从宏观角度来了解分布式解决方案时,可以看看Distributed systems for fun and profit 系列文章。如果想要体系化学习分布式数据存储系统的方案,推荐看《Designing Data-Intensive Applications》,这本书从浅到深介绍了分布式数据集群的方案,并对一些问题的解决机制和原理都有深入介绍。

  2. 服务通信和服务治理
    分布式系统中,服务实例部署在不同的节点,服务间的通信可能跨操作系统或者容器。随着容器技术的发展,服务治理已经成为了容器服务的重点技术领域之一。服务通信和服务治理关注的问题点以及应用的技术各有不同,但目前有很多分布式技术集成了这两者(如Kubernates,Consul 1.2版本开始支持 Service Mesh)。

    2.1 服务通信的基础是:服务发现、服务注册、健康检查。无论是SOA架构或者微服务架构,都需要通过服务名(service name)定位到服务实例的“IP:Port”。SOA一般由企业总线来集成这些功能(比如Dubbo基于Zookeeper)。在基于容器的微服务架构下,可以使用类似Consul、Eureka、Etcd等更加轻量级的服务发现技术。学习的时候,可以先了解这些技术的共通点,以及经典理论,比如CAP理论FLP不可能结果理论。然后再学习这些技术背后的原理和机制。比如服务发现和服务注册机制,不同的技术使用的一致性算法不同,Zookeeper基于Zab算法,Zab又基于Paxos算法做了很多改进;Etcd、Consul 基于 Raft算法,在CAP理论中,Zookeeper、Etcd以及Consul 都保证了CP。而 Eureka舍弃了严格的一致性,选择了AP。这些技术的知识的学习可以从官网以及Github中找到项目源码。

    2.2 分布式消息队列。对于SOA架构、微服务架构来说,消息队列可以用来进行服务间的解耦,并且提升请求响应的性能。在学习消息队列时,需要先对网络通信的知识打好基础(网络协议、编解码机制,底层框架和原理等),分布式消息队列的存储也是关键。最好先从工作中接触到的MQ进行学习,或者选择社区活跃的开源MQ:如Kafka、RocketMQ、RabbitMQ等。

    2.3 服务治理。服务治理在SOA架构中类似于企业总线涵盖的功能。容器技术里比较出名的服务治理技术是Kubernates。对于小规模集群来说,不是在一开始就需要服务治理,随着容器规模、服务体系的增长以及团队的扩充,才开始考虑是否需要构建服务治理平台。服务治理包含了熔断机制、流控机制、服务监控、负载均衡、容器的透明化管理、服务实例的动态扩容缩容等等。如果不用一个服务治理技术,一开始也可以手动“治理”加上一些有熔断、负载均衡的框架(如ribbon,hytrix)来集成到应用。服务治理包含的模块很多,不同技术的实现标准也不同,学习过程应该实践大于理论,如果对Docker比较感兴趣,可以结合Kubernates官网和Github源码进行学习,国内的社区可以多看看 k8s中文社区

  3. 分布式事务

    对于设计大型分布式系统,分布式事务基本上是必须要面对的一座大山。理解分布式事务,除了从应用系统的角度出发,还可以从更源头概念来理解。比如,数据库存储系统的事务特点,不同隔离级别的实现。分布式应用系统很难像存储系统一样满足完整的事务特性,比如2PC的解决方案,可以满足原子性,但会牺牲性能。所以对原子性、一致性要求不严格的场景,更多是基于BASE理论。BASE理论适用在很多NoSQL系统中。NoSQl更多的关注点不是保证事务ACID的特性,而是性能、吞吐量、扩展性以及可用性。BASE也同样适用于业务类型的分布式系统。对于分布式事务,简单列举下学习Route:

    3.1 了解关系型数据库的事务的特性,尤其是不同的隔离级别。可以从自己最常用的数据库着手,了解该数据库的隔离级别在哪种并发场景会出现哪些读、写数据的问题。这方面的知识需要去一些官网,找对应版本的资料。比如PostgreSQL可以去看下PostgreSQL 事务隔离级别介绍

    3.2 针对工作中平常使用的NoSQL技术,或者自己想学的NoSQL,了解它们是怎样利用集群的特性实现高可用和高可扩展性。对于一些通用的实现,可以看看经典论文。比如Dynamo的这篇论文Dynamo: Amazon’s Highly Available Key-value Store。Google 的BigTable论文:Bigtable: A Distributed Storage System for Structured Data。在一些论文里,可以了解到NoSQL系统是怎样实现BASE理论,以及对于CAP中一致性模型取舍的考量。

    3.3 在实践方面,基于X/Open(XA)标准的实现较多,但XA属于2PC模型,保证了原子性,但是会降低系统的吞吐量,适用于一致性、原子性敏感的业务。基于BASE理论的TCC模型,以及基于可靠的分布式消息队列的模型现在越来越成为主流的分布式事务解决方案。这些知识点是比较零散的,不同的公司使用的方案各不相同。学习的时候可以先对这些方案的实现以及可能存在的问题进行整体的了解(网上的资料很多,最好找到可靠的学习资料,比如Gitchat上有一些课程和chat)。然后在遇到具体场景时需要对业务进行充分的分析,然后决定使用哪种方案。

如何构建知识体系

分布式系统的知识点很多,除了分布式的重要理论(CAP、BASE、FLP不可能理论)、共识算法(Paxos、Raft、ZAB),还要了解一些开源的高性能、高可扩展的分布式NoSQL技术(如Dynamo,MongoDB,Redis)以及关系型数据库集群的数据复制、数据分区的方案和实现机制(Mysql、Oracle、PostgreSQL)。实践中还会需要知道分布式事务的解决方案(2PC、3PC、TCC)。面对庞大的知识体系,可以将知识模块进行拆分,然后逐个攻破。
在学习的时候,可以针对各个知识点尝试下面的方法:

  1. 利用碎片时间了解知识点:多在一些活跃的社区上订阅分布式系统的文章,微服务架构方面可以多阅读 microservicesGitchatCSDNInfoQDockerOne中关于分布式知识的文章可以每天读上一两篇,更加零散的时间可以阅读一些技术公众号的文章。

  2. 针对知识面进行体系化学习:进行体系化的学习可以先设定一些目标,比如一个月之内针对某一个知识模块,阅读完某本书或课程、论文,并对重点知识进行自己的梳理。
    关于分布式知识推荐一些资料,《Designing Data-Intensive Applications》这本书对数据密集型系统以及分布式的存储体系,从问题的引出到各种解决方案的介绍都非常详尽,虽然是英文版但是易读性强。Distributed Systems for fun and profit,其中包含了5篇文章,分别讲述了分布式的一些问题和概念,作为初步了解是很好的资料。《分布式计算——原理、算法与系统》这本书对很多分布式的概念,问题从数学和理论角度介绍得全面细致,需要一定的数学基础。
    同时,隆重推荐下自己的课程:《分布式微服务架构体系详解》。该课程基于自己多年的分布式开发及微服务架构经验,从分布式场景和问题出发,为大家逐一展开介绍实施微服务架构的分布式核心知识体系。
    该系列课程还包含基于Springboot、SpringCloud(Microservice)、RxJava(API-Gateway)的两个工程源码,以及 Docker 镜像的基础 build 文件。源码放在Github上。链接 :MicroserviceGateway。购买课程的读者可以在读者圈提问或留言。没有购买的读者也可以在Github上提Issue一起探讨。感谢各位支持 OvO。

    分布式微服务架构体系详解

猜你喜欢

转载自blog.csdn.net/lijingyao8206/article/details/82319941