Akka删除持久消息

Akka删除持久消息,akka,akka-persistence,Akka,Akka Persistence,我正在写一个应用程序来处理设备引发的事件(每小时一百万)。一些事件将被聚合(并且具有很长的时间跨度(例如48小时)),其中包含开始事件、状态(x倍)-事件和结束事件。其他是可以立即处理的单个事件。为了保证事件至少能被处理一次,我正在研究akka持久性。应用程序的其他部分已经使用akka和kafka 我想要的解决方案应该包含一个持久性映射,在这个映射中,可以通过事件ID轻松地从中选择事件。顺序不那么重要。在完成对事件的处理后,可以将其从映射中删除(并且不再持久化) 在找到的文档/示例中,我找到了满

我正在写一个应用程序来处理设备引发的事件(每小时一百万)。一些事件将被聚合(并且具有很长的时间跨度(例如48小时)),其中包含开始事件、状态(x倍)-事件和结束事件。其他是可以立即处理的单个事件。为了保证事件至少能被处理一次,我正在研究akka持久性。应用程序的其他部分已经使用akka和kafka

我想要的解决方案应该包含一个持久性映射,在这个映射中,可以通过事件ID轻松地从中选择事件。顺序不那么重要。在完成对事件的处理后,可以将其从映射中删除(并且不再持久化)

在找到的文档/示例中,我找到了满足每事件清除要求的队列示例,但在轻松查找方面遇到了困难(必须循环队列才能找到事件)。为了满足简单的查找,我想到了使用map,使用persistenctor特性和下面的一些db。但是,事件由sequencenumber清除(这将删除需要更多处理/正在等待其他事件发生的事件)。调查的另一个特性是AtLeastOnceDelivery,交付确认满足要求,但这一特性会阻止恢复,直到处理完所有事件


关于如何在阿克卡实现一个持久的活动篮子,有什么想法吗?(我使用的是scala btw)

这样的东西适合您的需要吗? 这可能不完全是您的逻辑,但基本上它接收一个新事件,保持它接收到事件的事实,然后使用id将事件保存到映射中。 然后在某个时刻(不确定如何触发事件处理),它会接收到处理具有特定id的事件的命令。它会保留本应处理该事件的事实,然后处理该事件并将其从映射中删除。 这样,地图将在重新启动时恢复,您可以通过Id访问所有尚未处理的事件

class PersistentMapActor extends PersistentActor {

    private var eventMap: Map[ Int, Event ] = Map[ Int, Event ]( )

    override def receiveRecover: Receive = {
            case NewEventSaved( payload: Event ) =>
                    eventMap = eventMap + ( (payload.eventId, payload) )
            case EventHandled( eventId ) =>
                    eventMap = eventMap - eventId
    }

    override def receiveCommand: Receive = {
            case SaveNewEvent( payload ) =>
                    persist( NewEventSaved( payload ) ) { persistedNewEvent =>
                            //Add new event to map
                            eventMap = eventMap + ( (payload.eventId, payload) )
                    }
            case HandleEvent( eventId ) =>
                    val event = eventMap.get( eventId )

                    event.foreach { e =>
                            persist( EventHandled( eventId ) ) { persistedEvent =>
                                    //Do stuff with the event
                                    //Remove the event from the map
                                    eventMap = eventMap - eventId
                            }
                    }
    }

    override def persistenceId: String = "PersistentMapActor"
}

object PersistentMapActor {

    case class Event( eventId: Int, someField: String )

    case class SaveNewEvent( payload: Event )

    case class NewEventSaved( payload: Event )

    case class HandleEvent( eventId: Int )

    case class EventHandled( eventId: Int )

}

谢谢你的回答。我实现了您的解决方案,并为持久性层添加了一个后台作业。已处理事件的计划后台作业检查将从数据库中删除它们。很高兴我能提供帮助。我想问一下,为什么要删除已处理的事件?因为存储数据没有好处,只有涉及成本方面的缺点。每个事件的大小约为20kb,每小时100万个事件。我们没有足够的磁盘空间让它运行多年(而且使用品牌化的高可用性产品仍然很昂贵(业务需求))。事件本身是无用的,这就是事件处理的地方,聚集/分组事件,只在数据库中存储计算的事件。