Trouble with Distributed Systems (2) - Unreliable Networks

不可靠的网路 (Unreliable Networks)

2020 Day 21 - Replication 之後的文章,我们的分散式系统都是都是聚焦在 无共享架构 (shared-nothing systems),节点间不共享记忆体或储存,网路是这些机器之间唯一的沟通方式。

网路和资料中心的内部网路(通常是乙太网路)都是 非同步封包网路 (asynchronous packet networks),在此类型网路架构中,一个节点送出讯息(封包)给另一个节点後,是不保证它能完整抵达的,如下图描述了一些挺好笑的情况。

寄件者甚至无法判断封包是不是有送达,只有当你接收到回覆讯息才晓得,你永远也不知道为什麽没有收到回覆;所以一个最常使用的解决方法就是使用 timeout ,设定一段时间过後放弃等待。

实务上的网路故障 (Network Faults in Practice)

没有人能免於网路问题的,像是 [鲨鱼咬海底电缆造成损坏](nobody is immune from network problems)、交换器软件升级时可能会触发网路拓扑重设定、网路介面有时会丢弃所有 进入封包 (inbound packets) 但是会成功送出 外出封包 (outbound packets) 等等。

只要是透过网路来沟通的,它就是有可能会失败。

检测故障 (Detecing Fauls)

有些系统会自动检测故障节点,像是:

  • 一台负载均衡器 (load balancer) 需要停止送 request 给故障节点。
  • 使用 single-leader 副本策略的分散式资料库,如果 leader 故障,follower 节点之一就会接手成为新的 leader (2020 Day 21 - Handling Node Outages)。

你不能只依靠网路协定来检查节点活着与否,不能只 ping 一下就认为应用系统活着,最好是透过应用系统回覆正向 Ok 的讯息来表达它自身的状态;另外虽然 TCP 协定有自己 retry 的机制,保险起见在有应用系统端也是需要做 retry。

Timeout 和无上限延迟 (delay)

讲到 timeout 就得聊聊 timeout 到底得设多久才好?

长时间的 timeout 就代表会等很久才宣告节点死亡,短时间的 timeout 则有可能会误判节点死亡(它说不定只是暂时变慢一点了而已,或者网路故障),然後让其他节点接手,导致同样的 request 执行 2 次以及增加接手节点负担(极端的可能就是造成连锁故障全节点死亡)。

如果你的系统能保证最大的封包延迟时间为何的话,每个封包交付的时间为 d,再来假设正常的节点处理 request 的时间不超过 r ,如此我们就可以合理设计 timeout 时长为 https://chart.googleapis.com/chart?cht=tx&chl=2d%20%2B%20r

但不幸的是,非同步网路的延迟是无上限的,就像你开车上路旅游一样,到热门风景区的路程总是会塞车,网路上的排队就像是:

  • 如果数个不同的节点同时送出封包到同一目的地,网路交换机必须将它们排进 queue 里,然後一一送入目的网路,如下图 8-2,等待的过程就是人们有感的 网路壅塞 (network congestion),如果有太多资料导致网路交换器的 quque 满了,後来的封包会被丢弃。
  • 当封包抵达目的地节点,如果所有 CPU 核心正在忙碌,该 request 也会被作业系统排进 queue 里,直到应用系统能准备处理它。
  • 如果是虚拟环境,执行中的作业系统也会因为其他机器用 CPU 的关系而暂停几毫秒时间,在此段时间里,VM 是无法处理资料的,持续来的进资料也会被 VM monitor 排 quque(做缓冲)。

结论是:没有所谓的 "正确" 的 timeout 时长,选择 timeout 是一个很权衡 (trade-off) 的事情,你能实验性的设定不同 timeout,然後测量整个网路延迟的变异程度,你也能凭感觉设定,最重要的是要有机制能自动调整 timeout,身为资料工程师要随时假设网路壅塞、排队 (queueing) 和无上限延迟都有可能会发生。


<<:  Day2-"基本介绍+基本运算"

>>:  Day 7: Docker 介绍与安装

资料结构(Data Structure),#阵列(array)-最常见的资料结构

#14章、资料结构(Data Structure) #14-1.#阵列(array)-最常见的资料结...

[Day14] 轻松掌握订单&付款状态(说明)

让我们再来看一遍消费流程: 订单建立⇒交易付款⇒信用卡付款.ATM转帐.(超商付款)⇒付款成功 买方...

Day14 - 机智接案生活

看过很多文章提到程序设计师接案的陷阱,因自己非本科出身,所以觉得这些陷阱都不会发生在自己身上,再加上...

Day16 购物车 -- 异动通知

接续昨天内容,为什麽购物车要分成主体跟项目呢? 主要有几个原因,首先是因为扩充性比较好,再来是常用的...

Powershell 入门之 policy

今天我们来看看 powershell 的执行策略。 在默认情况下,你自己编写的脚本,或者从网上找的第...