分布式系统问题之网络问题

网络 通信技术 分布式
在分布式系统上开发软件与在单机上开发软件完全不同。主要的区别是分布式系统有更多的地方可能出错,而且出错的形式可能与单机系统也不同。这一篇文章将介绍可能出现的两个问题:网络问题、时钟问题。

本文转载自微信公众号「程序员阿sir」,作者程序员阿sir。转载本文请联系程序员阿sir公众号。

在分布式系统上开发软件与在单机上开发软件完全不同。主要的区别是分布式系统有更多的地方可能出错,而且出错的形式可能与单机系统也不同。这一篇文章将介绍可能出现的两个问题:网络问题、时钟问题。

介绍这两个问题之前,我们先看一下构建大规模的计算服务的两种选择:

  • 高性能计算 (High Performance Computing, HPC):也就是使用超级计算机 (超算, Supercomputers)。这类计算机可能有几千个CPU,性能很强。这种机器适合于计算密集型的科学计算任务,比如实时预测天气等等。
  • 云计算 (Cloud Computing):它使用的机器可能都比较一般,但是它可能部署在多个数据中心,通过以太网进行相互通信。

当然很多企业使用的是两者结合的方式,即每台机器性能也不错,也由多台类似的机器组成集群来提供服务。高性能计算和云计算的区别如下:

  • 许多云服务应用都是在线的,也就是说任何时候都可能在服务用户。所以让整个云服务宕机是不可接受的。但是离线的任务我们可以随时停止然后重新启动。
  • 超级计算机的方向是构建可靠的稳定的系统,节点之间通过共享内存和RDMA (Remote Direct Memory Access) 来通信。而云服务的每个节点都很便宜,用的硬件也不一定稳定,所以失败率很高。
  • 大型数据中心网络经常基于IP和以太网,提供高速网络。而超级计算机的方向是使用专用的网络结构,专为超算通信而服务。
  • 云服务系统越大、组件越多,越可能出错。当错误处理策略有问题时,大型系统可能需要花费更长的时间从错误中恢复。
  • 云服务通过是全球范围分布式部署,数据通信通过网络。而超算通常节点都十分接近。

因此,如果我们想利用分布式系统创建一个我们自己的服务,这个服务必须能容忍错误 (Fault-Tolerance)。换句话说,我们需要利用不可靠的组件构建可靠的系统。我们需要处理错误 (Faults),并且要在软件设计阶段就充分考虑错误处理,需要知道当软件遇到错误的时候我们的软件会出现什么问题。

在构建系统时,我们应该多考虑一些可能出现的问题,而不是假设我们的服务完美无缺,不会遇到问题。在分布式系统中,任何的怀疑、悲观、执着都会得到回报。(In distributed systems, suspicion, pessimism, and paranoia pay off.)

下面将分别介绍这两个问题。

1. 网络问题

1.1. 网络问题概述

分布式的网络都是不可靠的网络 (Unreliable Networks)。数据中心之间或者公共网络大多数是异步包交换网络 (Asynchronous Packet Networks)。在这种网络中,一个节点可以发送数据包到另一个节点,但是网络不保证这个包什么时候能到、是不是能到。所以当你向服务器发送一个请求时,可能出现几种错误。

  • 请求在发送到对方节点之前就丢了。比如网线没插。
  • 请求可能在网络上排队,等着被发出去。比如网络过载。
  • 服务器处理请求失败。比如服务器crash了或者关机了。
  • 服务器暂时不能处理请求。比如服务器开始进行垃圾回收,暂停服务 (Garbage Collection Pause)。
  • 服务器已经处理了请求,但是返回的结果在网络上发丢了。比如交换机配置有问题。
  • 服务器已经处理了请求,但是返回的结果又延迟,等着被发出去。比如网络或机器过载。

网络请求失败示意图

所以当发送方没有收到回复时,他甚至不能判断出包是否成功到达了服务器。唯一判断的方式就是通过服务器的response,但是这个response也可能无法到达。如果没收到回复,我们几乎不可能知道哪里出了问题,除非service记了log。

常用的处理该问题的方式是设置超时时间 (Timeout),也就是一段时间之后不再继续等待结果。但是要注意的是即使设置了超时时间,我们也不知道请求是不是已经被service处理了。

处理网络问题不意味着一定要做处理,可能只是将错误的信息返回给用户。但是我们必须知道这个软件对于各种网络问题时如何相应的,并且确保这些处理操作不会造成死锁之类的系统问题。

1.2. 检测错误

很多系统需要自动检测错误节点的能力。比如负载均衡器 (Load Balancer),Single-Leader的分布式数据库等等。但是由于网络的不确定性,检测节点是否还在工作十分困难。有一些情况下可以帮助获取到一些关于网络问题的信息:

节点机器仍然能工作,但是没有进程在监听对应的目标端口 (比如进程crash了),那么系统会拒绝TCP连接,返回 RST 或 FIN包。

