分布式系统的烦恼------《Designing Data-Intensive Applications》读书笔记11

简介: 使用分布式系统与在单机系统中处理问题有很大的区别,分布式系统带来了更大的处理能力和存储容量之后,也带来了很多新的"烦恼"。在这一篇之中,我们将看看分布式系统带给我们新的挑战。

使用分布式系统与在单机系统中处理问题有很大的区别,分布式系统带来了更大的处理能力和存储容量之后,也带来了很多新的"烦恼"。在这一篇之中,我们将看看分布式系统带给我们新的挑战。

1.故障

当我们在使用单机系统时,它通常以一种相当可预测的方式工作:要么它正常工作,要么不工作。

而当我们在使用分布式系统时,情况就不同了。在分布式系统中,系统的某些部分可能以某种不可预知的方式被破坏,即使系统的其他部分工作正常。这种故障通常是不确定的:如果你想做涉及多个节点和网络的东西,可能甚至不知道某个消息是否成功,因为消息穿越网络所需的时间也是不确定的。

这种故障的不确定性,使得分布式系统的变得复杂而脆弱。一个系统越大,它的组件就越有可能出现故障。在一个有成千上万个节点的系统中,某些东西总是会出现故障。而错误处理策略仅仅是简单的放弃的话,一个大系统可能会花费大量时间从故障中恢复,而不是做有用的工作。所以我们需要分布式系统能够容忍失败的节点,并且仍然保持整体工作,将容错机制建立到软件中。换句话说,分布式系统需要从不可靠的组件中建立一个可靠的系统。

2.不可靠的网络

分布式系统是一组由网络连接的机器组成的。网络是这些机器通信的唯一方式,每台机器都有自己的内存和磁盘,一台机器不能访问另一台机器的内存或磁盘。在网络中,一个节点可以向另一个节点发送消息,但是网络不能保证它何时到达或是否到达,所以网络是不可靠的。

不可靠的网络系统

如上图所示,如果发送的请求并没有得到响应,则无法区分
(a)请求丢失
(b)远程节点失效
(c)响应丢失。
处理这个问题的通常方法是超时:一段时间后,发送方放弃等待,并假定响应不会到达。 但是,当超时发生时,远程节点可能已经得到请求并进行了处理。

故障检测

由于网络的不确定性使得很难判断一个节点是否工作。分布式系统当中常用的便是超时检测的机制。如果超时检测是检测故障的方法,那么超时应该是多长时间呢?不幸的是,没有简单的答案。

长的超时时间意味着需要等待一个节点被宣告死亡。短的超时时间会更快地检测到故障,但是事实上节点并没有停止工作(例如由于节点或网络过载)时,会错误地检测一个节点失效。如果节点实际上是活着的,在执行某些操作的时,工作另一个节点接管,则该操作可能最终执行两次。而且当一个节点失效时,它的责任需要转移到其他节点,这将额外的负载放到其他节点和网络上。如果系统已经处于高负载之下,过早检测节点失效会使问题变得更糟。特别是,它可能发生的是节点实际上没有时效,但由于过载而响应缓慢,将其负载转移到其他节点会导致级联故障。

目前学界和业界的趋势是:不使用常数配置的超时,而是系统可以连续测量的响应时间和响应时间的抖动,并自动调整超时时间根据所观察到的响应时间动态分布。如Akka的超时器,Cassandra的动态检测,TCP的超时重传。

3.不可靠的时间

在分布式系统中,时间是一件棘手的事情,因为通信不是瞬时的:消息穿越网络从一台机器转到另一台机器需要时间。消息接收的时间总是比发送的时间晚,但由于网络中的可变延迟,我们不知道以后会有多少延迟。很难确定多台机器处理的逻辑与顺序。

每台机器都有自己的时钟,通常是一个石英晶体振荡器。这些设备并不完全准确,所以每台机器都有自己的时间,它可能比其他机器稍快或慢一些。存在同步时钟的网络协议:最常用的机制是网络时间协议(NTP),它允许计算机时钟根据一组服务器报告的时间进行调整。服务器可以从更精确的时间源获取时间。

时钟:

UTC时间以1970年1月1日为开始,根据公历,忽略闰秒,来计算当前时间。计算机时钟通常与NTP同步,这意味着一台机器的时间戳(理想情况下)意味着与另一台机器上的时间戳相同。

单调的时间:

您可以在一个时间点检查时钟的值,然后再一次检查时钟。两个值之间的差异告诉你这两个检查之间要花多少时间。在分布式系统中,通过一个单调的时钟测量时间(如超时)通常是好的,因为它不承担不同的节点的时钟之间的同步的细微误差。

事件的时间戳排序

跨多个节点的事件排序是一个令人头疼的问题。例如,如果两个客户机向分布式数据库写入,谁首先到达?哪个是最近写的? 如下图所示:

node2 会通过时间戳检验规则,丢弃x=2的结果

写x = 1的时间戳是42.004秒,但写x = 2的时间戳42.003秒。当Node 2接收到这两个事件时,它会错误地得出结论:x = 1是最新的值,忽略x=2的写入。Client B的增量操作将会丢失。这种冲突解决策略被称为最后写者胜(LWW),会导致一个具有滞后时钟的节点无法覆盖以前用一个快速时钟写入的节点的值,直到节点之间的时钟偏差消失。

