【发布时间】:2012-01-10 04:29:11
【问题描述】:
我正在尝试使用 Akka 和 Scala 构建一个高性能的分布式系统。
如果请求昂贵(且无副作用)计算的消息到达,并且之前已请求完全相同的计算,我想避免再次计算结果。如果之前请求的计算已经完成并且结果可用,我可以缓存它并重新使用它。
但是,可以请求重复计算的时间窗口可以任意小。例如出于所有实际目的,我可以在同一时刻收到一千或一百万条请求相同昂贵计算的消息。
有一个名为 Gigaspaces 的商业产品据说可以处理这种情况。
但是,目前在 Akka 中似乎没有框架支持处理重复的工作请求。鉴于 Akka 框架已经可以访问通过该框架路由的所有消息,看来框架解决方案在这里很有意义。
这是我建议 Akka 框架做的事情: 1. 创建一个特征来指示一种消息类型(例如,“ExpensiveComputation”或类似的东西),这些消息将受到以下缓存方法的影响。 2. 智能地(散列等)识别由(相同或不同)参与者在用户可配置的时间窗口内接收到的相同消息。其他选项:选择用于此目的的最大缓冲区大小的内存,受(例如 LRU)替换等的影响。Akka 也可以选择仅缓存处理成本高的消息的结果;如果需要,可以重新处理那些花费很少时间处理的消息;无需浪费宝贵的缓冲区空间来缓存它们及其结果。 3. 当识别出相同的消息(在那个时间窗口内接收,可能是“同时”)时,避免不必要的重复计算。框架会自动执行此操作,并且本质上,重复的消息永远不会被新的参与者接收到进行处理;它们会默默地消失,并且处理一次的结果(无论该计算在过去已经完成,还是当时正在进行)将被发送给所有适当的接收者(如果已经可用,则立即发送,如果没有,则在完成计算后发送)。请注意,即使“回复”字段不同,消息也应被视为相同,只要它们表示的语义/计算在其他所有方面都相同。另请注意,计算应该是纯函数式的,即没有副作用,因为建议的缓存优化工作并且根本不改变程序语义。
如果我的建议与 Akka 的做事方式不兼容,和/或如果您发现这是一个非常糟糕的主意的一些强有力的理由,请告诉我。
谢谢, 真棒,斯卡拉
【问题讨论】: