MIT的【分布式系统课程】学习记录
内容纯属个人学习过程中的笔记记录,如果有侵权现象请留言,会立刻删除
人们使用 大量的、相互协作的 计算机驱动力是:
需要更高的计算性能
大量的计算机 == 大量的并行计算、大量CPU、大量内存、大量磁盘在并行运行
提供容错(tolerate faults)
两台计算机运行完全相同的任务,其中一台发生故障,可以切换到另一台
物理空间本身分布
银行转账,银行A在北京有一台服务器,银行B在南京有一台服务器,需要一种两者之间协调的方法
达成一些安全的目标
有一些代码不被信任,但需要和它进行交互,则将这些代码分散在多处运行。
你的代码在另一台计算机运行,我的代码在我的计算机上运行,我们通过一些特定的网络协议通信。
所以,把系统分成多个的计算机,这样可以限制出错域。
分布式系统的问题(挑战)在于:
并发编程会涉及复杂交互、时间依赖(同步、异步)等多部分
分布式系统的组成部分(有些出故障),计算机网络(网络不稳定),局部错误意向不到
达不到预期
设计分布式系统是为了获得更高性能,但一千台计算机能达到多大性能是个问题,需要精心设计才能让系统实际达到期望的性能
最终希望目标:
通过设计简单的接口,让第三方应用能够使用这些分布式的存储和计算。这样可以通过抽象接口,让分布式特性隐藏在整个系统内,这样从应用程序角度来看,整个系统是一个非分布式的系统,但实际上是一个有极高的性能和容错性的分布式系统。
三个目标(可扩展性、可用性、一致性):
可扩展性(性能层面):两台计算机构成的系统如果有两倍性能或者吞吐,就具备可扩展性
- 具备可扩展性的系统,只需要增加计算机的数量,系统就能相应提高性能或者吞吐量,这将会是一个巨大的成果。可扩展性在于系统能获得与计算机数量匹配的性能
- 现实中需要特别设计一些架构,让可扩展性无限推进
可用性(容错层面):设计时需要考虑系统能屏蔽错误,或错误出现也能继续运行。可通过构建基础架构,让尽可能多的开发人员不需要处理各种各样可能发生的错误
可用性(Availability)
自我可恢复性(Recoverability),如果出现问题,服务停止工作,但修复后系统仍然能正常运行。在故障到故障组件被修复期间,系统将会完全停止工作,但修复后系统又能完全正确重新运行
如何达到可用性+可恢复性:
非易失存储(non-volatile storage,类似于硬盘),可以在存储中存放一些checkpoint或系统状态的日志,当备用电源修复,可从硬盘中读出系统最新状态,并从那个状态继续运行。
复制,两个副本容易出现意外的偏离同步的状态,不再互为副本。
一致性
强一致性:get请求可得到最近一次完成的put请求写入的值 — 代价很高(各个组件要大量通信)
- 一般都会将数据中心的多个副本放在比较远的地方,这样一个地震了,另一个还能用,但会牵涉到数据通信问题,如果强一致性通信,代价会很高。每次执行put或者get请求,都需要等待几十毫秒来与数据的两个副本通信,以确保它们都被更新了或者都被检查了以获得最新的数据
弱一致性:不保证get请求可以得到最近一次完成的put请求写入的值(允许读出旧数据)
- 只需要更新最近的数据副本,并且只需要从最近的副本获取数据
MapReduce:
框架,允许应用程序设计人员、分布式运算的使用人员,只要编写简单的Map函数和Reduce函数,不需要知道任何有关分布式的事情,一切交给MapReduce框架
首先假设一些输入,这些输入会被分割成大量的不同文件或数据块,输入文件1、2、3
MapReduce启动时,框架为每个输入文件运行Map函数,这里可以并行运行多个Map函数
Map函数的输入:文件,文件是整个输入数据的一部分
第一个阶段,Map函数将输出一个key-value对的列表(中间输出 intermediate output)
举例:实现一个MapReduce Job(单词计数器 - 会统计每个单词出现的次数)
Map函数会将输入的每个单词拆分,输出一个key-value对,key是单词,value是1,最后对所有key-value计数。
假设输入文件1包含a、b,Map函数的最后输出是key=a,value=1和key=b,value=1
输入文件2包含b,则输出为key=b,value=1
第二个阶段,将Map函数输出的结果给Reduce函数,进行统计
Reduce函数的输入:key为a、b、c的key-value对
MapReduce框架会为每个Map函数输出的每个key,调用一次Reduce函数
每个Reduce会输出与之关联的信息
第一个Reduce输出a=1,第二个输出b=2
MapReduce Job
- 整个MapReduce计算称为Job
- 每一次MapReduce调用称为Task