为什么要有分布式系统?

1
无论是我们在学校刚开始学编程,还是在刚参加工作开始处理实际问题,写出来的程序都是很简单的 。因为面对的问题很简单 。
以处理数据为例,可能只是把一个几十 K 的文件解析下,然后生成一个词频分析的报告 。很简单的程序,十几行甚至几行就搞定了 。
直到有一天,给你扔过来 1000 个文件,有些还特别大,好几百 M 了 。你用之前的程序一跑,发现跑的时间有点长 。于是想要去优化下 。
1000 个文件,互相还没业务联系,用多线程呀,一个线程处理一个文件,结果再汇总就搞定了 。总算把学校里学的操作系统知识和编程语言里的多线程库都运用起来了 。你很高兴,老师知道了也会很欣慰 。
如果多线程效果不够好,比如像 Python 的多线程,没法利用多核的威力,那就用多进程 。
如果嫌线程和进程切换开销太大,大到影响整体性能 -- 通常就是所谓的 I/O bound 的场景,还可以用协程这类技术 。
无论是线程、进程,还是协程,本质上,目的都是为了计算的并行化,解决的是算的慢的问题 。
而如果计算量足够大,就算榨干了机器的计算能力,也算不过来,咋办?
一台机器不够,那就多搞几台机器嘛 。所以就从多线程/进程/协程的「计算并行化」,进化到了「计算的分布式化」(当然,分布式一定程度上也是并行化) 。

为什么要有分布式系统?

文章插图
 
2
这还没完,另一方面,如果处理的数据有 10T,而你手上的机器只有 500G 的硬盘,怎么办?
【为什么要有分布式系统?】一种办法是纵向扩展,搞一台几十 T 硬盘的机器;另一种是横向扩展,多搞几台机器,分散着放 。前者很容易到瓶颈,毕竟数据无限,而一台机器的容量有限,所以在大数据量的情况下,只能选后者 。
把数据分散到多台机器,本质上解决的是存不下的问题 。
同时,刚才提到计算分布式化后,总不能所以程序都去同一台机器读数据吧,这样效率必然会受到单台机器性能的拖累,比如磁盘 IO、网络带宽等,也就逼着数据存储也要分散到各个机器去了 。
基于这两个原因,数据存储也分布式起来了 。
3
前面说计算的分布式化的时候,有这么一句话:
一个线程处理一个文件,结果再汇总就搞定了
先做任务的拆分,然后再做结果的合并 。本质上就是分治的思想 。很显然,分治是个非常通用和应用无关的方法,没有必要每个应用都去实现一遍,做个通用的库就行了,或者装逼点,我们叫它框架 。
解决这个问题之后,再做好抽象,丰富下功能,定义好 API,基本的样子就出来了 。
于是,我们有了一个分布式的计算框架 。
 
4
而说存储的分布式化的时候,忽略了一些问题,比如:
  • 怎么拆分数据?以什么粒度拆?
  • 使用方怎么知道哪些数据在哪里?
这些问题的答案也不难:
  • 像前面说的那样以文件为单位去拆分,恐怕不妥 。文件大小差距可能很大,不利于数据的均衡分布,需要拆的更细 。
  • 为了让使用方知道该去哪台机器拿想要的数据,尤其在数据的切割粒度不再是使用方能理解的文件之后,需要维护一个数据单元和机器/服务位置的映射关系 。
当然,问题不只这些,只是举例而已 。解决这些问题之后,再加以完善,封装好 API 和服务,一个能存海量数据的框架就有了,或者装逼点,我们叫它引擎 。
于是,我们有了一个分布式的存储引擎 。
5
分布式存储引擎和分布式计算框架,就是一个分布式系统最基础的组成部分 。
广义的分布式系统,当然不只包含这两个东西 。但它们是最基础和核心的东西 。有了它们,我们就能对海量数据做最基本和通用的处理,而不再被单台机器束缚住 。
是的,分布式系统很强大、很有用 。但什么时候该用,什么时候又不要高射炮打蚊子呢?
其实也很简单 。和分布式系统尝试解决的问题对应起来,就一目了然了:
  • 当你尝试了各种优化方法,还是不能把计算时间降低到一个可接受的程度的时候
  • 当你发现找不到硬盘更大的机器来装下你的数据,或者无法承担这个成本的时候
那很有可能,你需要考虑分布式系统了 。
至于多慢叫慢,多大叫大,就区别于应用场景了 。
老板每天早上要看的报表,凌晨跑几个小时都能接受;全平台的准实时监控数据,就等不了几个小时了 。


推荐阅读