提示
提示是在写入操作期间应用的一种数据修复技术。当副本节点由于故障或更常见的例行维护而无法接受变异时,尝试写入这些副本的协调器会在其本地文件系统上存储临时提示,以便稍后应用于不可用的副本。提示是帮助缩短数据不一致持续时间的重要方法。协调器在不可用的副本节点返回环后会快速重播提示。但是,提示是尽力而为的,不能像 反熵修复
一样保证最终一致性。
提示之所以有用,是因为 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>
指标。