分布式计算技术之Actor计算模式

The Actor Model for Concurrent Computation

背景介绍

计算机CPU的计算速度提高(频率的提高)是有限度的,我们能做的是放入多个计算核心。为了利用多核心的计算机,我们需要并发执行。但是多线程的方式会引入很多问题和增加调试难度。

我们有个替换的方案,叫做Actor模型。

两种分布式计算模式: Actor 和流水线

分布式计算的本质就是在分布式环境下,多个进程协同完成一件复杂的事情,但每个进程各司其职,完成自己的工作后,再交给其他进程去完成其他工作。当然,对于没有依赖的工作,进程间是可以并行执行的。

分布式进程那么多,如果需要开发者自己去维护每个进程之间的数据、状态等信息,这个开发量可不是一般得大,而且特别容易出错。那么,有没有什么办法可以让开发者只关注自己的逻辑呢?

答案是肯定的,Actor 计算模式就能满足你的需求。也就是说,你可以把数据、状态等都扔给 Actor。

什么是 Actor?

Actor 类似于一个“黑盒”对象,封装了自己的状态和行为,使得其他 Actor 无法直接观察到它的状态,调用它的行为。多个 Actor 之间通过消息进行通信,这种消息类似于电子邮箱中的邮件。Actor 接收到消息之后,才会根据消息去执行计算操作。

那么,Actor 模型又是什么呢?

Actor 模型,代表一种异步消息模式的分布式并行计算模型。在 Actor 模型里,每个 Actor 相当于系统中的一个组件,都是基本的计算单元。

这种模型有自己的一套规则,规定了 Actor 的内部计算逻辑,以及多个 Actor 之间的通信规则。

Actor 模型的计算方式与传统面向对象编程模型(Object-Oriented Programming,OOP)类似,一个对象接收到一个方法的调用请求(类似于一个消息),从而去执行该方法。

OOP 因为数据封装在一个对象中,不能被外部访问,当多个外部对象通过方法调用方式,即同步方式进行访问时,会存在死锁、竞争等问题,无法满足分布式系统的高并发性需求。

而 Actor 模型通过消息通信,采用的是异步方式,克服了 OOP 的局限性,适用于高并发的分布式系统。

Actor模型

Actor模型是处理并行计算的概念模型。它定义了系统部件行为和交互的一些规则。使用这个模型的最著名的编程语言是Erlang。

模型中一个Actor是一个基本的计算单元。它接受消息然后基于接到的消息做一些计算。和面向对象编程有些类似,一个对象被调用(接收到一个消息),基于调用方法(接受到的一个消息)做处理。区别是actor之间是完全隔离的,不共用内存区域。actor的私有状态不会被另外一个actor直接改变。

actor作为群体存在,单一的actor不是actor模式。在actor模型中,actor是唯一组成部分,actor带有地址以便互相发送消息。

actor按次序处理消息,比如你发送三个消息给一个actor,它们不会被并发处理。如果你想让这三个消息得到并发处理,你需要创建3个actor,然后分别发送给它们。

接受到的异步消息存在于actor内部的一个队列中,我们可以把它形象化的叫做邮箱(mailbox)。

Actor模型定义

一种分布式并行计算模型。
该模型有自己的一套规则,规定了Actor的内部计算逻辑以及多个Actor之间的通信规则。Actor模型通过异步消息模式,实现分布式系统的高并发

Actor计算模式

Actor模型的三要素:

  1. 状态:Actor组件本身的信息

  2. 行为:Actor的计算处理操作

  3. 消息:Actor的消息以邮件的形式在多个Actor之间通信传递,每个Actor都会有一个自己的邮箱.

Actor工作原理

工作流程

Actor2从MailBox队列中依次取出Actor1和Actor3发送的消息执行相应的操作

消息传递流程

Actor的行为

当一个actor接受到消息后,它可以做如下事情:

  1. 创建更多的actor
  2. 发送消息到其他actor
  3. 指派对下一条消息做什么处理。

最后一条定义了actor如何操作内部状态。例如一个计算器作用的actor,初始状态是0,处理到加1消息时,它不改变内部状态,但分派下一条消息处理时,状态是1.

