【问题标题】:Service with background jobs, how to ensure jobs only run periodically ONCE per cluster具有后台作业的服务,如何确保作业仅在每个集群中定期运行一次
【发布时间】:2013-09-04 13:22:18
【问题描述】:

我有一个基于游戏框架的服务,它是无状态的,旨在部署在多台机器上以实现水平扩展。

此服务正在处理 HTTP JSON 请求和响应,并再次使用 CouchDB 作为其数据存储以实现最大的可扩展性。

我们有少量后台作业需要在整个集群中每 X 秒运行一次。作业不要在每台机器上同时执行,这一点至关重要。

要执行我们使用 Actors 和 Akka Scheduler 的作业(因为我们使用的是 Scala):

Akka.system().scheduler.schedule(
    Duration.create(0, TimeUnit.MILLISECONDS),
        Duration.create(10, TimeUnit.SECONDS),
        Akka.system().actorOf(LoggingJob.props),
        "tick")

(等)

object LoggingJob {
    def props = Props[LoggingJob]
}

class LoggingJob extends UntypedActor {
    override def onReceive(message: Any) {
        Logger.info("Job executed! " + message.toString())
    }
}

有吗:

  • 我错过的 Akka/Actors/Play 中的任何内置技巧对我有用吗?
  • 或者我可以在 Couchbase 之上放置一个公认的算法(分布式互斥锁?不完全是?)来做到这一点?

我不想让任何实例“特别”,因为它需要非常易于部署和管理。

【问题讨论】:

  • 我和你有同样的问题。我有一个播放应用程序,它有一个 akka 调度程序,它每 12 小时运行一次并执行某些数据库操作。但我希望它在集群中运行一次。否则,如果我有 2 个节点集群,那么它将运行 4 次,我希望它每天只运行两次。我们怎样才能做到这一点?

标签: scala playframework playframework-2.0 couchdb jobs


【解决方案1】:

查看 Akka 的 Cluster Singleton Pattern

对于某些用例,它很方便,有时也是强制性的 确保你有一个特定类型的演员在运行 集群中的某处。

一些例子:

  • 对某些集群范围内的一致决策或跨集群系统的行动协调的单一责任点
  • 外部系统的单一入口点
  • 单主,多工
  • 集中命名服务或路由逻辑

使用单例不应该是第一个设计选择。它有 几个缺点,例如单点瓶颈。单点 失败也是一个相关问题,但在某些情况下,此功能 通过确保另一个单例实例将处理这个问题 最终开始。

【讨论】:

  • 看起来不错,我唯一的保留是,当我们有一个很好的数据存储用于同步时,它会使用 gossip 协议来获得最终的一致性!我已经扫描了文档,但找不到任何关于将 gossip 协议用于其他目的的信息 - 你知道这是否值得花时间?
  • 我怀疑这是否可行。 gossip 协议是 Akka Cluster 的核心部分。
  • 我和你有同样的问题。我有一个播放应用程序,它有一个运行并执行某些数据库操作的 akka 调度程序。但我希望它在集群中运行一次。我们怎样才能做到这一点?
猜你喜欢
  • 2019-01-02
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 2018-07-02
  • 1970-01-01
  • 2018-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多