深入浅出 -- 系统架构之分布式集群的分类

一、单点故障问题

集群,相信诸位对这个概念并不陌生,集群已成为现时代中,保证服务高可用不可或缺的一种手段。

回想起初集中式部署的单体应用,因为只有一个节点,因此当该节点出现任意类型的故障(网络、硬件资源、物理环境......)时,都会造成整个系统对客户端不可用,而这就是所谓的"单点故障问题"。

单点故障是建立高可用系统的第一道坎,而集群恰恰是解决单点故障最有效的手段,就算系统内一个节点出现故障,依旧有其他健康的节点能处理请求,保障系统正常运行,实现99.999......%高可用。

很多人对集群的认知,都源自于Nginx,因为当程序性能跟不上业务需求、又不想对服务器升配时,就可以使用Nginx来加机器,使用多台"价格优美"的低配机器,为服务做集群化部署,从而提升系统整体的吞吐量。

不过许多人对集群的认知止步于此,如何实现PB级的海量数据存储?大部分人并不清楚,而本文则来详细聊聊集群的各方面知识,为诸位量身打造出结构化的集群知识体系。

二、集群的定义与分类

集群,即是指:通过多台物理机器,组成一台逻辑上的庞大机器使用,集群带来的优势有四:

  • ①高可用:集群内某个节点故障,可迅速将流量迁移至其他节点,解决了单点故障;
  • ②吞吐量:多台机器并行处理外部请求,可以为系统带来更强大的负载与吞吐能力;
  • ③拓展性:可根据业务的增长/萎靡,动态伸缩集群内的节点数量,系统更加灵活;
  • ④性价比:无需花费更高的价格升配机器,可使用多台价格、配置较低的机器构建。

集群带来的好处很多,即解决了单点故障,又兼顾了吞吐与性能、动态伸缩、性价比,同时对客户端是无感知的,客户端在请求时,无法分辨出究竟采用了多少台机器来部署服务。

上面是集群的基本定义与优势,现在问大家一个问题:从性质维度出发,你认为集群可以分为哪几种?

1.1、集群的分类

集群大家很熟,但一问集群的分类,估计各位会愣住,这......我没想过啊~

其实集群可粗略分为两大类,逻辑处理集群、数据存储集群,前者对应着业务系统,后者对应着数据存储组件,举些例子说明:

  • 逻辑处理型集群:业务服务、API网关、请求分发器、并行运算(科学计算)服务等;
  • 数据存储型集群:缓存中间件、消息中间件、数据库、搜索中间件集群、对象存储等。

仔细观察下,如果熟悉云技术的小伙伴会发现,这跟云平台里定义的有状态、无状态概念很类似~

简单来说,逻辑处理型的集群,只需要处理客户端请求的逻辑运算,拿业务系统来说,目前有个登录功能,系统只需根据业务流程,执行完对应的业务逻辑,接着就可给客户端响应结果。

PS:为了便于后续讲述,逻辑处理型集群则用业务系统来代替,当提到业务系统时,可自动代入"逻辑处理型集群"。

而存储型的集群,客户端一般是"程序",如DB、Redis、MQ、ES......,生产环境里,处理的绝大多数请求,都来自于业务系统。对于客户端的请求,需要保存信息,处理写入请求需要将客户端带来的数据存好,处理读取请求则需将之前存好的数据拿出来返回。

当然,有人也许会疑惑,业务系统不也是读写请求吗?为什么将其归类到逻辑处理型?这是因为业务系统自身不会存储任何信息,客户端(用户)提交的数据,会由业务系统间接调用各类组件来存储,如登录信息放到Redis、业务数据放到DB......。

1.2、逻辑处理型集群的核心

在之前的模式中,因为只有一台机器,域名可直接映射服务器的公网IP,当出现对应域名的请求,DNS可直接解析到对应的服务器IP,客户端(如浏览器)直接对拿到的IP发起请求就行。

但是当一个业务系统,使用多个节点部署组成集群时,所面临的最大问题,即是请求如何分发到具体服务器?

为了解决该问题,不得不引入请求分发器,域名映射请求分发器所在的IP,分发器接到客户端的请求后,再分发给具体的业务节点处理。

当外部请求来到分发器时,分发器可以在已配置的节点列表中选一台机器,负责处理具体的业务请求逻辑。但这里有个问题,如何保证各节点的负载均衡呢?随机分发貌似不太合适,咋办?选择合适的分发算法,如轮询。

所谓的轮询,则是根据配置的节点列表顺序,依次分发请求,如第一个请求给第一个节点、第二个请求给第二个节点......,当分发到最后一个节点时,再回到第一个节点,周而复始。听起来不错对吧?但有个问题,来看例子。

现在有个房子要装修,打电话定了一车水泥,总共六十包,目前有四个人在场:30岁的男人、9岁的儿子、30岁的老婆、60岁的老爹。

这里的水泥就是请求,按照轮询算法,六十包、四个人,你一拍大腿!正好一人十五包,合理不?显然不合理,先不说别的,光看九岁儿子那小身板,像个能抗十五袋的人不?

