具有akka持久性的批处理操作,有哪些选项?

问题描述

说我正在使用akka持久性,并且支持诸如Users之类的东西。

如果有一项工作需要扫描所有用户,并且已经过期以将其对象标记为已过期的任何用户,则该扫描。

在使用sql的更传统的设置中,您只需执行以下操作:

update u
  set u.is_expired=1
from users u
where u.expired_at >= getdate()

现在,如果这样做,您的akka​​持久性将不同步,您将不得不以某种方式广播给所有演员以重新加载。

否则,您必须向所有演员发送广播,以检查您是否已过期。

如果您有数百万的用户,那么您有哪些现实的选择? 如果这是数据库存储过程,则这种查询可以在几秒钟内完成。

试图了解如何通过akka和akka-persistance做到这一点。

解决方法

使用Akka Persistence可以通过两种易于使用的方法来进行此类操作。两者都利用Persistence Query来查询事件流。

如果实体数量很少,则可以使用currentPersistenceIds()查询(我知道的所有持久性实现都支持此查询)来获取当时存在的实体流(流节流和背压可能会派上用场),然后向每个实体的关联持久性参与者发送命令以检查是否过期。

在某一点之后,拥有一个单独的数据库来维护将实体ID映射到到期时间的实体视图可能是有意义的。为此,您可能会使用eventsByTag查询来获取标有"affects-expiration"的事件流;流中的后续阶段然后更新该数据库。然后,批处理作业可以查询该数据库并发出到期命令。

数据库的另一种选择是拥有一个持久性参与者,该参与者维护一组未过期实体及其过期时间。该参与者可以是单身人士,也可以以能够一致地确定哪个特定参与者将维持给定实体的到期时间的方式进行分片。可以通过eventsByTag流(最终是一致的)或实体参与者本身(要强得多的一致,但是通常要注意不要比您需要的一致性)来更新它。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...