失败可容忍
Erlang语言中有个“由它失败”的思想。就是你不可能考虑到所有导致失败的问题,与其绞尽脑汁处理这些问题,不如让它自然失败,然后指派给失败处理者处理(例如恢复到稳定状态),在actor模型中,这是可行的。

actor之间的隔离性导致actor失败不会影响其他actor,监控者可以对自然失败的actor做直接处理而不会带来连锁问题。这让“自愈系统”成为可能,就是说一个actor异常后,监控者可以恢复一致性,可能以初始状态重起actor。

分布性
actor发消息时不在乎目标actor是本地运行的还是运行在其他节点。试想,如果actor只是只有内部状态的邮箱,只对消息做出反应,那就没人在乎它在哪里运行,知道有个地址让消息可以到达即可。这让我们可以创建分布式系统,并且在节点失败时独立恢复而不影响整个系统。

进一步建议看一下Erlang和Elixir语言, JVM上的 Actor库Akka,基于Actor的框架Vert.x

Actor关键特征

优势

Actor 的通信机制与日常的邮件通信非常类似。因此,我们可以进一步总结出 Actor 模型的一些特点:

  1. 实现了更高级的抽象
    Actor 与 OOP 对象类似,封装了状态和行为。但是,Actor 之间是异步通信的,多个 Actor 可以独立运行且不会被干扰,解决了 OOP 存在的竞争问题。

2.非阻塞性
在 Actor 模型中,Actor 之间是异步通信的,所以当一个 Actor 发送信息给另外一个 Actor 之后,无需等待响应,发送完信息之后可以在本地继续运行其他任务。也就是说,Actor 模型通过引入消息传递机制,从而避免了阻塞。

3.无需使用锁
Actor 从 MailBox 中一次只能读取一个消息,也就是说,Actor 内部只能同时处理一个消息,是一个天然的互斥锁,所以无需额外对代码加锁。

4.并发度高
每个 Actor 只需处理本地 MailBox 的消息,因此多个 Actor 可以并行地工作,从而提高整个分布式系统的并行处理能力。

5.易扩展
每个 Actor 都可以创建多个 Actor,从而减轻单个 Actor 的工作负载。当本地 Actor 处理不过来的时候,可以在远程节点上启动 Actor 然后转发消息过去。

不足

虽然 Actor 模型有上述的诸多优点,但它并不适用于分布式领域中所有的应用平台或计算框架。因为,Actor 模型还存在如下一些不足之处:

Actor 提供了模块和封装,但缺少继承和分层,这使得即使多个 Actor 之间有公共逻辑或代码部分,都必须在每个 Actor 中重写这部分代码,也就是说重用性小,业务逻辑的改变会导致整体代码的重写。
Actor 可以动态创建多个 Actor,使得整个 Actor 模型的行为不断变化,因此在工程中不易实现 Actor 模型。此外,增加 Actor 的同时,也会增加系统开销。

Actor 模型不适用于对消息处理顺序有严格要求的系统。因为在 Actor 模型中,消息均为异步消息,无法确定每个消息的执行顺序。虽然可以通过阻塞 Actor 去解决顺序问题,但显然,会严重影响 Actor 模型的任务处理效率。

  1. 可重用性低,业务逻辑的改变会导致整体代码的重写

  2. 工程上难以实现

  3. 不适用于对消息处理顺序有严格要求的系统

Actor 主要应用

1.Erlang/OTP: Erlang是面向并发的编程语言,OTP是Erlang技术栈中的标准库

2.Akka: 为java和scala构建高度并发、分布式和弹性的消息驱动应用程序的工具包

  1. Quasar(Java): 开源的JVM库

框架与语言

Actor 模型在 1973 年被提出,已广泛应用在多种框架和语言中。可以说,很多框架或语言支持 Actor 编程模型,是为了给开发者提供一个通用的编程框架,让用户可以聚焦到自己的业务逻辑上,而不用像面向对象等编程模型那样需要关心死锁、竞争等问题。

那么,到底有哪些框架或语言支持 Actor 编程模型呢?接下来,和你列举几个典型的框架或语言吧,以方便你参考。

  1. Erlang/OTP。Erlang 是一种通用的、面向并发的编程语言,使用 Erlang 编写分布式应用比较简单,而 OTP 就是 Erlang 技术栈中的标准库。Actor 模型在 Erlang 语言中得到广泛支持和应用,其他语言的 Actor 逻辑实现在一定程度上都是参照了 Erlang 的模式。实现了 Actor 模型逻辑的 Erlang/OTP,可以用于构建一个开发和运行时环境,从而实现分布式、实时的、高可用性的系统。

  2. Akka。Akka 是一个为 Java 和 Scala 构建高度并发、分布式和弹性的消息驱动应用程序的工具包。Akka 框架基于 Actor 模型,提供了一个用于构建可扩展的、弹性的、快速响应的应用程序的平台。通过使用 Actors 和 Streams 技术, Akka 为用户提供了多个服务器,使用户更有效地使用服务器资源并构建可扩展的系统。Quasar (Java) 。

  3. Quasar 是一个开源的 JVM 库,极大地简化了高度并发软件的创建。Quasar 在线程实现时,参考了 Actor 模型,采用异步编程逻辑,从而为 JVM 提供了高性能、轻量级的线程,可以用在 Java 和 Kotlin 编程语言中.

高可用: 分布式集群容错

The Actor Model (everything you wanted to know...)

Our CPUs are not getting any faster. What’s happening is that we now have multiple cores on them. If we want to take advantage of all this hardware we have available now, we need a way to run our code concurrently. Decades of untraceable bugs and developers’ depression have shown that threads are not the way to go. But fear not, there are great alternatives out there and today I want to show you one of them: The actor model.

The model

The actor model is a conceptual model to deal with concurrent computation. It defines some general rules for how the system’s components should behave and interact with each other. The most famous language that uses this model is probably Erlang. I’ll try to focus more on the model itself and not in how it’s implemented in different languages or libraries.

Actors

An actor is the primitive unit of computation. It’s the thing that receives a message and do some kind of computation based on it.

The idea is very similar to what we have in object-oriented languages: An object receives a message (a method call) and does something depending on which message it receives (which method we are calling).

The main difference is that actors are completely isolated from each other and they will never share memory. It’s also worth noting that an actor can maintain a private state that can never be changed directly by another actor.

One ant is no ant

And one actor is no actor. They come in systems. In the actor model everything is an actor and they need to have addresses so one actor can send a message to another.

Actors have mailboxes

It’s important to understand that, although multiple actors can run at the same time, an actor will process a given message sequentially. This means that if you send 3 messages to the same actor, it will just execute one at a time. To have these 3 messages being executed concurrently, you need to create 3 actors and send one message each.

Messages are sent asynchronously to an actor, that needs to store them somewhere while it’s processing another message. The mailbox is the place where these messages are stored.

image

Actors communicate with each other by sending asynchronous messages. Those messages are stored in other actors' mailboxes until they're processed.


What actors do

When an actor receives a message, it can do one of these 3 things:

  • Create more actors
  • Send messages to other actors
  • Designate what to do with the next message

The first two bullet points are pretty straightforward, but the last one is interesting.
I said before that an actor can maintain a private state. “Designating what to do with the next message” basically means defining how this state will look like for the next message it receives. Or, more clearly, it’s how actors mutate state.

Let’s imagine we have an actor that behaves like a calculator and that its initial state is simply the number 0. When this actor receives the add(1) message, instead of mutating its original state, it designates that for the next message it receives, the state will be 1.

Fault tolerance

Erlang introduced the “let it crash” philosophy. The idea is that you shouldn’t need to program defensively, trying to anticipate all the possible problems that could happen and find a way to handle them, simply because there is no way to think about every single failure point.

What Erlang does is simply letting it crash, but make this critical code be supervised by someone whose only responsibility is to know what to do when this crash happens (like resetting this unit of code to a stable state), and what makes it all possible is the actor model.

