【问题标题】:How cassandra handles new node ( how tokens are redistributed)?cassandra 如何处理新节点(令牌如何重新分配)?
【发布时间】:2021-05-20 23:11:54
【问题描述】:

我最近开始为一个新项目探索 Cassandra。这是我目前对 Cassandra 的理解(基于在线提供的众多博客)

  1. Cassandra (C*) 是 AP(CAP 定理),即它具有高可用性和分区容错性
  2. C* 在逻辑上是环形拓扑。不是在真正的网络意义上(因为所有节点都可以相互通信),而是在数据复制意义上(数据被复制到相邻节点)
  3. C* 使用 Murmur3 分区算法将分区键映射到整数范围(大致 -2^63 到 2^63)
  4. 每个节点负责几个范围(启用 Vnode),即 节点1:[-2^63-2^61],[2^312^33 ] .... 节点2:[-2^61 - 12^59],[2^33 + 12^35]....

现在我的问题是,假设我创建了一个有 3 个节点且 RF = 2 的集群,那么

  1. 在这种情况下,整个令牌范围(我相信我在这里使用了正确的术语)-2^63 到 2^63 将均匀分布在这 3 个节点中?
  2. 如果我在这个正在运行的集群中添加另一个节点会发生什么?我的假设是,C* 将重新平衡环,因为它使用一致的哈希,因此范围 -2^63 到 2^63 将被重新分配,相应的数据将被复制到新节点。 (从现有节点复制的数据在修复之前不会被删除?)
  3. 当节点出现故障时会发生什么? C* 是否通过重新分配令牌和移动数据来重新平衡环?
  4. 标记是 Murmur3hash(分区键)的一个花哨的词吗?分区范围到底是什么意思?是否像分区范围1 = -2^63-2^61,分区范围2 = -2^61 + 1 -2^59 以此类推。
  5. 八卦期间实际分享了哪些信息?

对不起,如果这些问题看起来很基本,但我花了很长时间却找不到明确的答案。

【问题讨论】:

  • 我在 SO 上找到了一些有用的 Q/A,但这些并不能明确回答我的问题。就像这里 [0] 谈论重新平衡,但我仍然不明白 C* 是否重新分配范围? [0]:stackoverflow.com/questions/48735530/…
  • 每个问题只问一个问题。

标签: cassandra


【解决方案1】:

我会尽量用简单的方式解释

Cassandra 提供了一种简单的配置方式,所有配置都在 cassandra.yaml 中完成。您也可以通过THIS 了解集群中的分区情况。

让我们从基础开始,我们现在只使用一个节点,而不是使用三个节点。 使用 cassandra 的默认配置,我们在 cassandra.yaml 文件中得到以下值

num_tokens: 1
initial_token: 0

这意味着只有一个节点,所有分区都将驻留在这个节点上。 现在,虚拟节点的概念,简单来说就是 cassandra 将令牌划分为多个范围,即使没有物理节点。现在,如何在配置文件 cassandra.yaml 中启用虚拟节点功能。答案是 num_token 值。

num_tokens: 128
#initial_token: 0

此配置生成 128 个令牌范围,例如 0-10、11-20、20-30 等。保留 initial_token 的值注释,这意味着我们希望 cassandra 决定初始令牌的值(少了一件需要担心的事情)。

现在让我们在集群中添加另一个节点。下面是新节点的简单配置。为简单起见,将第一个节点 IP 视为 127.0.0.1,将第二个节点 IP 视为 127.0.0.2。

num_tokens: 128
#initial_token: 0
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
  parameters:
      - seeds: "127.0.0.1, 127.0.0.2"

我们刚刚在集群中添加了一个新节点,node1 将作为种子节点。 num_token 值为 128,即 128 个令牌范围。 initial_token 的值被注释了,这意味着 cassandra 将决定初始令牌和范围。新节点加入集群后,数据传输将立即开始。

对于第三个节点,配置如下-

num_tokens: 128
#initial_token: 0
seed_provider:
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
  parameters:
      - seeds: "127.0.0.1, 127.0.0.2, 127.0.0.3"

所以第三个节点将共享 node1 的几个令牌范围和 node2 的几个令牌范围。

我希望,到目前为止,我们已经得到了问题 1 和问题 2 的答案。让我们转到下一个问题。

当一个节点出现故障时,提示切换帮助 Cassandra 保持一致性。剩下的 2 个节点中的任何一个都保留了应该写入已关闭节点上的数据的提示。一旦节点上线,这些提示将被重播,数据将被写入目标节点。无需进行重新分区或重新平衡这类花哨的事情。提示存储在可以在 cassandra.yaml 文件中配置的目录中。默认情况下将存储 3 小时的提示,这意味着缺陷节点应在 3 小时内出现。这个值也可以在 cassandra.yaml 文件中配置。

