分布式系统(一):概念辨析与逻辑梳理
分布式系统领域的相关知识是每个后端开发人员都会遇到的,并且是很重要的一环。但是最关键的矛盾点在于:
分布式系统领域概念繁杂,新接触的同学或者已经接触一段时间的同学都会被这些概念困扰。
那么解决办法是什么呢?我认为有三点:
- 从“点”出发,去理清概念
- 从“线”出发,理解相关知识点
- 从系统性梳理出发,构建属于自己的分布式领域的知识树
本系列文章,就是围绕这三点而来,当然第3点肯定是靠自己整理的。
说到分布式,大家一定会想到单体应用、集群等等。我们来看看并分析几组名词。
分布式与集群
我们直接下一个通俗的定义:
集群:多台服务器对外提供同样的功能,即每台对外提供的都是相同的功能,所以他们组成了一个集群
分布式系统:多台服务器组合起来对外提供一类功能
这是他们之间的区别,那么联系呢?
集群是分布式系统中的组成部分
再来一组类比即可结束该组概念:
分布式系统可以看做一个公司整体,集群又可以看做是公司中的研发部、市场部、行政部等等部分。研发部对外提供完成需求的功能,市场部对外提供需求对接的功能,而公司作为一个整体,对客户提供服务。
站在客户的视角,他并不需要管你公司是什么架构,只要完成他的需求即可。所谓公司各部门组合起来实现客户需求。
最后,还是上一张图来有个感性认知吧(图拿以前画过的,凑乎用下)
他们组合起来成为了一个简单的分布式系统。
高可用、高性能、伸缩性、可扩展
这四个常见于分布式系统的描述中,我们来看看:
- 高可用:我想一直用
- 高性能:我想用的爽
- 伸缩性:我想邀请更多人来用
- 可扩展:我想提需求(实际可扩展主要说软件设计上)
其中,高可用、高性能、伸缩性这三个特性我们主要用在分布式系统的“物理结构上”,而可扩展性则更多的用在软件设计上。
这几个名词不再多说,因为下面的概念会直接关联,放在一起说更好。
无状态服务和有状态服务
个人认为,这是最关键的概念区分,可以解决后面很多的问题。
分布式系统中的所有组件都可以划分到这两个概念中
那么,什么是有状态服务呢?
举例:在上图中,我们看到的数据库、缓存都属于有状态服务
那么,什么是无状态服务呢?
举例:在上图中,我们看到的业务服务器和负载均衡都属于无状态服务。
但是,业务服务器真的是无状态的吗?是不是也可以变成有状态的呢?所以,关键点在于二者的区分,如何区分:
首先判断该服务是否存储数据,如果不存储,则一定是无状态的。
如果存储,则假设再来一台同样的设备,他们组成一个集群后,在保证业务正确的前提下,存储的数据是否需要在二者之间进行同步。
应用一下:
对于负载均衡器来说,本身不存储业务数据,所以一定是无状态的。
对于数据库来说,本身存储数据,再增加一台数据库组成集群,那么数据肯定要进行同步,所以一定是有状态的。
对于业务服务器来说,在有的场合下,本身需要将数据存储在内存中,比如一些用户的登录状态。则此时再加入一台业务服务器组成集群,那么登录状态肯定要进行数据同步,所以这种场合下属于有状态的业务服务器。
实际上,有状态和无状态的区分基本一眼就可以看出来,不是一个难点。关键是知道概念即可。
服务状态和分布式系统特性
可靠性
系统可靠性分成两大块,一块是对于有状态服务的可靠性设计,比如数据库系统;一块是针对无状态服务的可靠性设计,比如我们的业务程序。
但是,可靠性的核心解决方案无一例外都是:冗余,各种冗余。
其中,有状态服务的难点在于他们之间的数据同步。有状态服务可靠性的实现归纳起来就是通过两个方面:
- 复制集群
- 独立分片
- 将1和2组合实现
复制集群指的是比如搭建两个数据库,他们之间同步备份,其中一个对外提供读写能力,另外一个对外提供读能力(或者只备份)。
独立分片指的是比如搭建两个数据库,一个数据库存储用户ID小于1000的,另外一个存储用户ID大于1000的数据。
不论关系型还是非关系型数据库,或者缓存,都是这样的思路。
而无状态的服务的可靠性,则是依靠负载均衡或者是负载均衡的变种(后面会提到,也即服务治理这一块)来实现的,并且可以分为服务端负载均衡和客户端负载均衡。负载均衡本身又会有单点故障的隐患,所以又有专门的高可用软件保障负载均衡整体的高可靠。
高性能
性能的提升无非是两个方面:
- 提升单体的性能
- 通过增加节点并协作提升整体的性能。
这点不论是有状态服务或者无状态服务都是从这两个方面入手,需要具体情况具体说明。
伸缩性
伸缩性的设计就是整体系统对外部压力的自适应表现。
当外部压力过大时,系统可以自动扩容,当外部压力恢复时,系统又可以自动回收多余的节点。这属于自动化的伸缩,云端的弹性伸缩或者Kubernetes集群都可以做到这个要求,这也是为什么Kubernetes是未来云端操作系统的一个重要原因。
如果手动扩容的话,对于无状态服务还是要基于负载均衡及其变种。
但是针对有状态服务,伸缩性就没那么简单了,因为要涉及到数据的同步或者分片存储。
无状态服务的典型分布式结构
前一小节可以看到,一个无状态单体服务想要实现可靠性、伸缩性、高性能就需要进行结构划分。这里的划分分为两种:水平和垂直。水平划分类似下图:
其中,服务器ABC的业务功能都相同。
垂直类似下图:
其中,服务器ABC业务功能不同。
有状态服务的典型分布式结构
有状态单体服务的垂直划分类似于这样:
比如 memcached 缓存,它的分布式结构就是这种垂直拆分,服务节点之间的数据不进行同步。也就是可靠性中提到的独立分片结构。
有状态服务的水平划分当然是可靠性中提到的 复制集群结构,如下图:
服务器ABC之间的数据要进行同步,比如数据库主备等结构。数据的同步由于网络延迟或者节点故障等原因,很难保证节点之间的数据是时时刻刻完全一致的。
有状态服务之间的数据同步处理,即涉及到 CAP
定理等各种分布式的定理。
小结
本篇主要阐述分布式系统的重要概念,可以看到关于可扩展性并没有进行说明。由于可扩展性和业务强相关,所以放到下一篇专门进行阐述。