到底什么是分布式?

前言

我读了很多分布式相关的概念和书籍,胸里有一股说不出的感觉,总以为不吐不快,我也不知道是对还是错,只想说出来我的见解,请大家指正。

当我们在谈论分布式的时候,通常会说到高并发,大数据,负载均衡,但是,这个真的是分布式的核心吗?

我认为稍微有经验的同学,都知道实际上高并发等并不是很难去实现,企业在招人的时候更看重的是有没有高并发的开发经验,但我仍然认为这个并不是很重要的东西,所谓高并发、大数据更不如说是程序的调优。

但是分布式究竟是什么,我们在设计一个分布式的系统的时候究竟需要怎么样去考虑,在我们的大量使用开源组件的今天,还有什么是我们在考虑分布式的时候需要关注的?

当我们开始准备去设计一个分布式系统的时候,我们必不可免使用的一个框架就是:服务发现。

服务发现框架包括服务注册和服务发现两个功能,其最重要的功能是:客户端无需存储可用服务器的列表,可以通过服务自发现可用服务器列表。请注意我用了一个词,就是:可用。往深一点想,分布式的核心就是可用。

最好系统是,能够在任何的异常情况下,仍然可用,或者至少部分可用。我认为所有的分布式的理论和算法都是为了这一目标而努力。

CAP和BASE究竟是什么

但凡是对分布式有所了解的同学,必然肯定是知道CAP和BASE理论。

CAP指的是分布式中三种特性: Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)。

BASE是指分布式系统的可用性和一致性的一种权衡: Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)。

我认为CAP和BASE理论是为了指导我们在设计分布式系统时,如何去权衡系统的可用性。

请注意,CAP的三者不可兼得,是指在系统的使用过程中,一定会出现Partition tolerance。

当出现网络分区的时候或者部分网络节点(服务器宕机等)不可用的时,我们是否需要系统可用?在系统可用或者部分可用的的前提下,如何处理一致性?因为,网络出现故障之后,必然会出现网络恢复,在网络恢复的情况下,一定会出现不一致。

WARO和Quorum机制

WARO(Write All Read one)是一种简单的副本控制协议,当Client请求向某副本写数据时(更新数据),只有当所有的副本都更新成功之后,这次写操作才算成功,否则视为失败。

Quorum机制是“抽屉原理”的一个应用。定义如下:假设有N个副本,更新操作wi 在W个副本中更新成功之后,才认为此次更新操作wi 成功。称成功提交的更新操作对应的数据为:“成功提交的数据”。对于读操作而言,至少需要读R个副本才能读到此次更新的数据。其中,W+R>N ,即W和R有重叠。一般,W+R=N+1。

简单来说,WARO牺牲了系统的可用性,但是保证了系统的一致性,即,在写服务上的可用性降低,但是读服务的可用性极大的提高。它保证在任何时候任何节点读取的数据时一致的。

但是,Quorum是一种投票机制,即当系统中大多数的节点更新成功,则认为整个系统更新成功,同时采用一定的机制(心跳,定时ping)功能,保证其它节点一定更新成功。

Quorum无法保证强一致性,但是能保证最终一致性。Quorum也解释了为什么很多服务在部署的时候最好是奇数节点而不是偶数节点。这有两个好处:

第一,它保证了任何情况下投票一定不会出现相等的场景,一定会有成功和失败。

第二,当系统一定出现网络分区,并且分成两个区域的时候,一定有一个区域时可用的。保证了系统了部分可用性。举个例子,如果只有4个节点,但是系统分成两个区域,分别是2个节点,那么任何一个分区发起的投票都不会被认为成功,因为不满足Quorum机制。

高可用到底如何实现

所有有开发经验的同学,必然会听到一个词就是:高可用。从字面意思来说,就是指系统高度可用,其逆否就是:系统不可用的时间越少越好。这就是我想说,异常我认为真正的分布式系统为了去实现高可用这一目标,必须认为异常是一种常态。

这个小节,我不想给大家说高可用架构方面的知识,这是我的不足之处,但我认为我可以直指本源,那就高可用的唯一实现方式:副本。副本(replica/copy)指在分布式系统中为数据或服务提供的冗余。

首先说异常,在分布式系统中出现的异常唯一的表现特征是:节点丢失不可用。但是其包括:网络故障,服务器宕机,数据丢失等。但是不论任何情况,我们在系统节点恢复的时候,我们重新实现节点的可用,数据的同步,都需要依靠副本,这个也是分布式系统设计的核心。

副本,简单来说,就是备份,一旦某个节点数据出现问题,可以从其它节点同步更新恢复。

正因为为了保证高可用性,所以出现了很多协议,在保证高可用的前提下,保证数据的最终一致性。

在这里我不想过多的阐述这两种协议(raft 和paxos),但它们的实现方式就是Quorum的投票选举机制。Raft是更加优秀的协议,相比Paxos更容易理解,并且在各个异常场景的解释更加清晰。

这两种协议我认为其根本目的是:在一定会出现的异常情况下,只要绝大部分的节点可用,就一定保证系统的最终一致性。

 尾声

写到这里,我认为我已经说了我认为分布式系统的核心。当我们讨论分布式设计的时候,我们常说,负载均衡,容灾,备份,大数据,服务发现,高可用。 我认为前面所有的名词都是为了一个核心,可用

本文并没有扩展到业务的架构和具体的算法实现,只说了我理解的分布式系统设计的方向:考虑异常,把异常当成正常情况。