世界上最快的捷径,就是脚踏实地,本文已收录【架构技术专栏】关注这个喜欢分享的地方。
每日一个知识点系列的目的是针对某一个知识点进行概括性总结,可在一分钟内完成知识点的阅读理解。
此处不涉及过多的原理性解读,只作为一种抛砖引玉。
真正的理解一定是你自我研究探索所收获的知识,加入组织带你一起进步成长。
分布式系统出现的目的
一条定理,分布式系统的首要目标就是为了提升系统的整体性能和吞吐量
如果我们设计出来的分布式系统占用了10多台机器,其性能才勉强提升了2倍,那你说你图啥呢?
当然,为了使我们的分布式架构性能达到最优,我们仍需要尽可能的提示单机程序性能。掌握更多的高性能程序设计和编程技巧,比如多线程并发编程、多进程高性能IPC通信、高性能的网络框架等。
分布式系统出现的问题
虽然分布式系统会大大增加了我们分布式系统的性能和吞吐,但其存在着让人无法回避的风险和问题,就是系统的复杂性导致发生故障的概率大大增加了
小到一个硬盘故障,大到服务集群整体挂掉。分布式系统下故障概率的增加,除了受到网络通信天生的不可靠性及物理上分布部署的影响,还受到X86服务器品质等的影响。
分布式系统的关键点
分布式系统设计有两大关键点:
- 性能
- 容错性
举个例子:
我们设计一个分布式存储系统,出于对性能的考虑,在写文件时要先将数据写到某台机器上并立即返回,随后异步的进行数据备份到其他节点,这种设计虽然性能最好,但存在”容错性”的风险。
如果此时文件刚写完,目标机器发送故障,那就有可能会导致文件丢失。但如果同时写多个机器成功后再返回,又会导致性能下降,因为该耗时取决最慢的那台机器的性能。
其中由于性能指标是绝对的,而容错性指标是相对的,在实际场景中对于不同的数据和业务需求,我们对容错性可以存在很大的不同。
- 比如允许丢失一些的日志类数据
-
比如允许一些数据暂时不一致但最终达到一致
-
比如对交易类的数据要求高可靠性
所以根据不同的业务需求,在分布式系统设计时都会提供多种的容错性策略,这是我们在学习和设计分布式系统时也需要关注的一点。
分布式系统的设计思路
分布式系统设计中有两大思路:
- 中心化
- 去中心化
中心化
在分布式架构设计里,中心化始终是一个主流设计
设计思想:
- 分布式集群中的节点可分为两种角色:Leader和Worker
-
Leader负责分发任务并监督Worker
-
如果Leader发现某个Worker因意外状况不能正常执行任务,则将该Worker从Worker队列去除,并将其任务分给其他Worker
基于容器技术的微服务架构Kubernetes就恰好采用了这一设计思路
存在的问题:
- Leader的安全问题,如果Leader出了问题,就有可能导致集群崩溃
-
Leader能力问题,如果系统设计和实现的不好,那么有可能瓶颈就会出现在Leader上
去中心化
去中心化设计里通常不区分Leader和Worker这两种角色,比如全球互联网就是一个典型去中心化的分布式系统,联网任意节点设备怠机,都只会影响很小的范围功能。
去中心化设计的核心:
- 整个分布式系统中不存在一个区别于其他节点的Leader
-
每个节点都需要与其他节点对话才能获取必要的集群信息
去中心化的难题:
- 脑裂问题,这种情况发送概率很低,但影响很大
脑裂指一个集群由于网络的故障,被分为至少两个彼此无法通信的单独集群,此时如果两个集群各自工作,则可能会产生严重的数据冲突和错误。
一般的设计思路是,当集群判断发生了脑裂问题时,规模较小的集群就“自杀”或者拒绝服务。
实际上,完全意义的真正去中心化的分布式系统并不多见。
现在很多都是,在外部看来去中心化但工作机制采用了中心化设计思想。
在这种架构下,集群中的Leader是被动态选择出来的,而不是人为预先指定的,而且在集群发生故障的情况下,集群的成员会自发地选举新的Leader。
最典型的案例就是ZooKeeper及用Go实现的Etcd。
世界上最快的捷径,就是脚踏实地,本文已收录【架构技术专栏】关注这个喜欢分享的地方。