特性与实践
Actor 特性与实践
Actor 编程模型通过允许程序员更容易地进行行为推理,提供轻量级的并发原语(可以自然地跨许多机器进行扩展)以及实现系统组件之间的松散耦合以进行更改而不会中断服务,从而为分布式系统的程序员带来了好处。Actor 使程序员能够更轻松地对其行为进行推理,因为它们在根本上与其他 Actor 隔离。对 Actor 进行编程时,程序员只需要担心该 Actor 的行为以及它可以发送和接收的消息。这减轻了程序员对整个系统进行推理的需要。相反,程序员有一系列固定的关注点,这意味着他们可以孤立地确保行为的正确性,而不必担心意外的交互。Actor 提供了一种单一的通信方式(消息传递),这意味着减轻了程序员对数据并发修改的许多担忧。数据仅限于单个参与者中的数据及其已传递的消息,而不是整个系统中的所有可访问数据。
Actor 是轻量级的,这意味着程序员通常不必担心他们正在创建多少 actor。这与诸如线程或进程之类的其他并发基本单元形成了鲜明对比,程序员必须敏锐地意识到它们,因为它们会导致较高的创建成本,并迅速遇到机器资源和性能限制。
Without a lightweight process abstraction, users are often forced to write parts of concurrent applications in an event-driven style which obscures control flow, and increases the burden on the programmer. -Philipp Haller (Haller & Odersky, 2009)
与线程和进程不同,由于 Actor 在功能上是隔离的,因此也可以轻易地告诉他们在其他机器上运行。传统上,这无法使用线程或进程来完成,因为它们无法通过网络传递以在其他地方运行。消息可以通过网络传递,因此只要参与者可以发送和接收消息,Actor 就不必关心它在哪里运行。由于此特性,它们具有更高的可伸缩性,这意味着参与者可以自然地分布在许多机器上,以满足系统的负载或可用性需求。
最后,由于参与者是松散耦合的,因此仅取决于与其他参与者之间的一组输入和输出消息,可以在不更改整个系统的情况下修改和升级他们的行为。例如,单个 Actor 可以升级为使用性能更高的算法来完成其工作,并且只要它可以处理相同的输入和输出消息,系统中的其他内容就无需更改。这种隔离与并发编程方法(如远程过程调用,期货和承诺)形成对比。这些模型强调计算单元之间的紧密耦合,其中一个过程可以直接在另一个过程上调用一个方法,并期望获得特定的结果。这意味着呼叫者和被呼叫者(呼叫的接收者)都需要了解正在运行的代码,因此您将失去升级一个而不影响另一个代码的能力。在实践中,这成为一个问题,因为这意味着随着分布式系统的复杂性的增长,越来越多的组件被链接在一起。
It is important to note that the actor languages give special emphasis to developing flexible program structures which simplify reasoning about programs.
- Gul Agha (Agha, 1990)
这是不希望的,因为分布式系统的一个关键特性是可用性,并且链接在一起的东西越多,您必须拆卸或停止进行更改/升级的系统越多。由于 Actor 的低成本和松散耦合的特性,它们比其他并行编程原语(例如线程或远程过程调用)更具优势。它们还对程序员友好,并减轻了程序员对分布式系统进行推理的负担。
Actor 特性
并发
Actor 有许多优良的特性,适用于解决多种并发问题。消息传输和封装虽然多个 Actor 可以同时运行,但它们并不共享状态,而且在单个 Actor 中所有事件都是串行执行的。所以关于并发,只需要关注于多个 Actor 之间的消息流即可。对开发人员来说这是个重大利好。每个 Actor 可以被单独测试,而且当测试覆盖了某个 Actor 的消息类型和消息顺序时,就可以确定这个 Actor 非常可靠。如果发现了一个与并发相关的 bug,也就知道重点应该放在 Actor 之间的消息流上。
使用 Actor 模型的程序天生具有容错性。这不仅会让程序更加强壮,而且(通过“任其崩溃”的哲学)会让代码更加简洁明了。
Actor 模型支持共享内存模型,也支持分布式内存模型,这就带来了很多优点。首先,Actor 模型几乎可以解决任何规模的问题。我们不需要将问题局限于用一个系统解决。其次,Actor 模型可以解决地理分布式问题。对于不同部分需要部署在不同地理位置的软件,Actor 模型是个极佳的选择。最后,分布式是软件具有容错能力的基石。
尽管使用 Actor 模型的程序比使用线程与锁模型的程序更容易 debug,但 Actor 模型仍会碰到死锁这一类的共性问题,也会碰到一些 Actor 模型独有的问题(例如信箱溢出)。
类似于线程与锁模型,Actor 模型对并行也没有提供直接支持。需要通过并发的技术来构造并行的方案,这样就会引入不确定性。而且,由于多个 Actor 并不共享状态,仅通过消息传递来进行交流,所以不太适合实施细粒度的并行。
现代实践
在审查编程分布式系统的模型时,重要的是不仅要看学术界,还要看这些系统中的哪些实际上在工业中用于构建事物。这可以使我们了解参与者系统的哪些功能实际上有用,以及这些系统中存在的趋势。
关于主流技术中 Actor 模型的集成:Scala 观点(Haller,2012 年)提供了对主流平台上具有工业实力的 actor 实施要求的一些见解。这些要求来自于 Scala Actors 的初步努力,旨在将 Actor 模型带入主流软件工程,以及从 Akka 部署和提升生产 actor 中学到的经验教训。
这些属性为我们分析 Actor 系统是否可以成功生产提供了良好的基础。这些是必需的属性,但不足以使参与者系统在生产中有用。