我已经阅读了很多关于Cassandra的文章和很多关于Cassandra的问题/答案,但我仍然无法弄清楚Cassandra如何确定哪个节点何时会出现?读数据。
首先,关于假想集群的一些假设:
根据我读过的各种Datastax文章和其他博客文章,我对写作工作的理解如下:
数据被写入commit_log并可记忆,然后传播4次(RF = 5)。
然后选择环中的4个下一个节点,并将数据保留在其中。
到目前为止,非常好。
现在的问题是,当客户端向集群发送读取请求(例如CL = 3)时,Cassandra如何知道需要联系哪些节点(10个中的10个是最坏的情况)数据?当然,它并没有进入所有10个节点,因为效率低下。
我是否正确假设Cassandra将再次执行主要密钥(请求的主要密钥)的MD5哈希并根据该选择选择节点然后走环?
此外,网络拓扑案例如何运作?如果我有多个数据中心,Cassandra如何知道每个DC / Rack中的哪些节点包含数据?据我所知,只有第一个节点是显而易见的(因为主键的散列明确地导致了该节点)。
很抱歉,如果问题不是很明确,如果您需要有关我的问题的详细信息,请添加评论。
非常感谢,
答案 0 :(得分:36)
客户端将数据发送到随机节点
看起来似乎是这样,但实际上有一种非随机的方式,你的驱动程序选择一个节点来与之交谈。该节点被称为“协调器节点”,并且通常基于具有最小(最接近)的“网络距离”来选择。客户端请求实际上可以发送到任何节点,并且最初它们将被发送到您的驱动程序知道的节点。但是一旦它连接并理解了集群的拓扑结构,它就可能变成一个“更接近”的协调器。
群集中的节点使用Gossip Protocol相互交换拓扑信息。 gossiper每秒运行一次,并确保所有节点保持最新状态,其中包含您配置的Snitch数据。 snitch会跟踪每个节点所属的数据中心和机架。
通过这种方式,协调器节点还具有关于哪个节点负责每个令牌范围的数据。您可以通过从命令行运行nodetool ring
来查看此信息。虽然如果你使用的是vnodes,那将很难确定,因为所有256个(默认)虚拟节点上的数据都会在屏幕上快速闪烁。
所以,让我说我有一张桌子,我用它来跟踪船员的名字,我们假设我想查找Malcolm Reynolds。运行此查询:
SELECT token(firstname),firstname, id, lastname
FROM usersbyfirstname WHERE firstname='Mal';
...返回此行:
token(firstname) | firstname | id | lastname
----------------------+-----------+----+-----------
4016264465811926804 | Mal | 2 | Reynolds
通过运行nodetool ring
,我可以看到哪个节点负责此令牌:
192.168.1.22 rack1 Up Normal 348.31 KB 3976595151390728557
192.168.1.22 rack1 Up Normal 348.31 KB 4142666302960897745
或者更简单,我可以使用nodetool getendpoints
查看此数据:
$ nodetool getendpoints stackoverflow usersbyfirstname Mal
Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar
192.168.1.22
有关详细信息,请查看上面链接的部分内容,或尝试运行nodetool gossipinfo
。
答案 1 :(得分:17)
Cassandra使用一致的散列将每个分区键映射到标记值。每个节点都拥有令牌值范围作为其主范围,因此每个可能的哈希值都将映射到一个节点。然后以系统方式(例如环中的下一个节点)保存额外的副本,并将其作为 secondary 范围存储在节点中。
群集中的每个节点都知道整个群集的拓扑结构,例如哪些节点位于哪个数据中心,哪些节点位于环中,以及每个节点拥有哪些令牌范围。节点使用八卦协议获取并维护此信息。
当读取请求进入时,联系的节点成为读取的协调者。它将计算哪些节点具有所请求分区的副本,然后选择所需数量的节点以满足一致性级别。然后它会向这些节点发送请求并等待它们的响应,并在将结果发送回客户端之前根据列时间戳合并结果。
答案 2 :(得分:11)
Cassandra将根据分区键找到任何数据,分区键由分区器映射到标记值。标记是有限标记环值范围的一部分,其中环的每个部分由集群中的节点拥有。拥有某个令牌范围的节点被认为是该令牌的主要节点。将通过数据复制策略选择副本。基本上,这是通过在主令牌中从顺时针环顺时针方向开始,并根据所需副本的数量停止。
要认识到的重要一点是,集群中的每个节点都能够基于上述逻辑识别负责某个密钥的节点。每当将值写入集群时,接受请求的节点(协调器节点)将立即知道需要执行写入的节点。
如果是多个数据中心,所有密钥将跨所有DC映射到分区程序确定的完全相同的令牌。 Cassandra将尝试写入每个DC和每个DC的复制品。