hinted_handoff_enabled: true
max_hint_window_in_ms: 10800000 # 3 hours
hints_directory: /home/ubuntu/node1/data/hints

Murmur3Partitioner 使用分区键列计算哈希,让我们放心吧。还有其他从业者,例如 RandomPartitioner 和 ByteOrderedPartitioner。

以下是 gossip info 的示例输出 - 您可以浏览以下协议数据中的每个字段

        ubuntu@ds201-node1:~$ ./node1/bin/nodetool gossipinfo
    /127.0.0.1
      generation:1621506507  -- the tiem at this node is boot strapped.
      heartbeat:2323
      STATUS:28:NORMAL,-1316314773810616606 -----status of the node , NORMAL,LEFT,LEAVING,REMOVED,REMOVING.....
      LOAD:2295:110299.0                    -- Disk space usage
      SCHEMA:64:c5c6bdbd-5916-347a-ab5b-21813ab9d135  -- Changes if schema changes
      DC:37:Cassandra                       --- data center of the NODE
      RACK:18:rack1                         --- Rack of the within the datacenter 
      RELEASE_VERSION:4:4.0.0.2284
      NATIVE_TRANSPORT_ADDRESS:3:127.0.0.1
      X_11_PADDING:2307:{"dse_version":"6.0.0","workloads":"Cassandra","workload":"Cassandra","active":"true","server_id":"08-00-27-32-1E-DD","graph":false,"health":0.3}
      NET_VERSION:1:256
      HOST_ID:2:ebd0627a-2491-40d8-ba37-e82a31a95688
      NATIVE_TRANSPORT_READY:66:true
      NATIVE_TRANSPORT_PORT:6:9041
      NATIVE_TRANSPORT_PORT_SSL:7:9041
      STORAGE_PORT:8:7000
      STORAGE_PORT_SSL:9:7001
      JMX_PORT:10:7199
      TOKENS:27:<hidden>

Gossip 是跨集群传播数据的广播协议。没有人是 cassandra 集群的主人,对等点在彼此之间传播数据,这有助于他们维护最新信息。节点使用 gossip 协议随机地相互通信(这种随机性有一些标准)。 Gossip 仅传播节点元数据,而不传播客户端数据。

希望这能消除一些疑虑。

【讨论】:

    【解决方案2】:

    提供额外的深度:

    令牌范围分配确实有一个随机分量,所以它并不完全是“偶数”。但是,如果您使用 allocate_tokens_for_keyspace,新的令牌分配算法会接管,并根据指定键空间的复制因子 (RF) 优化未来的范围分配。

    这是来自nodetool ring 的六行缩写输出部分,来自使用num_tokens=16 构建的3 节点集群。请注意,“范围”实际上是定义的起始令牌(哈希)一直到下一个起始令牌减一:

    10.0.0.1  -6595849996054463311
    10.0.0.2  -5923426258674511018
    10.0.0.2  -5194860430157391004
    10.0.0.2  -4076256821118426122
    10.0.0.2  -3750110785943336998
    10.0.0.3  -3045824679140675270
    

    观察当我添加第 4 个节点时会发生什么:

    10.0.0.1  -6595849996054463311
    10.0.0.2  -5923426258674511018
    10.0.0.4  -5711305561631524277
    10.0.0.2  -5194860430157391004
    10.0.0.4  -4831174780910733952
    10.0.0.2  -4076256821118426122
    10.0.0.2  -3750110785943336998
    10.0.0.4  -3659290179273062522
    10.0.0.3  -3045824679140675270
    

    请注意,三个原始节点中每个节点的起始令牌范围保持不变。但在这种特殊情况下,10.0.0.2 上的范围被平分,后半部分分配给10.0.0.4

    请注意,一旦流式传输完成,10.0.0.4 上这些范围内的数据仍会在 10.0.0.2 上。这是设计使然,如果新节点的引导过程失败。一旦事情稳定下来,您就可以通过在原来的三个节点上运行 nodetool cleanup 来删除这些数据。

    当一个节点宕机时会发生什么? C* 是否通过重新分配令牌和移动数据来重新平衡环?

    nodetool removenode 运行时会发生这种情况。但是对于一个简单宕机的节点,“提示”会存储在剩余节点上,以便在宕机节点回来后重播。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-14
      • 1970-01-01
      • 2019-12-21
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多