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

1.故障

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

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

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

2.不可靠的网络

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


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

故障检测

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

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

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

3.不可靠的时间

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

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

时钟:

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

单调的时间:

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

事件的时间戳排序

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

写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。每次客户端发出一个写请求时,必须包含当前的租约令牌。而存储服务会记录写入的租约令牌,成为一个栅栏,旧的令牌写入将被存储服务拒绝。

小结:

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

分布式系统的烦恼------《Designing Data-Intensive Applications》读书笔记11的更多相关文章

  1. 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...

  2. 强化学习读书笔记 - 11 - off-policy的近似方法

    强化学习读书笔记 - 11 - off-policy的近似方法 学习笔记: Reinforcement Learning: An Introduction, Richard S. Sutton and ...

  3. 《精通Spring 4.X企业应用开发实战》读书笔记1-1(IoC容器和Bean)

    很长一段时间关注在Java Web开发的方向上,提及到Jave Web开发就绕不开Spring全家桶系列,使用面向百度,谷歌的编程方法能够完成大部分的工作.但是这种不系统的了解总觉得自己的知识有所欠缺 ...

  4. python for data analysis 2nd 读书笔记(一)

    第一章相对简单,也么有什么需要记录的内容,主要用到的工具的简介及环境配置,粗略的过一下就行了.下面我们开始第二章的学习 CHAPTER 22.2Python Language Basics, IPyt ...

  5. OCP读书笔记(11) - 使用闪回技术II

    闪回归档 1. 什么是闪回数据归档? 闪回归档是用来保存一个或多个表的历史数据的新数据库对象,以及该数据的存储保留和清除策略.归档只是保存数据库中一个或多个表的所有事务处理的变化的一个或多个表空间,数 ...

  6. 《Effective Java》读书笔记 - 11.序列化

    Chapter 11 Serialization Item 74: Implement Serializable judiciously 让一个类的实例可以被序列化不仅仅是在类的声明中加上" ...

  7. 『TCP/IP详解——卷一:协议』读书笔记——11

    2013-08-23 20:00:18 第4章 ARP:地址解析协议 4.1 引言 ARP(Address Resolution Protocol,地址解析协议)是获取物理地址的一个TCP/IP协议. ...

  8. 《Android开发艺术探索》读书笔记 (11) 第11章 Android的线程和线程池

    第11章 Android的线程和线程池 11.1 主线程和子线程 (1)在Java中默认情况下一个进程只有一个线程,也就是主线程,其他线程都是子线程,也叫工作线程.Android中的主线程主要处理和界 ...

  9. OCA读书笔记(11) - 实现Oracle数据库审计

    11 Implementing Oracle Database Auditing 描述DBA对于安全和审计的职责使能标准的数据库审计安全审计选项查看审计信息维护审计路径 最小权限原则只在计算机上安装所 ...

随机推荐

  1. 深入分析Parquet列式存储格式

    Parquet是面向分析型业务的列式存储格式,由Twitter和Cloudera合作开发,2015年5月从Apache的孵化器里毕业成为Apache顶级项目,最新的版本是1.8.0. 列式存储 列式存 ...

  2. HDU 1717 小数化分数2 数学题

    解题报告:输入一个小于1的小数,让你把这个数转化成分数,但注意,输入的数据还有无限循环的小数,循环节用一对括号包含起来. 之前还没有写过小数转分数的题,当然如果没有循环小数的话,应该比较简单,但是这题 ...

  3. HDU 1176 排列2 全排列

    解题报告:给出四个数,然后要你把这四个数组合成的各不相同的四位数按照从小到大的顺序输出来,然后如果最高位是0的话不能输出来,还有最高位是数字如果一样的话,则放在同一行输出. 本来是个比较简单的生成全排 ...

  4. HDU 4521 小明系列问题——小明序列 (线段树 单点更新)

    题目连接 Problem Description 大家都知道小明最喜欢研究跟序列有关的问题了,可是也就因为这样,小明几乎已经玩遍各种序列问题了.可怜的小明苦苦地在各大网站上寻找着新的序列问题,可是找来 ...

  5. c语言学习笔记.链表.

    链表: 链表单个节点的数据结构.链表的实现主要依靠结构体和指针. 头指针(head)指向链表的第一个节点,然后第一个节点中的指针指向下一个节点,然后依次指到最后一个节点,这样就构成了一条链表. str ...

  6. [转]CNN 中千奇百怪的卷积方式大汇总

    https://www.leiphone.com/news/201709/AzBc9Sg44fs57hyY.html 推荐另一篇很好的总结:变形卷积核.可分离卷积?卷积神经网络中十大拍案叫绝的操作. ...

  7. aarch64_a1

    AGReader-1.2-16.fc26.aarch64.rpm 2017-02-14 07:01 50K fedora Mirroring Project ATpy-0.9.7-11.fc26.no ...

  8. MySQL异步复制、半同步复制详解

    MySQL数据复制的原理图大致如下: 从上图我们可以看出MySQL数据库的复制需要启动三个线程来实现: 其中1个在主服务器上,另两个在从服务器上.当发出START SLAVE时,从服务器创建一个I/O ...

  9. textarea保留换行和空格

    <style> pre {white-space: pre-wrap;} </style> //替换textare <pre class="feedback_q ...

  10. centos7.2系统没有eth0网卡

    最近一直在学centos7.5系统,偶然看到虚拟机里有7.2系统所以想练习一下(其实7.2和7.5差不多),但是打开虚拟机之后,发现没有eth0网卡 那没有eth0网卡就无法远程连接ssh,既然遇到了 ...