如果节点进程crash了,节点仍然正常工作,集群可能能够立刻将请求交给另一个节点处理。比如 HBase。

如果有权限访问数据中心的网络交换机,可以从硬件层面查看是否存在问题。但是一般情况下我们没有权限访问交换机。

如果IP地址不可达,它可能返回ICMP 目标不可达 (ICMP Destination Unreachable) 包。

另外,尽管 TCP 请求会自己进行重试,并对应用层透明。但是我们最好还是自己在应用层进行重试 (Retry)。 如果直到超时时间如果还是没有得到结果,则可以说明节点出现了问题。

1.3. 超时 (Timeout)时间设置

超时时间设置并不是一个简单的事情。设置的时间长了的话,服务器可能会多等很长时间。设置的短了的话可能有判断错误的风险,也许现在只是服务器网络有一点临时性的堵塞,导致速度慢了一些。一些load balancer是通过timeout来判断节点是否存活的,如果误判了节点的存活状态可能对服务性能造成影响。

如果一个系统的理想中的网络延迟是,服务器处理时间是 ,则timeout时间最好设置为 。但是实际中大多数系统的网络延迟是没有上限的 (Unbounded Delays),也就是说网络尽力最快交付,但是也可能无限慢下去。服务本身也无法给出准确的最大处理时间。

1.4. 网络拥塞和排队 (Network Congestion and queueing)

我们开汽车到达目的地的时间不确定主要是由于车在路上排队的时间是不确定的。同理,网络包延迟的不确定性也可能是由于包在网络中排队 (queueing)。有以下几个可能导致排队的地方。

  • 如果很多人同时往一个目的地发送包,交换机必须把这些请求排好队一个一个的发到目标网络链路。因此包可能需要在目标网络链路中排队。如果排队的包太多了,可能后面发送上来的包都会直接被丢弃,必须重传。
  • 当包到达服务器时,如果所有的CPU都在忙着,当前请求就会被操作系统排队,直到应用获取了时间片可以处理这个请求。这个等待时间根据当前机器的负载来决定,可能很短时间也可能很长。
  • 如果是虚拟环境,可能当前获取CPU时间片的是另一个虚拟环境,所以当前虚拟环境可能也需要等待,所以网络请求也会排队等待处理。
  • TCP拥塞控制 (Flow Control, Congestion Avoidance or backpressure)。可能发送方限制了发送速率以保证不会对网络或目标机器造成过载,所以可能在包进入网络之前,包就已经在排队了。

端口1,2,4尝试发送包给端口3

除此之外,当TCP没有收到ACK时,会重传请求。虽然这一过程对应用层是透明的,但是应用层可以感受到更高的延迟。

当服务有很多空闲的时间时,队列任务可以被很快处理完然后清空。但是当服务器快达到它的处理上限时,队列将很快变得越来越长,排队将会导致严重的网络延迟。

同时,在云环境下,我们很难控制网络延迟,因为可能有很多服务在共享当前的同一个服务器。所以当网络拥堵时,也许是别的服务造成的网络拥堵,从而影响了我们的服务。

1.5. 总结

在云服务的场景下,目前的技术不允许我们对网络延迟和可靠性作出保证,也就是说我们需要考虑网络拥塞、排队以及无上限的延迟。超时时间也没有一个固定的参考值,需要通过实验来进行设置。

下一篇文章将继续介绍时钟问题。

(未完待续)

参考文献

 

[1] Kleppmann, Martin. Designing data-intensive applications: The big ideas behind reliable, scalable, and maintainable systems. " O'Reilly Media, Inc.", 2017.

 

责任编辑:武晓燕 来源: 程序员阿sir
相关推荐

2021-12-15 07:24:56

分布式系统时钟

2018-08-24 07:03:45

分布式系统数据分片元数据

2020-02-17 16:05:17

系统演进过程时间问题

2022-08-12 18:40:00

分布式

2018-09-29 14:08:04

存储系统分布式

2010-07-26 13:25:11

SQL Server分

2017-06-05 15:51:54

分布式Logical Tim算法

2019-12-26 08:59:20

Redis主从架构

2023-05-29 14:07:00

Zuul网关系统

2023-05-12 08:23:03

分布式系统网络

2018-07-17 08:14:22

分布式分布式锁方位

2017-10-27 08:40:44

分布式存储剪枝系统

2023-10-26 18:10:43

分布式并行技术系统

2016-12-09 09:21:45

分布式系统大数据

2023-02-11 00:04:17

分布式系统安全

2021-05-17 09:32:18

分布式存储问题数据

2020-01-03 08:33:57

Ceph硬件系统

2022-05-22 09:48:47

微服务Sentinel

2019-07-12 09:14:07

分布式系统负载均衡

2017-10-17 08:33:31

存储系统分布式
点赞
收藏

51CTO技术栈公众号