分布式系统(一):概念辨析与逻辑梳理

分布式系统领域的相关知识是每个后端开发人员都会遇到的,并且是很重要的一环。但是最关键的矛盾点在于:

分布式系统领域概念繁杂,新接触的同学或者已经接触一段时间的同学都会被这些概念困扰。

那么解决办法是什么呢?我认为有三点:

  1. 从“点”出发,去理清概念
  2. 从“线”出发,理解相关知识点
  3. 从系统性梳理出发,构建属于自己的分布式领域的知识树

本系列文章,就是围绕这三点而来,当然第3点肯定是靠自己整理的。


说到分布式,大家一定会想到单体应用、集群等等。我们来看看并分析几组名词。

分布式与集群

我们直接下一个通俗的定义:

集群:多台服务器对外提供同样的功能,即每台对外提供的都是相同的功能,所以他们组成了一个集群

分布式系统:多台服务器组合起来对外提供一类功能

这是他们之间的区别,那么联系呢?

集群是分布式系统中的组成部分

再来一组类比即可结束该组概念:

分布式系统可以看做一个公司整体,集群又可以看做是公司中的研发部、市场部、行政部等等部分。研发部对外提供完成需求的功能,市场部对外提供需求对接的功能,而公司作为一个整体,对客户提供服务。

站在客户的视角,他并不需要管你公司是什么架构,只要完成他的需求即可。所谓公司各部门组合起来实现客户需求。

最后,还是上一张图来有个感性认知吧(图拿以前画过的,凑乎用下)

他们组合起来成为了一个简单的分布式系统。

高可用、高性能、伸缩性、可扩展

这四个常见于分布式系统的描述中,我们来看看:

  • 高可用:我想一直用
  • 高性能:我想用的爽
  • 伸缩性:我想邀请更多人来用
  • 可扩展:我想提需求(实际可扩展主要说软件设计上)

其中,高可用、高性能、伸缩性这三个特性我们主要用在分布式系统的“物理结构上”,而可扩展性则更多的用在软件设计上。

这几个名词不再多说,因为下面的概念会直接关联,放在一起说更好。

无状态服务和有状态服务

个人认为,这是最关键的概念区分,可以解决后面很多的问题。

分布式系统中的所有组件都可以划分到这两个概念中

那么,什么是有状态服务呢?

举例:在上图中,我们看到的数据库、缓存都属于有状态服务

那么,什么是无状态服务呢?

举例:在上图中,我们看到的业务服务器和负载均衡都属于无状态服务。

但是,业务服务器真的是无状态的吗?是不是也可以变成有状态的呢?所以,关键点在于二者的区分,如何区分:

首先判断该服务是否存储数据,如果不存储,则一定是无状态的。

如果存储,则假设再来一台同样的设备,他们组成一个集群后,在保证业务正确的前提下,存储的数据是否需要在二者之间进行同步。

应用一下:

对于负载均衡器来说,本身不存储业务数据,所以一定是无状态的。

对于数据库来说,本身存储数据,再增加一台数据库组成集群,那么数据肯定要进行同步,所以一定是有状态的。

对于业务服务器来说,在有的场合下,本身需要将数据存储在内存中,比如一些用户的登录状态。则此时再加入一台业务服务器组成集群,那么登录状态肯定要进行数据同步,所以这种场合下属于有状态的业务服务器。

实际上,有状态和无状态的区分基本一眼就可以看出来,不是一个难点。关键是知道概念即可。

服务状态和分布式系统特性

可靠性

系统可靠性分成两大块,一块是对于有状态服务的可靠性设计,比如数据库系统;一块是针对无状态服务的可靠性设计,比如我们的业务程序。

但是,可靠性的核心解决方案无一例外都是:冗余,各种冗余

其中,有状态服务的难点在于他们之间的数据同步。有状态服务可靠性的实现归纳起来就是通过两个方面:

  1. 复制集群
  2. 独立分片
  3. 将1和2组合实现

复制集群指的是比如搭建两个数据库,他们之间同步备份,其中一个对外提供读写能力,另外一个对外提供读能力(或者只备份)。

独立分片指的是比如搭建两个数据库,一个数据库存储用户ID小于1000的,另外一个存储用户ID大于1000的数据。

不论关系型还是非关系型数据库,或者缓存,都是这样的思路。


而无状态的服务的可靠性,则是依靠负载均衡或者是负载均衡的变种(后面会提到,也即服务治理这一块)来实现的,并且可以分为服务端负载均衡和客户端负载均衡。负载均衡本身又会有单点故障的隐患,所以又有专门的高可用软件保障负载均衡整体的高可靠。

高性能

性能的提升无非是两个方面:

  • 提升单体的性能
  • 通过增加节点并协作提升整体的性能。

这点不论是有状态服务或者无状态服务都是从这两个方面入手,需要具体情况具体说明。

伸缩性

伸缩性的设计就是整体系统对外部压力的自适应表现。

当外部压力过大时,系统可以自动扩容,当外部压力恢复时,系统又可以自动回收多余的节点。这属于自动化的伸缩,云端的弹性伸缩或者Kubernetes集群都可以做到这个要求,这也是为什么Kubernetes是未来云端操作系统的一个重要原因。

如果手动扩容的话,对于无状态服务还是要基于负载均衡及其变种。

但是针对有状态服务,伸缩性就没那么简单了,因为要涉及到数据的同步或者分片存储。

无状态服务的典型分布式结构

前一小节可以看到,一个无状态单体服务想要实现可靠性、伸缩性、高性能就需要进行结构划分。这里的划分分为两种:水平和垂直。水平划分类似下图:

其中,服务器ABC的业务功能都相同。

垂直类似下图:

其中,服务器ABC业务功能不同。

有状态服务的典型分布式结构

有状态单体服务的垂直划分类似于这样:

比如 memcached 缓存,它的分布式结构就是这种垂直拆分,服务节点之间的数据不进行同步。也就是可靠性中提到的独立分片结构。

有状态服务的水平划分当然是可靠性中提到的 复制集群结构,如下图:

服务器ABC之间的数据要进行同步,比如数据库主备等结构。数据的同步由于网络延迟或者节点故障等原因,很难保证节点之间的数据是时时刻刻完全一致的。

有状态服务之间的数据同步处理,即涉及到 CAP 定理等各种分布式的定理。

小结

本篇主要阐述分布式系统的重要概念,可以看到关于可扩展性并没有进行说明。由于可扩展性和业务强相关,所以放到下一篇专门进行阐述。

发布了50 篇原创文章 · 获赞 99 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/zhou307/article/details/105058019