首页 文章

为什么Cassandra集群需要在节点之间同步时钟?

提问于
浏览
6

introduction course of Cassandra DataStax中,他们说必须同步Cassandra集群节点的所有时钟,以防止READ查询到'old'数据 .

如果一个或多个节点关闭,他们无法获得更新,但只要他们再次备份 - 他们会更新并且没有问题......

那么,为什么Cassandra集群需要在节点之间同步时钟?

1 回答

  • 12

    一般来说,保持服务器时钟同步总是一个好主意,但节点之间需要时钟同步的主要原因是因为Cassandra使用一个名为'Last Write Wins'的概念来解决冲突并确定哪个突变代表最正确的最新数据状态 . 这在Why cassandra doesn't need vector clocks中有解释 .

    每当您在cassandra中'变异'(写入或删除)列时,处理您的请求的协调员都会分配一个时间戳 . 该时间戳使用单元格中的列值写入 .

    当读取请求发生时,cassandra会根据您的查询条件构建查找突变的结果,当它看到表示同一列的多个单元格时,它将选择具有最新时间戳的那个(读取路径比此更复杂但是这一切都是你需要知道在这种情况下) .

    当节点的时钟不同步时,事情开始变得有问题 . 正如我所提到的,处理请求的协调器节点会分配时间戳 . 如果对同一列执行多个突变并分配了不同的协调器,则可以创建一些情况,其中返回过去发生的写入而不是最近的写入 .

    以下是描述以下内容的基本方案:

    假设我们有一个带有节点A和B的2节点集群 . 让我们假设一个初始状态,其中A在时间 t10 ,B在时间 t5 .

    • 用户执行 DELETE C FROM tbl WHERE key=5 . 节点A协调请求,并为其分配时间戳 t10 .

    • 第二次传递,用户执行 UPDATE tbl SET C='data' where key=5 . 节点B协调请求并为其分配时间戳 t6 .

    • 用户执行查询 SELECT C from tbl where key=5 . 由于步骤1中的 DELETE 具有更新的时间戳( t10 > t6 ),因此不会返回任何结果 .

    请注意,较新版本的数据存储驱动程序将开始默认使用客户端时间戳来生成客户端应用程序并为请求分配时间戳,而不是依赖于C *节点来分配它们 . 从3.0开始的datastax java-driver现在默认为客户端时间戳(在'Client-side generation'中有关于那里的更多信息) . 如果所有请求都来自同一个客户端,这是非常好的,但是如果您有多个应用程序写入cassandra,您现在必须担心保持客户端时钟同步 .

相关问题