所以对于有严格时序要求的系统,需要使用逻辑时钟(比如:Lamport Clock,Lanport老爷子真的是分布式领域的上古神牛啊~~~),这是基于递增计数器是一个来判断事件的更迭顺序。逻辑时钟不测量每天的时间或经过的秒数,只有事件的相对顺序,也就是判断一个事件是否发生在另一个事件之前或之后。

4.不可靠的租约

在分布式系统之中,有时需要确保在存储服务文件只能同时被一个客户端访问,因为如果多个客户端试图写它,文件会被损坏。您需要通过在访问文件之前从锁服务获得租约来实现分布式锁。但是有时这个锁并非有我们想象的可靠,如下图所示:

不正确的执行分布式租约

如果持有租约的客户端 1 因为GC等原因暂停太久,而它的租约到期了。另一个客户端 2 可以获取租约,并开始向文件写入数据。当暂停的客户端1返回时,它仍然认为自己拥有一个有效的租约,并且继续写入数据。于是造成了写入冲突。

栅栏令牌

我们可以使用栅栏令牌的方式,让不可靠的租约变的更加可靠,如下图所示:

通过栅栏令牌来确保写入安全

锁服务器可以在每次授予租约时,返回一个令牌,它是一个在每次授予锁时增加的数字ID。每次客户端发出一个写请求时,必须包含当前的租约令牌。而存储服务会记录写入的租约令牌,成为一个栅栏,旧的令牌写入将被存储服务拒绝。

小结:

分布式系统最大的挑战是我们需要在不可靠的组件与复杂的多节点交互之中建立起一个可靠的系统,所以也需要我们付出更多的努力。我这里略过了拜占庭问题的讲解,通常我们开发的数据系统认为是拜占庭安全的,节点是可以信任的。

目录
相关文章
|
存储 监控 API
每日一博 - 闲聊Microservice Architecture
每日一博 - 闲聊Microservice Architecture
87 1
|
存储 缓存 算法
The art of multipropcessor programming 读书笔记-硬件基础1
The art of multipropcessor programming 读书笔记-硬件基础1
The art of multipropcessor programming 读书笔记-硬件基础1
|
存储 缓存 Java
The art of multipropcessor programming 读书笔记-硬件基础2
The art of multipropcessor programming 读书笔记-硬件基础2
The art of multipropcessor programming 读书笔记-硬件基础2
|
存储 Kubernetes Cloud Native
云原生渐进式交付,刷 Argo CD 技术文档之 Understand The Basics & Core Concepts 篇
云原生渐进式交付,刷 Argo CD 技术文档之 Understand The Basics & Core Concepts 篇
140 0
|
内存技术 Go Windows
带你读《计算机组成与体系结构:性能设计(英文版·原书第10版)》之一:Basic Concepts and Computer Evolution
本书以Intel x86体系结构和ARM两个处理器系列为例,将当代计算机系统性能设计问题与计算机组成的基本概念和原理紧密联系起来,介绍了当代计算机体系结构的主流技术和最新技术。本书作者曾13次获a得美国教材和学术专著作者协会颁发的年度最佳计算机科学教材奖。目前,他是一名独立顾问,为众多计算机和网络制造商、软件开发公司以及政府前沿研究机构提供服务。
Knowledge of Network Building&Maintenance(网络组建与维护知识点)
CH1 计算机网络技术基础 一、Gap Filing1.编码是将模拟数据or数字数据变换成数字信号,以便于数据的传输和处理。信号必须进行编码,使得与传输介质相适应。(第一点存疑) 2.在数据传输系统中,主要采用以下3种数据编码技术:-数字数据的数字信号编码-模拟数据的数字信号编码-数字数据的模拟信号编码Knowledge Extension:数据传输方式有以下4类a.模拟数据的模拟信号编码 b.数字数据的数字信号编码c.数字数据的模拟信号编码 d.模拟数据的数字信号编码这4类中除了模拟数据的模拟信号编码之外,其他3类都属于数据编码技术。
2259 0
|
存储 消息中间件 监控
流处理与消息队列------《Designing Data-Intensive Applications》读书笔记16
上一篇聊了聊批处理的缺点,对于无界数据来说,流处理会是更好的选择,“流”指的是随着时间的推移逐步增加的数据。消息队列可以将这些流组织起来,快速的在应用程序中给予反馈。
1193 0
|
存储 分布式计算 调度
MapReduce与批处理------《Designing Data-Intensive Applications》读书笔记14
之前的文章大量的内容在和大家探讨分布式存储,接下来的章节进入了分布式计算领域。坦白说,个人之前专业的重心侧重于存储,对许多计算的内容理解可能不是和确切,如果文章中的理解有所不妥,愿虚心赐教。
1361 0
|
算法 数据库
线性一致性与全序广播------《Designing Data-Intensive Applications》读书笔记12
上一篇聊了聊构建分布式系统所面临的困难,这篇将着重讨论构建容错分布式系统的算法与协议。构建容错系统的最佳方法是使用通用抽象,允许应用程序忽略分布式系统中的一些问题。
1490 0
|
存储 数据库 索引
数据分区------《Designing Data-Intensive Applications》读书笔记9
进入到第六章了,我们要开始聊聊分布式系统之中的核心问题:数据分区。分布式系统通常是通过大规模的数据节点来处理单机没有办法处理的海量数据集,因此,可以将一个大型数据集可以分布在多个磁盘上,查询负载可以分布在多个处理器上。
1347 0