【问题标题】:What server-side architectures could provide high availability and avoid race conditions?哪些服务器端架构可以提供高可用性并避免竞争条件?
【发布时间】:2015-07-02 18:56:46
【问题描述】:

我有以下(有缺陷的)分布式架构,它有竞争条件。我知道你们中的一些人可能对这个经典的“分布式状态传播问题”有解决方案——我很想听听他们的意见。如果你能容忍我,这是架构:

假设您有两个 golang 应用服务器,S1 和 S2。

还有两个 Cassandra 数据库节点,DB1 和 DB2。

S1 和 S2 分别连接到 DB1 和 DB2。

一个用户几乎同时从两个浏览器做两件事:

  1. 他打开客户端浏览器 C1,该浏览器将通过 websockets 连接到 S1 并请求从 DB1 或 DB2 获取状态。消息 M1 包含状态并从 S1 发送到 C1。
  2. 他打开客户端浏览器 C2,它将连接到 S2 以切换某些状态。 S2 将在 DB1 或 DB2 中更新该状态。然后 DB1 和 DB2 将相互同步。 S2 还需要告诉 C1 新状态,并使用 NSQ(或您喜欢的消息队列)将此状态更新消息发送给 S1,然后 S1 将带有状态更改的消息 M2 发送给 C1。

现在,在 (1) 和 (2) 之间存在毛茸茸的竞争条件。在 C1 上,什么先到达,M1 还是 M2? M1 可能包含或不包含 M2 中包含的状态更新,具体取决于 Cassandra 传播相对于 C1 请求的时间。

我意识到幂等消息或 CRDT 可以在某些用例中解决这个问题,但不是全部——尤其是对于非单调状态变化,如布尔切换状态。

我知道 OST(操作状态转移)也可以解决这个问题,但我不知道有什么好的现成解决方案。我之前已经建立了一个 OST 系统,它是一个主要的 PITA。

当然,可以拥有一种更一致的数据库,这使得这更易于处理,但我需要具有分区容错性的高可用性,这意味着要处理最终的一致性。

拥有数据库挂钩/回调可能会解决此问题,应用服务器可以在其中侦听特定状态的更改,并在状态传播到达该数据库节点时收到通知。我知道这些钩子存在于 Rethinkdb 等一些一致的数据库中,但(据我所知)它们不存在于 Cassandra 或任何其他高可用性 (HA)、分区容错 (PT) 数据库中。

我发现自己渴望应用程序级的状态抽象:跨平台;与 HA/PT 分布式持久存储集成;为我处理状态传播;并且可以在状态更改时轻松触发行为。我不知道这样的事情。

您知道哪些工具或架构可以满足这些限制:

  • 没有竞争条件
  • 高可用性、分区容错(最终一致)
  • 处理非单调状态变化

【问题讨论】:

    标签: state distributed-computing race-condition distributed-system eventual-consistency


    【解决方案1】:

    我认为 Cassandra 具有非常特殊的功能,但即使您使用单个节点,也无法以您需要的方式管理事务。 我不知道你为什么使用 Cassandra,也许你有理由被缝合,但为了你的需要,我会在 HA 配置中使用 SQL db 集群:Oracle 或 SQL Server 已经解决了这些问题。当然它们可能很贵

    【讨论】:

      【解决方案2】:

      尝试使用您的 Cassandra 服务器之一,例如DB1 作为锁服务器。这将保证您所有操作的原子性,因此在您的情况下,操作不会相互干扰。

      【讨论】:

      • 这是一个有趣的想法,但这不会造成单点故障吗?
      • 并非如此。如果锁定服务器已关闭,那么您只是在做您当前正在做的事情。我的意思是,如果您很幸运并且锁定服务器已启动,那么您将具有一致性。如果你不走运并且它倒下了,那么你就不会。但是,始终保持一致性不是更好吗?
      • “不可靠的锁定”——这很有趣。尽可能锁定/解锁(大部分时间),但不要让它停止操作。
      • 没错。但是,如果您避免分布式锁定和分布式事务,您将能够更顺利地完成所有事情。尝试在一台服务器上拥有您在一次事务中需要的所有数据。你的情况有可能吗?
      猜你喜欢
      • 1970-01-01
      • 2015-01-30
      • 2010-09-25
      • 2015-09-10
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      • 2019-06-12
      相关资源
      最近更新 更多