初识分布式:MIT 6.284 系列(一)
前言
本系列是源于「码农翻身」
所属知识星球发起的读书活动,由大佬 @我的UDP不丢包
推荐而来,这次的读书活动有一些另类,我们抛弃了传统的书籍,开始攻略最高学府的研究生顶级课程 <6.824>,该课程是很多年前的蠕虫病毒发明者Robert Morris
大佬授课,归属于麻省理工大学
,授课方式主要是:视频 + Lab 实验(Go 语言) + 论文,全程英语,难度较大。
分布式系统的判断依据
multiple cooperating computers (多台计算机协作)
storage for big web sites, MapReduce, peer-to-peer sharing (大规模数据集运算,如:MapReduce,或点对点共享)
lots of critical infrastructure is distributed (系统的绝大部分基础设施是分布式的)
MapReduce
:大规模数据集计算系统,比如计算从 1 加到 1000 亿,可以单台计算机计算,也可以利用该技术分散到多台计算机计算然后合并结果,极大的提高效率
为什么需要分布式系统
to increase capacity via parallelism (通过并行增加系统性能)
to tolerate faults via replication (通过复制备份增加系统容错)
to place computing physically close to external entities (可以将计算放在离外部实体更近的地方)
to achieve security via isolation (可以通过隔离增加系统的安全)
容错:
针对于容错,主要是两点,一是可用性,二是可恢复性
>
对于分布式系统来说,一般不会全部服务器同时瘫痪,因此无论是服务可用还是数据安全,都比单体服务更有保障。
分布式的难点
需要额外注意并发编程,对开发人员的能力要求直线上升
系统内的相互作用非常复杂
意想不到的错误:局部错误
预期性能和实际性能往往不符
局部错误
:假设一台机器每天出故障的概率是千分之一,在单体应用中,可能很长时间可以工作,但是在分布式系统中,设备数量急剧上升,每天都可能有设备出现故障,这就是所谓的局部错误,很难排查,也几乎无法避免
此处展示一张单体应用和分布式应用的对比图,图片出自:《极客时间 · 左耳听风》
分布式系统的解决方案
宏观目标
我们需要设计一系列能够屏蔽分布式系统复杂性的抽象
为什么要设立此目标?
>
因为分布式系统本身已足够复杂,因此必须简化使用方式
>
简化使用方式和抽象有什么关系?
>
我目前认可的最完美抽象是:文件
>
“UNIX 文件本质上就是一大袋字节。” —— 《UNIX 编程艺术》
>
在 Unix 中,任何可读/写也就是有 I/O 的设备,无论是文件,socket,驱动,在打开设备之后都有一个对应的文件描述符。Unix 将对这些设备的读写简化在 read/write 中,换言之,你只需要把打开的文件描述符传给这两个函数,操作系统内核知道如何根据这个文件描述符得到具体设备信息,内部隐藏了对各种设备进行读写的细节,所有这些对用户都是透明的,你只需要打开它,得到 fd,再进行相应的操作就够了。
研究角度
实现方式。
- RPC 远程调用,线程和并发控制
性能:
- 通常我们想要提供一个性能可以扩展的系统。
- 可以通过简单增加系统的电脑数量来增强并行能力,从而部分扩展系统的性能:
- 当没有复杂交互的时候这么做很有效
- 可以不用请昂贵的程序员来重新设计系统。
- 简单增加系统内电脑数量并不能一直增加系统性能:
- 当电脑数量变得很多的时候,负载不均,系统内每台电脑性能不均,无法并行执行的代码,初始化的交互都会降低系统的性能。
- 来自共享资源的访问也会造成性能瓶颈,比如网络通讯或者数据库等
- 同时性能也并不能总是靠增加系统内电脑数量达成:
- 比如来自单一用户请求的快速响应时间
- 比如所有用户都想要更新同一个数据。
- 通常这些情况需要更好的程序设计而不是更多的电脑。
容错:
- 大量的服务器 + 大型的系统通常代表着总有错误会发生
- 我们需要向应用程序隐藏这些错误
- 我们通常想要让系统拥有可用性和可恢复性
- 可用性:即使错误发生了,系统还是可以继续运行
- 可恢复性:当错误被修复之后,系统可以恢复运行
- 通常可以用备用的服务器来增加容错
一致性:
- 通常想要达成正确工作的系统十分困难:
- 服务器和它的备份服务器之间很难保持一致,代价太高
- 客户端可能会在中途出错。
- 服务器可能会在处理之后回复之前崩溃
- 不佳的网络可能会使得正常的服务器无法提供服务
- 一致性和性能通常是矛盾的:
- 高一致性需要各种基础设置之间大量的通信
- 许多设计为了提升性能被迫只提供弱一致性
一致性
:一致性问题貌似是最难以解决的问题,因为它本质包含了性能,容错,数据一致性等等诸多要素
>
我们前文说过,为了考虑容错容灾机制,需要数据进行备份,那么在分布式系统中,A 服务修改了 A 数据库的值,B 数据库的值要不要跟着改,是立即跟着改,还是延迟跟着改,在同步修改中出问题了怎么办,在异步修改中出问题了怎么办
>
最终业界也很难解决相应的问题,因此现在主流的方式是:
最终一致性
>
即允许短时间内数据不一致,通过最终一致性保证性能和数据安全的兼顾
持续脑图
文件分享地址:https://www.processon.com/view/link/5f1db0230791291b99680fa0
下一章内容
接下来的一章,我们将进行 <6.824> 中的 Lab 1,即实现一个简单的MapReduce
系统,该系统将采用 Go 语言构建
Go 语言是近些年非常热门的语言之一,其价值个人感觉大于被炒的火热的 Python
本章要求
了解分布式系统的由来及面临的挑战
了解<6.824>课程中涉及的分布式系统解决方案
搭建 Go 语言环境,写出 HelloWorld 即可(语法层面及 MR 实现将在下章学习)
最后
相关资源:
如果觉得对你有用的话,不要忘记点个赞啊~ 也可以扫描二维码关注我,一起朝着技术人的顶峰前进!
版权声明: 本文为 InfoQ 作者【Kerwin】的原创文章。
原文链接:【http://xie.infoq.cn/article/36b5e86b398ecb2f55fbc123e】。文章转载请联系作者。
评论