Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Java_Guide
整理自《架构解密从分布式到微服务》第七章——聊聊分布式计算.做了相应补充和修改。
前言
不管是网络、内存、还是存储的分布式,它们最终目的都是为了实现计算的分布式:数据在各个计算机节点上流动,同时各个计算机节点都能以某种方式访问共享数据,最终分布式计算后的输出结果被持久化存储和输出。 分布式作为分布式系统里最重要的一个能力和目标,也是大数据系统的关技术之一。经过多年的发展与演进,目前业界已经存在很多成熟的分布式计算相关的开源编程框架和平台供我们选择。
一 不得不说的Actor模型1.1 Actor模型的诞生与发展
Carl Hewitt于1970年发明Actor模型,当时Actor模型的概念远远领先于那个时代,知道Erlang这样基于Actor模型设计的面向并发编程的新语言横空出世之后,Actor模型才真真火了起来。
1.2 Actor模型是什么?
Actor是计算机科学领域中的一个并行计算模型,它把Actor当做通用的并行计算原语:一个Actor对接收到的消息做出响应,进行本地决策,可以创建更多的Actor(子Actor),或者发送更多的消息;同时准备接收下一条消息。
在Actor理论中,一切都被认为是Actor,这和面向对象语言里一切都被看成对象很类似。但包括面向对象语言在内的软件通常是顺序执行的,而Actor模型本质上则是并发的。Actor之间仅通过发送消息进行通信,所有的操作都是异步的,不同的Actor可以同时处理各自的信息,使整个系统获得大规模的并发能力。
1.3 Actor模型原理简单介绍
Actor模型简单原理图:
根据上图,每个Actor都有一个Mailbox(邮箱),Actor A 发送给消息给Actor B,就好像Actor A 给Actor B写了一封邮箱地址为Actor B的邮箱地址的邮件(消息)一样,随后平台负责投递邮件。当邮件Actor B之后,平台就会通知Actor B收取邮件并做出回复,如果有多封邮件,则Actor B按顺序处理。很简单和容易理解的技术,但是蕴含了强大的力量。Actor B收到消息后可能会做那些处理呢?
- 创建其他Actor
- 向其他Actor发送消息
- 指定下一条消息到来的行为,比如修改自己的状态
在什么情况下一个Actor会创建子Actor呢?
通常情况是为了并行计算,比如我们有10G的文件要分析处理,我们可以在根Actor里创建10个子Actor,让每个Actor分别处理一个文件,为此根Actor给每个子Actor发送一个消息,消息里包含分配给它的的文件编号(或位置),当子Actor完成处理后,就把处理好的结果封装为应答消息返回给根Actor,然后根Actor在进行最后的汇总与输出,下面是这个过程的示意图。
一个Actor与其所创建的Actor形成父子关系。在实际编程中,父Actor应该监督其所创建的子Actor的状态,原因是父Actor知道可能会出现那些失败情况,知道如何处理他们,比如重新产生一个新的子Actor 来重做失败的任务,或者某个Actor失败后就通知其他Actor终止任务。
1.4 Actor模型的优缺点
通过上面对Actor模型原理的简单分析,我们来总结一下Actor模型的优缺点。
优点:
1)将消息收发、线程调度、处理竞争和同步的所有复杂逻辑都委托给了Actor框架本身,而且对应用来说是透明的,我们可以认为Actor只是一个实现了Runnable接口的对象。关注多线程并发问题时,只需要关注多个Actor之间的消息流即可。
2)符合Actor模型的程序很容易进行测试,因为任意一个Actor都可以被单独进行单元测试。如果测试案例覆盖了该Actor所能响应的所有类型的消息,我们就可以确定该Actor的代码十分可靠。
缺点:
二 初始AKKA1) Actor完全避免共享并且仅通过消息来进行交流,使得程序失去了精细化并发调控能力,所以不适合实施细粒度的并行且可能导致系统响应时延的增加。如果在Actor程序中引入一些并行框架,就可能会导致系统的不确定性。
2)尽管使用Actor模型的程序 比使用线程和锁模型的程序更容易调试,Actor模型仍会碰到死锁这一类的共性问题,也会碰到一些Actor模型独有的问题(例如信箱移溢出)。
2.1 AKKA简介
Akka 是一个用 Scala 编写的库,用于简化编写容错的、高可伸缩性的 Java 和 Scala 的 Actor 模型应用。它已经成功运用在电信行业。系统几乎不会宕机(高可用性 99.9999999 % 一年只有 31 ms 宕机)。
Akka虽然是Scala写成的,但是由于Scala最终还是编译为Java字节码运行在JVM上,所以我们可以认为Akka属于Java领域。
Akka处理并发的方法基于Actor模型。在Akka里,Actor之间通信的唯一机制就是消息传递。
Akka官方宣传是这样介绍Akka的:
- 是对并发、并行程序的简单的高级别的抽象
- 是异步、非阻塞、高性能的事件驱动编程模型
- 是非常轻量级的事件驱动处理(1GB内存可容纳约270万个actors)
2.2 为什么要用Akka?
Akka是一个运行时与编程模型一致的系统,为以下目标设计:
- 垂直扩展(并发)
- 水平扩展(远程调用)
- 高容错
使用Akka带来的好处:
- AKKA提供一种Actor并发模型,其粒度比线程小很多,这意味着你可以在项目中使用大量的Actor。
- Akka提供了一套容错机制,允许在Actor出错时进行一些恢复或者重置操作
- AKKA不仅可以在单机上构建高并发程序,也可以在网络中构建分布式程序,并提供位置透明的Actor定位服务 三 使用面很广的Storm
与前面提到的Actor面向消息的分布式计算式模型不同,Apache Storm提供的是面向连续的消息流(Stream)的一种通用的分布式计算解决框架。
2.1 Storm简介
Apache Storm是一种侧重于极低延迟的流处理框架,也是要求近实时处理的工作负载的最佳选择。该技术可处理非常大量的数据,通过比其他解决方案更低的延迟提供结果。
Storm作为实时流式计算中的佼佼者,因其良好的特性使其使用场景非常广泛。
Zookeeper作为分布式协调服务框架,因其完善的数据一致性保证特性使其成为各框架必备组件。
2.2 Storm的应用场景
1)日志处理: 监控系统中的事件日志,使用 Storm 检查每条日志信息,把符合匹配规则的消息保存到数据库。
2)电商商品推荐: 后台需要维护每个用户的兴趣点,主要基于用户的历史行为、查询、点击、地理信息等信息获得,其中有很多实时数据,可以使用 Storm 进行处理,在此基础上进行精准的商品推荐和放置广告。
2.3 Storm与Hadoop的关系
Hadoop 是强大的大数据处理系统,但是在实时计算方面不够擅长;Storm的核心功能就是提供强大的实时处理能力,但没有涉及存储;所以 Storm 与 Hadoop 即不同也互补。
Storm与Hadoop应用场景对比:
三 MapReduce及其引发的新世界Storm: 分布式实时计算,强调实时性,常用于实时性要求较高的地方
Hadoop:分布式批处理计算,强调批处理,常用于对已经在的大量数据挖掘、分析
3.1 MapReduce简单介绍
与前面介绍的Actor模型一样,MapReduce本质上也是一种很古老的并行计算模型,它的名字起源于LISP类函数式语言里的map和reduce操作。MapReduce的计算模型非常简单,它的思想就是“分而治之”,Mapper负责“分”,即把复杂的大任务分解为若干个小任务来处理,彼此之间没有依赖关系,以便可以分布到多个计算节点上实现高度的并行计算能力;Reducer则负责对map阶段的结果进行汇总和输出。
我们通过一个最简单的统计词频的案例看一下,MapReduce的简单原理:
3.2 MapReduce与Spark以及Storm孰优孰劣
Hadoop传统意义上就是离线数据处理平台。但是2.0之后就不一样了,因为多了yarn资源管理器(可能是收到了分布式资源调度系统Mesos的启发),Spark和Storm都可以搭建在Hadoop之上,用yarn进行调度。这是大数据处理中目前最流行的三个计算框架。
Mapreduce: 适用于离线计算。这个框架充分利用了磁盘,处处存在着排序和合并。所以适合于实时性不高的离线计算。
Spark: 相对于Hadoop的MapReduce会在运行完工作后将中介数据存放到磁盘中,Spark使用了存储器内运算技术,能在数据尚未写入硬盘时即在存储器内分析运算。Spark在存储器内运行程序的运算速度能做到比Hadoop MapReduce的运算速度快上100倍,即便是运行程序于硬盘时,Spark也能快上10倍速度。Spark允许用户将数据加载至集群存储器,并多次对其进行查询,非常适合用于机器学习算法。
Storm: 一种侧重于极低延迟的流处理框架,也是要求近实时处理的工作负载的最佳选择。该技术可处理非常大量的数据,通过比其他解决方案更低的延迟提供结果。
关于三者的一些概括总结
Hadoop: 离线分析框架,适合离线的复杂的大数据处理
Spark:内存计算框架,适合在线、离线快速的大数据处理
Storm: 流式计算框架,适合在线的实时的大数据处理