Actor-ES框架:Ray
并发
1. 并发和并行
- 并发:两个或多个任务在同一时间段内运行。关注点在任务分割。
- 并行:两个或多个任务在同一时刻同时运行。关注点在同时执行。
本文大多数情况下不会严格区分这两个概念,默认并发就是指并行机制下的并发。
2. 好处
随着多核处理器的出现,并发编程可以提高程序的性能(吞吐量和响应能力)。
3. 并发实现方式
共享内存模型
因为并发能提高程序的性能,为了解决并发的需求,许多编程语言提供了共享内存通信机制(本文称为共享内存模型),体现是引入了Thread(线程)等概念。线程的出现解决了两个问题,一是GUI出现后急切需要并发机制来保证用户界面的响应;二是互联网发展后带来的多用户问题。但编写正确的并发、容错、可扩展的程序并不容易,对开发人员要求比较高,需要开发人员有能力处理避免死锁、互斥等待、竞争条件等问题。 当对程序进行纵向扩展(Scale Up)和横向扩展(Scale Out)时,问题会变得更加复杂。
为什么这么难:
We believe that writing correct concurrent, fault-tolerant and scalable applications is too hard. Most of the time it’s because we are using the wrong tools and the wrong level of abstraction. ——Akka
译:
我们认为写正确的并发、容错、可扩展的程序如此之难,是因为我们用了错误的工具和错误的抽象。——Akka
开发人员采用共享内存模型进行并发编程时,需要特别关注共享的数据结构及线程间的资源竞争导致的死锁等问题,这是一个非常大的难点,Actor模型可以很大程度地解决这些问题。
Actor模型
Actor模型这么好,Actor模型是什么?
Actor模型是一个概念模型,用于处理并发计算。它定义了一系列系统组件应该如何动作和交互的通用规则,最著名的使用这套规则的编程语言是Erlang。
Actor由3部分组成:状态(State)+行为(Behavior)+邮箱(Mailbox),State是指actor对象的变量信息,存在于actor之中,actor之间不共享内存数据,actor只会在接收到消息后,调用自己的方法改变自己的state,从而避免并发条件下的死锁等问题;Behavior是指actor的计算行为逻辑;邮箱建立actor之间的联系,一个actor发送消息后,接收消息的actor将消息放入邮箱中等待处理,邮箱内部通过队列实现,消息传递通过异步方式进行。
Actor是分布式存在的内存状态及单线程计算单元,一个Id对应的Actor只会在集群种存在一个(有状态的 Actor在集群中一个Id只会存在一个实例,无状态的可配置为根据流量存在多个),使用者只需要通过Id就能随时访问不需要关注该Actor在集群的什么位置。单线程计算单元又保证了消息的顺序到达,不存在Actor内部状态竞用问题。
Actor框架--Orleans
Actor模型这么好,怎么实现?
可以通过特定的Actor工具或直接使用编程语言实现Actor模型,Erlang语言含有Actor元素,Scala可以通过Akka框架实现Actor编程。目前C#语言中有两类比较流行,Akka.NET框架和Orleans框架。本文主要关注Orleans框架。
Orleans是微软开发的开源、分布式、跨平台的Virtual Actor框架,可以方便C#开发者开发分布式、高扩张、高并发、低延时的应用程序。
架构落地
1. N-Tier架构(代表三层)
N-Tier架构的代表是三层架构,实际项目分了很多层,多数是三层的延伸。传统的三层体系结构包括无状态的前端,无状态的中间层和存储层。
这种架构存在两个比较大的问题:
- 由于存储层在延迟和吞吐量方面的限制,系统很难处理高并发的场景。这种结构下通常的办法是在中间层和存储层之间添加缓存层来提高性能。如果引入的是分布式缓存,又会引入状态同步问题,这时候就需要考虑如何精准快速的更新缓存。
- 这种无状态的N-Tier架构,中间层内独立的应用实体之间通信很不方便,当一个请求需要多实体之间调用时,为业务代码的实现带来了困难。
Actor在架构层面上提供了一个简单的方式来构建无锁分布式大规模的应用程序,而不需要学习和应用复杂的并发和分布式控制,有效的解决了上述两个问题。
Orleans提供了一种直接的方式构建有状态的中间层,大量的业务逻辑实体分布式地部署在集群中,彼此相互独立,又可以相互访问。
缺点:
Orleans技术很优秀,许多人想用,但是目前国内圈子里的资料很少,代码多是Demo,Actor初接触通常觉得不易理解,使得大家找不到Orleans落地的方式。
2. Event Sourcing
在Orleans中,actor中的数据(State)存在于内存中,内存中的数据在断电、重启的场景下会丢失,可以使用Event Sourcing技术解决这一问题,Actor的状态修改是由事件驱动的,事件被持久化起来,然后通过Event Sourcing的技术,还原特定Actor的最新状态到内存。不仅如此,Event Sourcing还会极大地降低系统的耦合性。
什么是事件溯源
一个对象从创建开始到消亡会经历很多事件,以前我们是在每次对象参与完一个业务动作后把对象的最新状态持久化保存到数据库中,也就是说我们的数据库中的数据是反映了对象的当前最新的状态。而事件溯源则相反,不是保存对象的最新状态,而是保存这个对象所经历的每个事件,所有的由对象产生的事件会按照时间先后顺序有序的存放在数据库中。
事件溯源:
不保存对象的最新状态,而是保存对象产生的所有事件。
通过事件溯源(Event Sourcing,ES)得到对象最新状态。
Actor内数据的修改,是ACID强一致性的;跨Actor的数据修改,是最终一致性的,通过EventSourcing实现。这样可以让我们最大化的降低并发冲突,从而最大化的提高整个系统的吞吐。Actor和DDD,CQRS,Event Soucing(事件溯源)设计模型有天然的融合性,基于Actor可以很好的进行以上实践。
EventSourcing的概念通常跟CQRS放在一起,CQRS/ES的概念常常出现在DDD中,在DDD中,有许多程序员向往的实现,但是里面的抽象概念比较多,只熟悉三层的开发人员很难驾驭这些概念,基于这些概念提出的架构设计更是难以捉摸,一些前辈为探索DDD最佳实践,开发了一些DDD框架,但实际项目中,很难保证系统性能。
Actor不好理解,CQRS/ES、DDD不好理解,恰恰这些技术交织在一起能很好的使彼此落地。
3. Ray
说了这么多,目的是为了引出Ray。
Ray是一个集成Actor、Event Sourcing(事件溯源)、Eventual Consistency(最终一致性)的无数据库事务、高性能分布式云框架。Ray是一个非常精致小巧的Actor/ES框架,来自生产环境,踩了很多坑,降低了Actor、ES的开发难度。
来自生产环境
ASP.NET Core、Redis、MongoDB、跨平台、gRPC、RabbitMQ、Dapper……许多朋友都掌握了,但依旧好像缺些什么,或许可以尝试一下新的旅程。这是项目的地址: https://github.com/RayTale, 欢迎大家讨论、参与、使用。
设计图
这张图方便大家初步了解Ray,但是太过强调细节,对DB太过突出,而Event没有突出出来。
这张图更简洁明了一些。
参考:
深度长文:我对CQRS/EventSourcing架构的思考
Actor-ES框架:Ray的更多相关文章
- 学界| UC Berkeley提出新型分布式框架Ray:实时动态学习的开端—— AI 应用的系统需求:支持(a)异质、并行计算,(b)动态任务图,(c)高吞吐量和低延迟的调度,以及(d)透明的容错性。
学界| UC Berkeley提出新型分布式框架Ray:实时动态学习的开端 from:https://baijia.baidu.com/s?id=1587367874517247282&wfr ...
- 解析分布式应用框架Ray架构源码
摘要:Ray的定位是分布式应用框架,主要目标是使能分布式应用的开发和运行. Ray是UC Berkeley大学 RISE lab(前AMP lab) 2017年12月 开源的新一代分布式应用框架(刚发 ...
- 框架Ray
高性能最终一致性框架Ray之基本概念原理 一.Actor介绍 Actor是一种并发模型,是共享内存并发模型的替代方案. 共享内存模型的缺点: 共享内存模型使用各种各样的锁来解决状态竞争问题,性能低下且 ...
- CQRS/ES框架调研
1.Enode一个C#写的CQRS/ES框架,由汤雪华设计及实现,github上有相关源码,其个人博客上有详细的孵化.设计思路.版本迭代及最新的完善: 2.axon framwork,java编写,网 ...
- 高性能分布式执行框架——Ray
Ray是UC Berkeley AMP实验室新推出的高性能分布式执行框架,它使用了和传统分布式计算系统不一样的架构和对分布式计算的抽象方式,具有比Spark更优异的计算性能. Ray目前还处于实验室阶 ...
- 高性能最终一致性框架Ray之基本概念原理
一.Actor介绍 Actor是一种并发模型,是共享内存并发模型的替代方案. 共享内存模型的缺点: 共享内存模型使用各种各样的锁来解决状态竞争问题,性能低下且让编码变得复杂和容易出错. 共享内存受限于 ...
- 高性能最终一致性框架Ray之基本功能篇
一.Event(事件) Event是Actor产生的记录状态变化的日志,由StateId(状态Id),UID(幂等性控制),TypeCode(事件类型),Data(事件数据),Version(事件版本 ...
- 取代 Python 多进程!伯克利开源分布式框架 Ray
Ray 由伯克利开源,是一个用于并行计算和分布式 Python 开发的开源项目.本文将介绍如何使用 Ray 轻松构建可从笔记本电脑扩展到大型集群的应用程序. 并行和分布式计算是现代应用程序的主要内容. ...
- 基于Actor模型的CQRS、ES解决方案分享
开场白 大家晚上好,我是郑承良,跟大家分享的话题是<基于Actor模型的CQRS/ES解决方案分享>,最近一段时间我一直是这个话题的学习者.追随者,这个话题目前生产环境落地的资料少一些,分 ...
随机推荐
- [数据清洗]-使用 Pandas 清洗“脏”数据
概要 准备工作 检查数据 处理缺失数据 添加默认值 删除不完整的行 删除不完整的列 规范化数据类型 必要的转换 重命名列名 保存结果 更多资源 Pandas 是 Python 中很流行的类库,使用它可 ...
- WPF后台写ControlTemplate总结
这段时间写ControlTemplate的时候发现绑定的时候有些问题需要总结: 实例ControlTemplate如下: <UserControl x:Class="ArcGISWpf ...
- JAVA图片批量上传JS-带预览功能
这篇文章就简单的介绍一个很好用的文件上传工具,批量带预览功能.直接贴代码吧,都有注释,很好理解. HTML页面 <!DOCTYPE html> <%@ taglib prefix=& ...
- 解决openssh漏洞,升级openssh版本
关于解决漏洞的问题我就不详说了,主要就是升级版本.这里我们就直接简单记录下步骤: 1.升级 使用root用户登录系统进入到/home/guankong ,上传openssh-6.6p1.tar.gz到 ...
- Siamese Network理解
提起siamese network一般都会引用这两篇文章: <Learning a similarity metric discriminatively, with application to ...
- K:线性表
1. 线性表在计算机中可以用顺序存储和链式存储两种存储结构来表示.其中用顺序存储结构表示的线性表成为顺序表,用链式存储结构表示的线性表称为链表,链表又有单链表,双向链表,循环链表之分. 2. 线性表是 ...
- springMVC(6)---处理模型数据
springMVC(6)---处理模型数据 之前一篇博客,写个怎么获取前段数据:springMVC(2)---获取前段数据,这篇文章写怎么从后端往前端传入数据. 模型数据类型 ...
- python导入模块时的执行顺序
当python导入模块,执行import语句时,到底进行了什么操作?按照python的文档,她执行了如下的操作: 第一步,创建一个新的module对象(它可能包含多个module) 第二步,把这个mo ...
- golang 多维数组
具体的题目如下:(就是将多维数组的行列互换) A multi-dimensional array is an array of arrays. 2-dimensional arrays are the ...
- 【Java框架型项目从入门到装逼】第六节 - 用ajax请求后台数据
这一节我们来说一下如何用ajax提交请求? 我们先不讲ajax的原理,还是先以实战为主,看一下这个东西到底怎么用的? form表单: <!-- 采用post表单提交 --> <for ...