Every code run inside a process (that is basically how Erlang calls its actors). This process is completely isolated, meaning its state is not going to influence any other process. We have a supervisor, that is basically another process (everything is an actor, remember?), that will be notified when the supervised process crashes and then can do something about it.

This makes it possible to create systems that “self heal”, meaning that if an actor gets to an exceptional state and crashes, by whatever reason, a supervisor can do something about it to try to put it in a consistent state again (and there are multiple strategies to do that, the most common being just to restart the actor with its initial state).

Distribution

Another interesting aspect of the actor model is that it doesn’t matter if the actor that I’m sending a message to is running locally or in another node.

Think about it, if an actor is just this unit of code with a mailbox and an internal state, and it just respond to messages, who cares in which machine it’s actually running? As long as we can make the message get there we are fine.
This allows us to create systems that leverage multiple computers and helps us to recover if one of them fail.

Next steps and other resources

This was a quick overview of the conceptual model that is the base of great languages like Erlang and Elixir and libraries like Akka (for the JVM) and Celluloid (for Ruby).

If I was successful in making you curious about how this model is implemented and used in the real world, this is the list of books that I read or am reading about this topic and can recommend:

  • Seven Concurrency Models in Seven Weeks: When Threads Unravel
  • Programming Elixir
  • Elixir in Action

And if you are interested in more details about the conceptual idea itself, I can’t recommend this video enough:


http://www.taodudu.cc/news/show-4428588.html

相关文章:

  • java加载tensorflow训练的PB模型记录
  • linux端防火墙指定端口的开和关
  • 虚拟机防火墙关了怎么端口还是不能访问
  • linux防火墙关闭开放的端口,Linux关闭防火墙,开放端口
  • 安装mysql5.7防火墙关了为什么远程登录不了呢?
  • Oracle索引、视图、序列、同义词、事务、锁机制详解
  • Oracle中序列
  • oracle 语法简介说明 一
  • docker安装mysql并挂载配置文件和修改密码
  • java IO流(复习,上课笔记)
  • 【Oracle 数据库】奶妈式教程day15 DDL、DML、索引、视图、序列、死锁这一篇就够了
  • oracle基础技术点全记录
  • 面试智力题:如何才能证明自己不怕老婆
  • 什么样的女人适合嫁给男博士 ?
  • 1 简历该怎么写?注意事项--绝密,程序员大厂面试求职大揭秘!
  • 远征日服·信喵之野望 按键精灵脚本6.高级自动抽吉
  • BUU 杂项【喵喵喵】
  • 喵的Unity游戏开发之路 - 玩家控制下的球的滑动
  • Code128 编码规则
  • 8位二进制数中,对于-128的一些个人理解
  • 在一张图片上显示热力图(前端)
  • DEJA_VU3D - Cesium功能集 之 083-Cesium热力图实现完整版
  • 图像描述的注意力可视化
  • matlab语言剪力弯矩图,剪力图和弯矩图(史上最全面)
  • 软考高级系统架构设计师系列论文三十五:论企业应用集成
  • html怎么设置图片宽高比,CSS力图像调整尺寸和保持高宽比
  • oracle导入提示字符过长,Oracle 解决【ORA-01704:字符串文字太长】
  • java字符串Emoji表情的处理
  • Pthon.习题二 字符串的基本处理
  • 字符串中Emoji表情处理

