Akka 作为持久的参与者存储一个丰富的对象会是一个好主意吗?

Akka 作为持久的参与者存储一个丰富的对象会是一个好主意吗?,akka,event-sourcing,akka-persistence,Akka,Event Sourcing,Akka Persistence,如果您熟悉Trello,将整个Trello板存储为参与者(使用akka持久性)是一个好的用例吗 trello板由以下部分组成: 列表 列表中的任务 每个任务都可以有注释和其他属性 在决定akka持久性是否是给定问题集的良好用例时,一般的最佳实践或考虑事项是什么 这主要取决于应用程序要执行多少写操作 Akka persistence是一种实现非常高的写入吞吐量的方法,同时确保数据的持久性,即,如果参与者死亡且内存中的数据丢失,则写日志可以持久化到磁盘 如果数据的持久性是必要的,而不需要非常高的

如果您熟悉Trello,将整个Trello板存储为参与者(使用akka持久性)是一个好的用例吗

trello板由以下部分组成:

  • 列表
  • 列表中的任务
  • 每个任务都可以有注释和其他属性
在决定akka持久性是否是给定问题集的良好用例时,一般的最佳实践或考虑事项是什么


这主要取决于应用程序要执行多少写操作

Akka persistence是一种实现非常高的写入吞吐量的方法,同时确保数据的持久性,即,如果参与者死亡且内存中的数据丢失,则写日志可以持久化到磁盘


如果数据的持久性是必要的,而不需要非常高的写入吞吐量(假设应用程序每秒更新Trello板1次),那么只需将数据写入外部存储器就完全可以了。

任何事件源非常适合的上下文都非常适合Akka持久性

反过来,事件源通常是适用的(请注意,您使用的几乎所有数据库都是事件源(具有异常频繁的快照、截断事件日志和清除旧快照))

当您想要明确地对域中的实体如何随时间变化进行建模时,事件源非常有效:您正在有效地定义一个变化代数。这种变化模式越丰富(即,离创建/更新越远),就越适合事件来源。这种变更建模反过来有助于让系统的其他组件仅在需要时更新其状态

Akka持久性,特别是当与集群分片一起使用时,允许您处理命令/请求,而不必在每个命令/请求上从DB读取(基本上,当带回已持久化的参与者时,您将从DB读取,但后续的命令/请求(直到参与者钝化或死亡)不需要这样的读取). Akka中的父母和孩子角色模型也倾向于导致多对一关系的自然编码

在trello板的例子中,我可能会

  • 每个板都是一个持久参与者,它是
  • 列表,它们是持久的参与者,并且是每个参与者的父级
  • 列出项目,它们也是持久参与者
根据列表项下的内容,他们可能会有子持久参与者(用于评论等)

关于领域驱动的设计可能值得一读。虽然DDD不需要actor模型(反之亦然),也不需要事件源(反之亦然),但我和许多其他人发现它们相互加强

将整个Trello董事会存储为演员(与akka一起) 持久性)是一个好的用例


我认为参与者的大小应该与聚合根的大小相匹配。让整个董事会成为聚合根似乎是一个非常糟糕的选择。这意味着该板上的所有操作现在都已序列化,并且不能同时执行任何操作。为什么更改卡#1的描述会与移动的车#2冲突到不同的类别?为什么创建新的董事会类别与将卡片#3分配给某人冲突


我的意思是,你可以让整个系统成为一个单一的参与者,你永远不必关心竞争条件,但你也会扼杀你的可伸缩性…

如果没有高吞吐量,那么使用持久参与者总是一个坏主意吗?如果我只是喜欢它的简单性,以及如何将数据保存到磁盘等更快地进行开发,该怎么办?@Blankman您当然可以,只需注意它带来了额外的一层复杂性。如果您对Cassandra和活动采购非常熟悉,请随意选择这条路线。只是写一个SQL数据库非常简单,而且很容易理解。你能给我一些现实世界中使用akka持久性的例子吗?谢谢你的概述。你建议的设计唯一的问题是呈现一个棋盘,它需要演员之间进行大量的沟通,比如说,1个演员获得棋盘,5个演员获得5个列表,然后如果每个列表有10个项目,那就是50次调用。每个列表项下的任何东西都意味着50 x n个东西。这真的很快就累积起来了……您不必为每个参与者单独进行REST调用(参与者间通信的延迟比REST调用的延迟低得多)。相反,尽管只需一次调用就可以获取所有内容,但很有可能最终请求的内容会远远超出您的需要(序列化/反序列化时间加起来很快)。child-actor方法的另一个好处是并行性(无论您是直接将REST请求路由给孩子,还是让董事会进行分散收集,都是如此)!出于好奇,使用您提出的模型,您如何处理项目从一个列表到另一个列表的更改?我不是演员模型的专家,但我认为改变演员的父母是一件复杂的事情。在我看来,您需要执行两个命令来执行“从第一个列表中删除”“添加到第二个列表”。将列表项作为董事会的直接子项,并将其作为状态的一部分包含在列表中(如具有列表id的属性)不是更好吗?通常情况下,参与者的父项不会更改,因此属于列表a的列表项如果属于列表B,则严格来说不会是相同的列表项。因此命令明智“从列表A移到列表B”将被解释为类似“提议密封此列表项”、“使用这些属性在列表B中创建列表项(其中之一是它曾经是A下的此项)”、“密封此列表项,并注明其已被列表B中的项所取代”(密封基本上被理解为拒绝进一步写入,但仍可用于读取)。On