提示
提示是在写入操作期间应用的一种数据修复技术。当副本节点由于故障或更常见的例行维护而无法接受变异时,尝试写入这些副本的协调器会在其本地文件系统上存储临时提示,以便稍后应用于不可用的副本。提示是帮助缩短数据不一致持续时间的重要方法。协调器在不可用的副本节点返回环后会快速重播提示。但是,提示是尽力而为的,不能像 反熵修复 一样保证最终一致性。
提示之所以有用,是因为 Apache Cassandra 如何将数据复制以提供容错性、高可用性和持久性。Cassandra 将数据分区到集群中,使用一致性哈希,然后将键复制到哈希环上的多个节点。为了保证可用性,键的所有副本都可以接受变异而无需达成共识,但这意味着一些副本可能会接受变异,而另一些副本则不会。当这种情况发生时,就会引入不一致性。
除了读取修复和完整/增量反熵修复之外,提示是 Cassandra 实现最终一致性保证的三个方法之一,即所有更新最终都会被所有副本接收。提示与读取修复一样,是尽力而为的,不是执行完整修复的替代方法,但它们确实有助于在实践中缩短副本之间不一致的持续时间。
提示传递
提示传递是 Cassandra 将提示应用于不可用节点的过程。
例如,假设要对具有 复制因子为 3 的键空间进行 一致性级别为 LOCAL_QUORUM 的变异。通常,客户端会将变异发送到单个协调器,协调器会将变异发送到所有三个副本,当三个副本中的两个确认变异时,协调器会成功地响应客户端。但是,如果副本节点不可用,协调器会在本地文件系统上存储一个提示,以便稍后应用。新的提示将保留最多 max_hint_windowin_ms 的停机时间(默认为 3 小时)。如果不可用的副本在窗口过期之前返回到集群,协调器会将任何待处理的提示变异应用于副本,以确保最终一致性得到维护。
-
(
t0):客户端发送写入,协调器将其发送到三个副本。不幸的是,replica_2正在重启,无法接收变异。 -
(
t1):客户端从协调器接收法定人数确认。此时,客户端认为写入是持久的,并且对读取可见(实际上也是如此)。 -
(
t2):在写入超时(默认2 秒)后,协调器确定replica_2不可用,并将其提示存储到本地磁盘。 -
(
t3):稍后,当replica_2启动时,它会向所有节点(包括协调器)发送八卦消息。 -
(
t4):协调器重播提示,包括针对replica_2的遗漏变异。
如果节点没有及时返回,目标副本将永久性地不同步,直到读取修复或完整/增量反熵修复传播变异。
配置提示
提示默认情况下是启用的,因为它们对于数据一致性至关重要。cassandra.yaml 配置文件提供了几个用于配置提示的设置。
表 1. 提示设置
| 设置 | 描述 | 默认值 |
|---|---|---|
|
启用/禁用提示传递 |
|
|
不执行提示传递的数据中心的列表,即使启用了传递。示例
|
|
|
定义节点在故障后应生成提示的最长时间。 |
|
|
每个传递线程每秒的最大节流值(以 KiB 为单位)。这将根据集群中的节点数量成比例地减少。(如果集群中有两个节点,每个传递线程将使用最大速率;如果有 3 个节点,每个节点将节流到最大速率的一半,因为预计两个节点会同时传递提示。) |
|
|
用于传递提示的线程数;如果您有多数据中心部署,请考虑增加此数字,因为跨数据中心的传递往往比较慢 |
|
|
Cassandra 存储提示的目录。 |
|
|
提示从内部缓冲区刷新到磁盘的频率。不会触发 fsync。 |
|
`max_hints_file_size |
单个提示文件的最大大小(以兆字节为单位)。 |
|
|
要应用于提示文件的压缩。如果省略,提示文件将以未压缩的方式写入。支持 LZ4、Snappy 和 Deflate 压缩器。 |
|
使用 nodetool 在运行时配置提示
nodetool 提供了几个用于配置提示或获取提示相关信息的命令。nodetool 命令会覆盖运行该命令的节点的 cassandra.yaml 中的任何相应设置。
表 2. 用于提示的 Nodetool 命令
| 命令 | 描述 |
|---|---|
|
禁用存储和传递提示 |
|
禁用将提示存储和传递到数据中心 |
|
重新启用当前节点上未来的提示存储和传递 |
|
启用先前禁用的数据中心的提示 |
|
打印最大提示窗口(毫秒)。Cassandra 4.0 中的新功能。 |
|
打印当前的提示切换窗口 |
|
暂停提示传递过程 |
|
恢复提示传递过程 |
|
设置提示切换节流,单位为每秒千字节,每个传递线程 |
|
设置指定的最大提示窗口(毫秒) |
|
在当前节点上存储未来提示的状态 |
|
截断本地节点上的所有提示,或截断指定端点的提示。 |
在运行时加快提示播放速度
默认的 1024 kbps 切换节流对于大多数现代网络来说是保守的,在简单的节点重启中,您可能会积累许多千兆字节的提示,这些提示可能需要几个小时才能播放完毕。例如,如果您每个节点的摄取数据量为 100 Mbps,则单个 10 分钟的重启将创建 10 分钟 * (100 兆比特 / 秒) ~= 7 GiB 的数据,以 (1024 KiB / 秒) 的速度播放需要 7.5 GiB / (1024 KiB / 秒) = 2.03 小时。确切的计算取决于负载均衡策略(循环轮询优于令牌感知)、每个节点的令牌数量(更多令牌优于更少令牌),以及集群的写入速率,但无论如何,您可能希望在运行时增加此节流。
如果您遇到这种情况,可以考虑通过 nodetool sethintedhandoffthrottlekb 命令动态提高 hinted_handoff_throttle。
允许节点在运行时停机更长时间
有时,节点可能停机时间超过正常的 max_hint_window(默认值为 3 小时),但硬件和数据本身仍然可以访问。在这种情况下,您可以考虑通过 Cassandra 4.0 中添加的 nodetool setmaxhintwindow 命令动态提高 max_hint_window (CASSANDRA-11720)。这将指示 Cassandra 继续为停机的端点保留提示更长的时间。
此命令应应用于集群中可能保留提示的所有节点。如果需要,可以通过在 cassandra.yaml 中设置 max_hint_window 设置,然后进行滚动重启,永久应用此设置。
监控提示传递
Cassandra 4.0 添加了直方图,可用于了解传递提示所需的时间,这对于运营商更好地识别问题非常有用 (CASSANDRA-13234)。
还有一些指标可用于跟踪 提示切换 <handoff-metrics> 和 提示服务 <hintsservice-metrics> 指标。
