在introduction course of Cassandra DataStax中,他们说Cassandra集群节点的所有时钟都必须同步,以防止READ查询“旧”数据。
如果一个或多个节点出现故障,他们无法获得更新,但只要他们再次备份 - 他们就会更新并且没有问题......
那么,为什么Cassandra集群需要在节点之间同步时钟?
答案 0 :(得分:14)
一般来说,保持服务器时钟同步总是一个好主意,但节点之间需要时钟同步的主要原因是因为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,您现在必须担心保持客户端时钟同步。