# 22 | 答疑篇:分布式体系架构与分布式计算相关问题 你好,我是聂鹏程。今天,我来继续带你打卡分布式核心技术。 到目前为止,“分布式技术原理与算法解析”专栏已经更新21篇文章了,我已经为你介绍了分布式技术四纵四横知识体系中的三横,即“分布式资源管理”“分布式计算技术”和“分布式通信”,以及四纵中的“分布分布式式协同”和“分布式调度”。 在这里,我首先要感谢你们坚持学习每一篇文章,以及对每一道思考题的积极思考与讨论,并且还在此基础上对类似问题进行了扩展。 比如,@1024、@每天晒白牙、@游弋云端、@Jackey和@Dale等同学,对双主问题展开了激烈的讨论;再比如,@xj\_zh、@mt11912、@小白啊、@随心而至等同学,对Master如何判断Slave是否存活的问题进行了讨论,特别是@小白啊还专门查询了Kubernetes的方法,在留言区进行了回复。 这样的同学还有很多,我就不再一一点名了。今天,我就针对前面文章涉及的与思考题有关的留言,做一次进一步的梳理与分析,以帮助你夯实前面所学的知识点。 留言涉及的问题有很多,但我经过进一步地分析和总结后,发现大家特别感兴趣和有疑惑的思考题主要分为两类: * 分布式体系架构中,如何判断节点存活的问题; * 分布式计算技术中,离线计算、批量计算、实时计算和流式计算的区别。 今天,我主要就对这两类思考题进行一下分析和讲解。 ## 分布式体系架构相关问题 在第9篇文章“[分布式体系结构之集中式结构:一人在上,万人在下](https://time.geekbang.org/column/article/148187)”中,我给你留了一个思考题:**在集中式架构中,Master 如何判断 Slave 是否存活呢**? 首先,我先和你说说Slave故障的两类情况:一种是Slave进程退出,另一种是Slave所在服务器宕机或重启了。你可能会说,这两种情况的判断方法,难道还不一致吗?别着急,且听我慢慢道来。 如下图所示,假设Master节点与3个Slave节点相连。请注意,我在图中,Master与Slave之间画了两条线,实线旁写的是TCP长连接,虚线旁写的是心跳。因为Master与Slave之间的监控关系是固定的,因此我用了两种机制协同来判断Slave是否存活。 ![](https://static001.geekbang.org/resource/image/a0/a1/a04e5d8e89239be68a1ed239b66d6ea1.png) 其中,**TCP长连接就是针对Slave进程退出,但是Slave所在服务器未故障的情况。**这种方式是借助TCP长连接的工作原理进行判断的。TCP长连接中,TCP会对对端的Socket进行检测,当发现对端Socket不可用时,比如不能发出探测包或探测包未收到响应,会返回-1的状态,表示连接断开。所以,这种方式可以快速检测到Slave进程的退出。 对于Slave所在服务器故障的情况,由于服务器宕机或重启,那么系统环境等均不工作了,这种情况TCP长连接也无法进行探测了,也就是说TCP长连接方法在这种场景下无法判断节点是否故障。 对于这种场景,现有的软件架构中,基本都采用了**心跳方式**。其核心策略是,Master按照周期性(比如每隔1s)的方式给Slave发送心跳包,正常情况下Slave收到Master发送的心跳包后,会立即回复一个心跳包,告知Master自己还活着。当某个Slave(比如Slave1)所在服务器故障后,由于Slave无法接收到Master的心跳包,也就无法回复了。 因此,Master也无法接收到这个Slave(比如Slave1)的回复信息。通常情况下,**系统会设置一个阈值(一般设置为与心跳周期一致),若超过这个阈值还未收到Slave节点的回复,Master就会标记自己与该Slave心跳超时。** 其中,设置阈值的目的是,解决Slave故障情况下,Master一直收不到心跳信息而阻塞在那里等待心跳回复的问题。一般连续k次Master与Slave的心跳超时,Master就会判断该Slave故障了。其中,设置连续k次的目的是,降低因为系统做垃圾回收或网络延迟导致误判的概率。 这里的k,主要是根据业务场景进行设置的。如果k设置得太小,容易导致故障误判率过高,因为系统在做垃圾回收或系统进程正在占用资源时,会阻塞心跳,导致心跳包无法及时回复而超时,从而被误判。如果k设置得太大,会导致故障发现的时间过长,因为故障发现时间=k\*心跳发送周期。 接下来,我们继续延展下这个问题吧。 ### 追问1:非集中式架构中,如何判断节点是否存活? 集中式架构中,采用了TCP连接和心跳协同判断节点是否存活,那么非集中式架构中是否也是这样判断的呢? 其实,**在非集中式架构与集中式架构中,判断节点是否存活的原理有所不同。**因为,非集中式架构中节点之间是对等的,没有Master与Slave之分。如果每个节点间都建立TCP长连接,假设集群中有n个节点,那么每个节点均需要与其他n-1个节点建长连接,这将导致每个节点的资源占用都会非常多。因此,非集中式架构是采用心跳的方式进行判断的。 这里你可能会问,如果像集中式架构那样,每个节点与其他n-1个节点都发送心跳的话,整个集群中同一时间心跳消息为n\*(n-1),消息量也特别大,甚至会导致网络风暴,应该怎么办。 其实,与集中式架构中的心跳包不同,非集中式架构中采用的心跳方式的核心思想是,**每个节点被b(1≤b