Actor 分布式并行计算模型: The Actor Model for Concurrent Computation相关推荐

  1. hadoop基础----hadoop理论(四)-----hadoop分布式并行计算模型MapReduce详解

    我们在前一章已经学习了HDFS: hadoop基础----hadoop理论(三)-----hadoop分布式文件系统HDFS详解 我们已经知道Hadoop=HDFS(文件系统,数据存储技术相关)+ M ...

  2. 程序员修神之路--分布式高并发下Actor模型如此优秀

    写在开始 一般来说有两种策略用来在并发线程中进行通信:共享数据和消息传递.使用共享数据方式的并发编程面临的最大的一个问题就是数据条件竞争.处理各种锁的问题是让人十分头痛的一件事. 传统多数流行的语言并 ...

  3. Reactor模型,Actor模型

    背景 最近准备接手公司的消息系统,消息是系统是vert.x写的.突然觉得好懵逼,vert.x以前只听过名字,根本不知道是干啥的.然后开始了疯狂学习.此文是在学习vert.x过程中学到的知识.vert. ...

  4. 并行分布式计算 并行算法与并行计算模型

    文章目录 并行分布式计算 并行算法与并行计算模型 基础知识 定义与描述 复杂性度量 同步和通讯 并行计算模型 PRAM 模型 异步 PRAM 模型 (APRAM) BSP 模型 LogP 模型 层次存 ...

  5. AutoML大提速,谷歌开源自动化寻找最优ML模型新平台Model Search

    作者|魔王.杜伟 来源|机器之心 为了帮助研究者自动.高效地开发最佳机器学习模型,谷歌开源了一个不针对特定领域的 AutoML 平台.该平台基于 TensorFlow 构建,非常灵活,既可以找出最适合 ...

  6. python并行计算numpy_【Nature文章摘录】NumPy: 从单机到分布式并行计算

    原标题:[Nature文章摘录]NumPy: 从单机到分布式并行计算 点击上图,查看详情 本公众号的推送以互联网大数据技术为主,是<互联网大数据处理技术与应用><Python爬虫大数 ...

  7. 浅谈Opencl四大模型之Platform model

    Opencl是一种典型的异构架构,可以很好的实施并发性,为了简化并行计算复杂度以及兼容各个芯片差异性,opencl将其抽象为四大模型(Platform model, Execution model,M ...

  8. 分布式并行计算:概述

    顾名思义,分布式并行计算就是在单台机器多个GPU(单机多卡) 上,或者多台机器多个GPU(多机多卡) 上进行并行计算. 分布式计算带来了两个好处: 降低了 GPU 的显存压力.一块普通的 GPU 显存 ...

  9. 并行计算模型有哪些?

    写在前面 本文隶属于专栏<100个问题搞定大数据理论体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和文献引用请见100个问题搞定大数据理 ...

最新文章

  1. 详细谈电脑ip、域名、内网、外网、localhost、127.0.0.1、网关等通讯基础知识(易懂)
  2. db2关闭下一句sql的日志_MySQL性能管理及架构设计:SQL查询优化、分库分表
  3. C语言考研复试知识点整理
  4. zookeeper错误KeeperErrorCode = ConnectionLoss解决
  5. java float内存结构_Java后端开发岗必备技能:Java并发中的内存模型
  6. 5G 与边缘计算的发展现状(2021 年 6 月)
  7. c++局域网主动ftp_如何在局域网中实现 ARP 攻击
  8. BZOJ 1443: [JSOI2009]游戏Game
  9. 斐讯K2 22.4.6.3 非telnet 页面直刷 Breed 详细方法
  10. 杭电oj1087最长递增子序列java实现
  11. Linux入门——文件管理
  12. jpa的查询api_为JPA的本机查询API键入安全查询
  13. 超轻型的数据库sqlite
  14. 车票?工作?对象?Python 教你优雅解决年关三大难题!
  15. quartz集群分布式(并发)部署解决方案-Spring
  16. 怎么配置FlyMcu(stm32串口下载软件)有图 超详细
  17. m3u8文件下载及合并
  18. 基于Neo4j实现数据血缘管理
  19. DaVinci:RGB 混合器
  20. 获取非行内样式的兼容

热门文章

  1. 帖子浏览定位展开、收起标签js部分思路及代码
  2. LINUX下,C语言MALLOC可能达到的最大空间测试
  3. F7弹出界面模糊查询
  4. js手机号码校验,邮箱校验
  5. 【组合逻辑电路】如何从真值表中求解逻辑函数?
  6. 从语义网的角度看聊天机器人的产生
  7. Markdown编辑器推荐
  8. 抽奖随机滚动_仅需2分钟,使用excel制作一个抽奖小工具,再也不用为抽奖发愁了...
  9. 漫画:经典谷歌面试题“扔鸡蛋”,看看你会做吗?
  10. 病毒木马查杀实战第004篇:熊猫烧香之专杀工具的编写