上述例子,换到集群场景中亦是同理,组成集群的机器有好有差,如果一视同仁,站在那些较差的服务器来说,请求分发的不够合理,因此该如何保证分发的负载均衡?

负载均衡是两个词,负载即服务器目前承担的压力,均衡代表压力一致,组合起来就是指:集群内各节点承担的压力要一致 !相同的访问量,分发到一台2C4G服务器上,CPU利用率经常打到95%;但放到8C16G的机器上根本不是事。

综上所述,负载均衡要考虑各机器本身的性能,这时就得用到一些较为智能的分发算法,如:

  • 平滑加权轮询算法:在轮询的基础上,根据机器配置,为各节点分配权重值;
  • 最小活跃数算法:根据实际负载情况进行调整,自动寻找活跃度最低的节点处理请求;
  • 最优响应算法:根据分发后请求的处理时间,新请求到来时,分发给响应最快的节点处理;
  • ......

这些智能化的分发策略,能综合考虑机器性能、实际负载、响应速度等因素,选择出相对合适的节点处理请求,但这里不做过多展开,感兴趣可参考《网络编程-请求分发篇》

1.3、为什么分发器性能那么高?

业务系统做集群,通常会选择Nginx,毕竟它除开提供负载均衡的能力外,还能做反向代理,避免了将后端服务直接暴露在公网的隐患性,可为什么这类负载均衡器,性能那么高呢?

相同的访问量,Nginx可以轻松抗住,而后端服务或许要起几个才能勉强处理,为啥?其实道理很简单,因为这类负载均衡器,自身并不负责处理请求,只是负责做请求分发,所以用户的请求,在Nginx里逗留的时间极其短暂。

一台机器处理请求的速度越快,在相同的时间窗口里,其吞吐量更高。除此之外,因为不需要处理业务逻辑,自然也不存在资源之类的竞争(如锁资源),并且Nginx底层选用了多路复用模型,实际负责分发请求的线程数极少,也不存在多线程应用那种线程上下文频繁切换的开销......,种种因素下,为其高性能表现提供了强有力的支撑。

1.4、双机热备机制

工作年限较长的一点的小伙伴,应该在之前的招聘需求上,见过这么一条:

"具备集群、双机热备等高可用系统经验者优先......"

其中的双机热备技术是指啥?所谓的热备机制,可以理解成集群技术的另类体现,它是一种系统冗余设计方案,即同时部署两套系统,一主一备,主系统和备用系统并行运行。在主系统发生故障时,备用系统能迅速接管主系统的工作,维持系统正常运作,以确保服务的可用性,及业务的连续性。

可是有了Nginx这类负载均衡器,还要啥热备技术呀?恰巧,就是Nginx这类组件需要热备技术支持,虽然业务系统通过Nginx做了集群化部署,避免单点故障造成系统不可用的风险,但Nginx就成了"咽喉要地",因为它只有一个节点,如果部署Nginx的机器发生故障,就会导致外部流量无法分发到业务系统,造成整个系统瘫痪。

热备机制如何实现呢?可以借助keepalived、TurbolinuxTurboHA、Heartbeat这类专门保障高可用的技术栈实现,建设热备机制时要考虑几点:

  • ①当进程出现故障(内存溢出、进程宕机等)时,热备机制能自动重启服务;
  • ②当部署进程的机器出现故障(断网、停电、硬件损坏)时,备机能及时接替主机工作;
  • ③新主上线接管后,旧主重新启动能自动成为新主的备机,保障热备机制的可持续性;
  • ④出现热备机制无法处理的故障时(硬件问题、机房环境问题等),能及时通知人工介入。

做好上述四点,则代表热备机制较为完善,可具体咋做呢?这里不过多赘述,感兴趣可参考《Keepalived搭建双机热备机制》

PS:除一主一备外,也可以选择搭建双主热备,这样能最大程度利用资源,避免备机长时间处于空闲状态。

相关推荐
爱吃泡芙的小白白1 小时前
爬虫学习——使用HTTP服务代理、redis使用、通过Scrapy实现分布式爬取
redis·分布式·爬虫·http代理·学习记录
躺不平的理查德7 小时前
General Spark Operations(Spark 基础操作)
大数据·分布式·spark
talle20218 小时前
Zeppelin在spark环境导出dataframe
大数据·分布式·spark
渣渣盟8 小时前
大数据开发环境的安装,配置(Hadoop)
大数据·hadoop·分布式
Angindem8 小时前
SpringClound 微服务分布式Nacos学习笔记
分布式·学习·微服务
龙仔72517 小时前
离线安装rabbitmq全流程
分布式·rabbitmq·ruby
〆、风神19 小时前
Spring Boot 整合 Lock4j + Redisson 实现分布式锁实战
spring boot·分布式·后端
胡萝卜糊了Ohh20 小时前
kafka
分布式·kafka
云达闲人1 天前
1.6软考系统架构设计师:架构师的角色与能力要求 - 练习题附答案及超详细解析
系统架构·软考·系统架构设计师