Actor模型浅析 一致性和隔离性
一.Actor模型介绍
在单核 CPU 发展已经达到一个瓶颈的今天,要增加硬件的速度更多的是增加 CPU 核的数目。而针对这种情况,要使我们的程序运行效率提高,那么也应该从并发方面入手。传统的多线程方法又极其容易出现 Bug 而难以维护,不过别担心,今天将要介绍另一种并发的模式能一定程度解决这些问题,那就是 Actor 模型。
Actor 模型其实就是定义一组规则,这些规则规定了一组系统中各个模块如何交互及回应。在一个 Actor 系统中,Actor 是最小的单元模块,系统由多个 Actor 组成。每个 Actor 有两个东西,一个是 mailbox,一个是自身状态。同时 Actor 有接收和发送的功能。下面代码给出一个大概的 Actor 样例:
trait Actor {
//持有一个表示自身状态的私有变量
val state:Integer = 0;
//持有一个mailbox 的队列
val mailBox:mutable.Queue[Message] = scala.collection.mutable.Queue[Message]()
def send(message : Message): Unit ={
...
}
def recive(): Unit ={
...
}
}
当一个 Actor 接收到消息后,它会执行下面三种操作中的一种:
- 创建其他 Actor。
- 向其他 Actor 发送消息。
- 修改自身状态。
需要注意的是,尽管许多 Actor 同时运行,但是一个actor只能顺序地处理消息。也就是说其它 Actor 发送了三条消息给一个 Actor ,这个 Actor 只能一次处理一条。所以如果你要并行处理3条消息,你需要把这条消息发给3个actors。
下面这张图展示了一个简单的 Actor 模型系统:
了解了 Actor 模型的大概规则后,我们用两个具体的例子来看看 Actor 模型的妙处以及不足吧。
二. 两个例子
2.1 素数计算
假设我们现在有一个任务,需要找出100000以内素数个数,并且使用多线程的方式实现。
下图展示了使用共享内存的方式和以Actor模型的方式进行并发执行。
这里展示了两种处理并发的不同思路,传统的方式是通过锁/同步的方式来实现并发,每次同步获取当前值,并让一个线程去判断值是否为素数,是的话再通过同步的方式对计数器加1(这里的说明只是作为提供思路用,这种方法自然有很大的优化空间)。
而使用 Actor 模型则不一样,它将这一过程拆分成几个模块,即拆分成几个 Actor 。每个 Actor 负责不同的部分,通过消息传递的方式让这几个 Actor 协同工作,并且其中涉及到主要计算的 Actor 可以有多个,通过多个 Actor 协同工作实现并发。
2.2 银行转账
银行转账的任务描述很简单,假设有两个用户,现在用户A向用户B转账100元,这个 Actor 模型该如何设计呢?
用户 A 和 用户 B 明显是两个 Actor ,但我们同时还需要一个可以控制用户A Actor 和用户B Actor 的 Actor ,我们称之为 转账管家 Actor。那么流程图如下。
可以看到,当一个转账需求过来的时候,Actor 管家会先向 用户A Actor 发送扣款 100 元的信息,接受到扣款成功消息后再发送消息给用户B Actor,发送让其增加 100 元的消息。
一切看起来都很美好是吧,但这里面有一个问题,那就是在用户A Actor 扣款期间,用户B Actor 是不受限制的,此时对用户B Actor 进行操作是合法的!针对这种情况单纯的Actor模型就显得比较乏力了,需要加入其他机制以保证一致性。
看到这你就明白了,Actor 模型并非万能的,它有一定的缺点。那就是针对一致性要求比较强的场景比较乏力。
三. 为什么会出现 Actor 模型
接下来我们来聊聊为什么会有 Actor 模型这种并发编程模型出现。
我们需要先说说并发性中的一致性和隔离性。
一致性即让数据保持一致,比如银行转账例子中,用户A 转给 用户B 100块钱,没有其他干扰的情况下,转账完成时。用户A 的账户必然减少 100 元,用户B 的账户必然增加100 元,这就满足了一致性。不能说用户A 减少50 或用户B 增加了 200。
隔离性可以理解为牺牲一部分的一致性需求,而获得性能的提高。打个比方,在完全一致的情况下,任务都是串行的,这时候也就不存在隔离性了。
明白这些之后,你就直到为什么会有 Actor 模型了。
传统并发模式,共享内存是倾向于强一致性弱隔离性的。比如悲观锁/同步的方式,其实就是使用强一致性的方式控制并发。而 Actor 模型天然是强隔离性且弱一致性,所以 Actor 模型在并发中有良好的性能,且易于控制和管理。
这样你就明白 Actor 模型适合于什么样的并发场景了,当对一致性需求不是很高的情况下且对性能需求较高时,Actor 模型无疑是一个值得尝试的方案。
推荐阅读 :
从分治算法到 MapReduce
Actor并发编程模型浅析
大数据存储的进化史 --从 RAID 到 Hadoop Hdfs
Actor模型浅析 一致性和隔离性的更多相关文章
- 事务四大特征:原子性,一致性,隔离性和持久性(ACID)
一.事务 定义:所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位. 准备工作:为了说明事务的ACID原理,我们使用银行账户及资金管理的案例进行分析. [sql] ...
- 数据库事务ACID特性(原子性、一致性、隔离性、持久性)
ACID特性: 原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability) 原子性:一个事务必须被视为一个不可分割的最小工作单元,整个 ...
- acid-事务的原子性、一致性、隔离性、持久性
博客分类: oracle-dba 原子性 多个事情组成一个单元,要么同时成功或失败,不能只运行其中一个 一致性 事务处理要将数据库从一种状态转变为另一种状态. 一旦提交了修改数据,那么其它人读 ...
- Mysql学习之事务的隔离性
今天咱们说说事务,相信大家都知道事务的 ACID (Atomicity.Consistency.Isolation.Durability,即原子性.一致性.隔离性.持久性). 原子性:表示一个事务不可 ...
- mysql 隔离性与隔离级别
提到事务,你肯定不陌生,和数据库打交道的时候,我们总是会用到事务.最经典的例子就是转账,你要给朋友小王转 100 块钱,而此时你的银行卡只有 100 块钱. 转账过程具体到程序里会有一系列的操作,比如 ...
- ACID隔离性
数据库ACID 一致性 原子性 隔离性 持久性 隔离性: 1.读未提交 2.读已提交 3.可重复读 4.串行 读未提交:容易引起脏读 读已提交:容易引起幻读(前后读到的行数不一致) 场景: A事务 ...
- SqlServer事务详解(事务隔离性和隔离级别详解)
概述 不少人对于事务的使用局限于begin transaction:开始事务.commit transaction:提交事务.rollback transaction:回滚事务的初步运用. 并且知道使 ...
- 高系统的分布性有状态的中间层Actor模型
写在前面 https://www.cnblogs.com/gengzhe/p/ray_actor.html Orleans是基于Actor模型思想的.NET领域的框架,它提供了一种直接而简单的方法来构 ...
- 事务的四大属性ACID即事务的原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability.。
事务的四大属性ACID即事务的原子性(Atomicity).一致性(Consistency).隔离性(Isolation).持久性(Durability.. 原子性(Atomicity) 原子性是指事 ...
随机推荐
- [Swift]LeetCode349. 两个数组的交集 | Intersection of Two Arrays
Given two arrays, write a function to compute their intersection. Example 1: Input: nums1 = [1,2,2,1 ...
- C语言——Win10系统下安装VC6.0教程
学习一门语言最重要的一步是搭建环境,许多人搭建在搭建环境上撞墙了,就有些放弃的心理了:俗话说,工欲善其事,必先利其器:所以接下来我们进行学习C的第一步搭建环境; 第一步:先解压我们下载好的VC6.0软 ...
- Spring中的IOC_源码_随笔
Spring ioc 叫控制反转,也就是把创建Bean的动作交给Spring去完成. spring ioc 流程大致为 定位-> 加载->注册 先说几个比较有意思的点 1.Spring中 ...
- 关于 redis.properties配置文件及rule
当你配置的 FinanceRlue 的path为/count/users时,redis.properties中就必须也配置一个/users=redis://localhost:6379/2?keyle ...
- vue组件,可以通过npm引用的组件
本文章通过实现一个vue-dialog的弹出层组件,然后附加说明如果发布此包到npm,且能被其他项目使用. 功能说明 多层弹出时,只有一个背景层. 弹出层嵌入内部组件. 弹出层按钮支持回调 源码下载 ...
- C#版 - PAT乙级(Basic Level)真题 之 1024.科学计数法转化为普通数字 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. PAT Bas ...
- 你安装的是SUN/Oracle JDK还是OpenJDK?
目录 1 如何查看你安装的JDK版本 1.1 要用到的命令行工具 1.2 查看JDK的版本 2 什么是 OpenJDK 2.1 OpenJDK 的来历 2.2 Oracle JDK的来历 3 Orac ...
- 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes
前言 在之前的一篇文章中,我们介绍了 如何将一个本地的 Java 应用程序直接部署到阿里云 ECS ,有不少读者反馈,如果目前已经在使用阿里云容器服务 Kubernetes 了,那该如何配合这个插件部 ...
- ubuntu 15.10 设置静态ip 分配固定ip 设置dns 设置网关 命令行配置ip 固定ip不生效怎么办
要用到的文件: 配置接口信息 /etc/network/interfaces 配置内容: auto eth0 iface eth0 inet static address 192.168.216.18 ...
- [VsCode] 开发所使用的VsCode的插件
vscode 的插件 必须 Chinese (Simplified) Language Pack for Visual Studio Code Markdown Preview Enhanced De ...