管理副本
本主题介绍如何在 StarRocks 集群中管理数据副本。
概述
StarRocks 采用多副本策略来保证数据的高可用性。创建表时,您必须使用表属性 replication_num
(默认值:3
)指定表的副本计数。当加载事务启动时,数据会同时加载到指定数量的副本中。只有在数据存储在大多数副本中之后,事务才会返回成功。有关详细信息,请参见 写入仲裁。尽管如此,StarRocks 允许您为表指定较低的写入仲裁,以获得更好的加载性能。
StarRocks 将多个副本存储在不同的 BE 节点上。例如,如果要为一个表存储三个副本,则必须在 StarRocks 集群中部署至少三个 BE 节点。如果任何副本失败,StarRocks 会从另一个 BE 节点克隆一个健康的副本(部分或全部)来修复失败的副本。通过使用多版本并发控制 (MVCC) 技术,StarRocks 通过复制这些多版本数据的物理副本来加速副本的修复。
将数据加载到多副本表中
加载事务的流程如下:
-
客户端向 FE 提交加载请求。
-
FE 选择一个 BE 节点作为此加载事务的协调器 BE 节点,并为此事务生成一个执行计划。
-
协调器 BE 节点从客户端读取要加载的数据。
-
协调器 BE 节点将数据分派到所有 tablet 副本。
注意
Tablet 是表的一个逻辑切片。一个表有多个 tablet,每个 tablet 都有 replication_num 个副本。表中 tablet 的数量由表的
bucket_size
属性决定。 -
数据加载并存储到所有 tablet 后,FE 使加载的数据可见。
-
FE 向客户端返回加载成功。
即使在极端情况下,这样的流程也能保证服务的可用性。
写入仲裁
将数据加载到多副本表中可能非常耗时。如果您想提高加载性能,并且可以容忍相对较低的数据可用性,您可以为表设置较低的写入仲裁。写入仲裁是指在写入操作被认为是成功之前需要确认写入的最小副本数。您可以通过在 CREATE TABLE 时添加属性 write_quorum
来指定写入仲裁,或者使用 ALTER TABLE 将此属性添加到现有表中。此属性从 v2.5 开始支持。
write_quorum
支持以下值:
MAJORITY
:默认值。当大多数数据副本返回加载成功时,StarRocks 返回加载任务成功。否则,StarRocks 返回加载任务失败。ONE
:当一个数据副本返回加载成功时,StarRocks 返回加载任务成功。否则,StarRocks 返回加载任务失败。ALL
:当所有数据副本返回加载成功时,StarRocks 返回加载任务成功。否则,StarRocks 返回加载任务失败。
自动副本修复
副本可能会因为某些 BE 节点崩溃或某些加载任务失败而失败。StarRocks 会自动修复这些失败的副本。
每隔 tablet_sched_checker_interval_seconds
(默认为 20 秒),FE 中的 Tablet Checker 会扫描 StarRocks 集群中所有表的所有 tablet 副本,并通过检查当前可见数据的版本号和 BE 节点的健康状态来判断副本是否健康。如果一个副本的可见版本落后于其他副本,StarRocks 将执行增量克隆来修复失败的副本。如果一个 BE 节点无法接收心跳或从集群中删除,或者副本滞后太多无法通过增量克隆修复,StarRocks 将执行完全克隆来修复丢失的副本。
在检测到需要修复的 tablet 副本后,FE 会生成一个 tablet 调度任务,并将该任务添加到调度任务队列中。FE 中的 Tablet Scheduler 从队列中接收调度任务,根据需要克隆的类型为每个失败的副本创建克隆任务,并将任务分配给执行器 BE 节点。
克隆任务本质上是从源 BE 节点(具有健康的副本)复制数据,并将数据加载到目标 BE 节点(具有失败的副本)。对于具有滞后数据版本的副本,FE 会将增量克隆任务分配给存储失败副本的 BE 执行器,并通知执行器 BE 节点它可以从哪个对等 BE 节点找到健康的副本并克隆新数据。如果副本丢失,FE 会选择一个幸存的 BE 节点作为执行器 BE 节点,在该 BE 节点中创建一个空副本,并将完全克隆任务分配给 BE 节点。
对于每个克隆任务,无论其类型如何,执行器 BE 节点都会从健康的副本中复制物理数据文件,然后相应地更新其元数据。克隆任务完成后,执行器 BE 节点向 FE 中的 Tablet Scheduler 报告任务成功。在删除冗余 tablet 副本后,FE 会更新其元数据,标志着副本修复完成。
在 tablet 修复期间,StarRocks 仍然可以执行查询。只要健康副本的数量满足 write_quorum
,StarRocks 就可以将数据加载到表中。
手动修复副本
手动副本修复包括两个步骤:
- 检查副本状态。
- 设置副本优先级。
检查副本状态
按照以下步骤检查 tablet 的副本状态,以识别不健康的(失败的)tablet。
-
检查集群中所有 tablet 的状态。
SHOW PROC '/statistic';
示例
mysql> SHOW PROC '/statistic';
+----------+-----------------------------+----------+--------------+----------+-----------+------------+--------------------+-----------------------+
| DbId | DbName | TableNum | PartitionNum | IndexNum | TabletNum | ReplicaNum | UnhealthyTabletNum | InconsistentTabletNum |
+----------+-----------------------------+----------+--------------+----------+-----------+------------+--------------------+-----------------------+
| 35153636 | default_cluster:DF_Newrisk | 3 | 3 | 3 | 96 | 288 | 0 | 0 |
| 48297972 | default_cluster:PaperData | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 5909381 | default_cluster:UM_TEST | 7 | 7 | 10 | 320 | 960 | 1 | 0 |
| Total | 240 | 10 | 10 | 13 | 416 | 1248 | 1 | 0 |
+----------+-----------------------------+----------+--------------+----------+-----------+------------+--------------------+-----------------------+UnhealthyTabletNum
:表示对应数据库中不健康的 tablet 数量。InconsistentTabletNum
:表示副本不一致的 tablet 数量。
如果特定数据库中的
UnhealthyTabletNum
或InconsistentTabletNum
的值不为0
,您可以使用其DbId
检查数据库中不健康的 tablet。SHOW PROC '/statistic/<DbId>'
示例
mysql> SHOW PROC '/statistic/5909381';
+------------------+---------------------+
| UnhealthyTablets | InconsistentTablets |
+------------------+---------------------+
| [40467980] | [] |
+------------------+---------------------+不健康的 tablet 的 ID 在字段
UnhealthyTablets
中返回。 -
检查特定表或分区中的 tablet 状态。
您可以在 ADMIN SHOW REPLICA STATUS 中使用 WHERE 子句来过滤具有特定
STATUS
的 tablet。ADMIN SHOW REPLICA STATUS FROM <table_name>
[PARTITION (<partition_name_1>[, <partition_name_2>, ...])]
[WHERE STATUS = {'OK'|'DEAD'|'VERSION_ERROR'|'SCHEMA_ERROR'|'MISSING'}]示例
mysql> ADMIN SHOW REPLICA STATUS FROM tbl PARTITION (p1, p2) WHERE STATUS = "OK";
+----------+-----------+-----------+---------+-------------------+--------------------+------------------+------------+------------+-------+--------+--------+
| TabletId | ReplicaId | BackendId | Version | LastFailedVersion | LastSuccessVersion | CommittedVersion | SchemaHash | VersionNum | IsBad | State | Status |
+----------+-----------+-----------+---------+-------------------+--------------------+------------------+------------+------------+-------+--------+--------+
| 29502429 | 29502432 | 10006 | 2 | -1 | 2 | 1 | -1 | 2 | false | NORMAL | OK |
| 29502429 | 36885996 | 10002 | 2 | -1 | -1 | 1 | -1 | 2 | false | NORMAL | OK |
| 29502429 | 48100551 | 10007 | 2 | -1 | -1 | 1 | -1 | 2 | false | NORMAL | OK |
| 29502433 | 29502434 | 10001 | 2 | -1 | 2 | 1 | -1 | 2 | false | NORMAL | OK |
| 29502433 | 44900737 | 10004 | 2 | -1 | -1 | 1 | -1 | 2 | false | NORMAL | OK |
| 29502433 | 48369135 | 10006 | 2 | -1 | -1 | 1 | -1 | 2 | false | NORMAL | OK |
+----------+-----------+-----------+---------+-------------------+--------------------+------------------+------------+------------+-------+--------+--------+如果字段
IsBad
为true
,则表示此 tablet 已损坏。有关字段
Status
中提供的详细信息,请参见 ADMIN SHOW REPLICA STATUS。您可以使用 SHOW TABLET 进一步探索表中 tablet 的详细信息。
SHOW TABLET FROM <table_name>
示例
mysql> SHOW TABLET FROM tbl1;
+----------+-----------+-----------+------------+---------+-------------+-------------------+-----------------------+------------------+----------------------+---------------+----------+----------+--------+-------------------------+--------------+----------------------+--------------+----------------------+----------------------+----------------------+
| TabletId | ReplicaId | BackendId | SchemaHash | Version | VersionHash | LstSuccessVersion | LstSuccessVersionHash | LstFailedVersion | LstFailedVersionHash | LstFailedTime | DataSize | RowCount | State | LstConsistencyCheckTime | CheckVersion | CheckVersionHash | VersionCount | PathHash | MetaUrl | CompactionStatus |
+----------+-----------+-----------+------------+---------+-------------+-------------------+-----------------------+------------------+----------------------+---------------+----------+----------+--------+-------------------------+--------------+----------------------+--------------+----------------------+----------------------+----------------------+
| 29502429 | 29502432 | 10006 | 1421156361 | 2 | 0 | 2 | 0 | -1 | 0 | N/A | 784 | 0 | NORMAL | N/A | -1 | -1 | 2 | -5822326203532286804 | url | url |
| 29502429 | 36885996 | 10002 | 1421156361 | 2 | 0 | -1 | 0 | -1 | 0 | N/A | 784 | 0 | NORMAL | N/A | -1 | -1 | 2 | -1441285706148429853 | url | url |
| 29502429 | 48100551 | 10007 | 1421156361 | 2 | 0 | -1 | 0 | -1 | 0 | N/A | 784 | 0 | NORMAL | N/A | -1 | -1 | 2 | -4784691547051455525 | url | url |
+----------+-----------+-----------+------------+---------+-------------+-------------------+-----------------------+------------------+----------------------+---------------+----------+----------+--------+-------------------------+--------------+----------------------+--------------+----------------------+----------------------+----------------------+返回的结果显示 tablet 的大小、行数、版本和 URL。
SHOW TABLET 返回的字段
State
指示 tablet 的任务状态,包括CLONE
、SCHEMA_CHANGE
和ROLLUP
。您还可以使用 ADMIN SHOW REPLICA DISTRIBUTION 检查特定表或分区的副本分布,以查看这些副本是否均匀分布。
ADMIN SHOW REPLICA DISTRIBUTION FROM <table_name>
示例
mysql> ADMIN SHOW REPLICA DISTRIBUTION FROM tbl1;
+-----------+------------+-------+---------+
| BackendId | ReplicaNum | Graph | Percent |
+-----------+------------+-------+---------+
| 10000 | 7 | | 7.29 % |
| 10001 | 9 | | 9.38 % |
| 10002 | 7 | | 7.29 % |
| 10003 | 7 | | 7.29 % |
| 10004 | 9 | | 9.38 % |
| 10005 | 11 | > | 11.46 % |
| 10006 | 18 | > | 18.75 % |
| 10007 | 15 | > | 15.62 % |
| 10008 | 13 | > | 13.54 % |
+-----------+------------+-------+---------+返回的结果显示每个 BE 节点上的 tablet 副本数及其相应的百分比。
-
检查特定 tablet 的副本状态。
使用您在前面的过程中获得的不健康的 tablet 的
TabletId
,您可以检查它们的副本状态。SHOW TABLET <TabletId>
示例
mysql> SHOW TABLET 29502553;
+------------------------+-----------+---------------+-----------+----------+----------+-------------+----------+--------+---------------------------------------------------------------------------+
| DbName | TableName | PartitionName | IndexName | DbId | TableId | PartitionId | IndexId | IsSync | DetailCmd |
+------------------------+-----------+---------------+-----------+----------+----------+-------------+----------+--------+---------------------------------------------------------------------------+
| default_cluster:test | test | test | test | 29502391 | 29502428 | 29502427 | 29502428 | true | SHOW PROC '/dbs/29502391/29502428/partitions/29502427/29502428/29502553'; |
+------------------------+-----------+---------------+-----------+----------+----------+-------------+----------+--------+---------------------------------------------------------------------------+返回的结果显示有关 tablet 的数据库、表、分区和索引(Rollup)的详细信息。
您可以复制字段
DetailCmd
中的 SQL 语句,以进一步检查 tablet 的副本状态。示例
mysql> SHOW PROC '/dbs/29502391/29502428/partitions/29502427/29502428/29502553';
+-----------+-----------+---------+-------------+-------------------+-----------------------+------------------+----------------------+---------------+------------+----------+----------+--------+-------+--------------+----------------------+----------+------------------+
| ReplicaId | BackendId | Version | VersionHash | LstSuccessVersion | LstSuccessVersionHash | LstFailedVersion | LstFailedVersionHash | LstFailedTime | SchemaHash | DataSize | RowCount | State | IsBad | VersionCount | PathHash | MetaUrl | CompactionStatus |
+-----------+-----------+---------+-------------+-------------------+-----------------------+------------------+----------------------+---------------+------------+----------+----------+--------+-------+--------------+----------------------+----------+------------------+
| 43734060 | 10004 | 2 | 0 | -1 | 0 | -1 | 0 | N/A | -1 | 784 | 0 | NORMAL | false | 2 | -8566523878520798656 | url | url |
| 29502555 | 10002 | 2 | 0 | 2 | 0 | -1 | 0 | N/A | -1 | 784 | 0 | NORMAL | false | 2 | 1885826196444191611 | url | url |
| 39279319 | 10007 | 2 | 0 | -1 | 0 | -1 | 0 | N/A | -1 | 784 | 0 | NORMAL | false | 2 | 1656508631294397870 | url | url |
+-----------+-----------+---------+-------------+-------------------+-----------------------+------------------+----------------------+---------------+------------+----------+----------+--------+-------+--------------+----------------------+----------+------------------+返回的结果显示 tablet 的所有副本。
设置副本优先级
Tablet Scheduler 会自动为每种不同类型的克隆任务分配不同的优先级。
如果您希望尽早修复来自某个表或某些分区的 tablet,您可以使用 ADMIN REPAIR TABLE 手动为它们分配 VERY_HIGH
优先级。
ADMIN REPAIR TABLE <table_name>
[PARTITION (<partition_name_1>[, <partition_name_2>, ...])]
注意
- 执行此 SQL 语句只会提交一个提示,以修改要修复的 tablet 的优先级。它不能保证这些 tablet 可以成功修复。
- 在您执行此 SQL 语句后,Tablet Scheduler 仍可能为这些 tablet 分配不同的优先级。
- 当 Leader FE 节点更改或重新启动时,此 SQL 语句提交的提示将过期。
您可以使用 ADMIN CANCEL REPAIR TABLE 取消此操作。
ADMIN CANCEL REPAIR TABLE <table_name>
[PARTITION (<partition_name_1>[, <partition_name_2>, ...])]
副本平衡
StarRocks 会自动平衡 BE 节点上的 tablet。
要将 tablet 从高负载节点移动到低负载节点,StarRocks 首先在低负载节点中创建 tablet 的副本,然后删除高负载节点上的相应副本。如果在集群中使用不同类型的存储介质,StarRocks 会根据存储介质类型对所有 BE 节点进行分类。StarRocks 尽可能地在相同存储介质类型的 BE 节点之间移动 tablet。同一 tablet 的副本存储在不同的 BE 节点上。
BE 负载
StarRocks 使用 ClusterLoadStatistics
(CLS) 显示集群中每个 BE 节点的负载统计信息。Tablet Scheduler 根据 ClusterLoadStatistics
触发副本平衡。StarRocks 评估每个 BE 节点的磁盘利用率和副本数,并相应地计算 loadScore
。BE 节点的 loadScore
越高,节点的负载就越高。Tablet Scheduler 每分钟更新一次 ClusterLoadStatistics
。
capacityCoefficient
和 replicaNumCoefficient
分别是磁盘利用率和副本数的加权因子。capacityCoefficient
和 replicaNumCoefficient
的总和为 1。 capacityCoefficient
根据实际磁盘使用情况动态调整。当 BE 节点的总体磁盘利用率低于 50% 时,capacityCoefficient
值为 0.5。当磁盘利用率高于 75% 时,该值为 1。您可以通过 FE 配置项 capacity_used_percent_high_water
配置此限制。如果利用率在 50% 到 75% 之间,capacityCoefficient
会根据此公式平滑增加
capacityCoefficient= 2 * Disk utilization - 0.5
capacityCoefficient
确保当磁盘使用率非常高时,此 BE 节点的 loadScore
会更高,从而迫使系统尽早减少此 BE 节点上的负载。
平衡策略
每次 Tablet Scheduler 调度 tablet 时,它都会选择一定数量的健康 tablet 作为通过负载均衡器进行平衡的候选 tablet。下次调度 tablet 时,Tablet Scheduler 会平衡这些健康的 tablet。
检查 tablet 调度任务
您可以检查待处理、正在运行和已完成的 tablet 调度任务。
-
检查待处理的 tablet 调度任务
SHOW PROC '/cluster_balance/pending_tablets';
示例
+----------+--------+-----------------+---------+----------+----------+-------+---------+--------+----------+---------+---------------------+---------------------+---------------------+----------+------+-------------+---------------+---------------------+------------+---------------------+--------+---------------------+-------------------------------+
| TabletId | Type | Status | State | OrigPrio | DynmPrio | SrcBe | SrcPath | DestBe | DestPath | Timeout | Create | LstSched | LstVisit | Finished | Rate | FailedSched | FailedRunning | LstAdjPrio | VisibleVer | VisibleVerHash | CmtVer | CmtVerHash | ErrMsg |
+----------+--------+-----------------+---------+----------+----------+-------+---------+--------+----------+---------+---------------------+---------------------+---------------------+----------+------+-------------+---------------+---------------------+------------+---------------------+--------+---------------------+-------------------------------+
| 4203036 | REPAIR | REPLICA_MISSING | PENDING | HIGH | LOW | -1 | -1 | -1 | -1 | 0 | 2019-02-21 15:00:20 | 2019-02-24 11:18:41 | 2019-02-24 11:18:41 | N/A | N/A | 2 | 0 | 2019-02-21 15:00:43 | 1 | 0 | 2 | 0 | unable to find source replica |
+----------+--------+-----------------+---------+----------+----------+-------+---------+--------+----------+---------+---------------------+---------------------+---------------------+----------+------+-------------+---------------+---------------------+------------+---------------------+--------+---------------------+-------------------------------+TabletId
:待调度的 tablet 的 ID。一个调度任务仅适用于一个 tablet。Type
:任务类型。有效值:REPAIR 和 BALANCE。Status
:tablet 的当前状态,例如 REPLICA_MISSING。State
:调度任务的状态。有效值:PENDING、RUNNING、FINISHED、CANCELLED、TIMEOUT 和 UNEXPECTED。OrigPrio
:任务的原始优先级。DynmPrio
:动态调整后任务的当前优先级。SrcBe
:源 BE 节点的 ID。SrcPath
:源 BE 节点路径的哈希值。DestBe
:目标 BE 节点的 ID。DestPath
:目标 BE 节点路径的哈希值。Timeout
:成功调度任务时任务的超时时间。单位:秒。Create
:任务创建的时间。LstSched
:最近一次调度任务的时间。LstVisit
:最近一次访问任务的时间。此处访问任务意味着调度任务或报告其执行情况。Finished
:任务完成的时间。Rate
:克隆数据的速率。FailedSched
:任务调度失败的次数。FailedRunning
:任务执行失败的次数。LstAdjPrio
:最近一次调整任务优先级的时间。CmtVer
、CmtVerHash
、VisibleVer
和VisibleVerHash
:用于执行克隆任务的版本信息。ErrMsg
:调度和运行任务时发生的错误消息。
-
检查正在运行的 tablet 调度任务
SHOW PROC '/cluster_balance/running_tablets';
返回的结果与待处理任务的结果相同。
-
检查已完成的 tablet 调度任务
SHOW PROC '/cluster_balance/history_tablets';
返回的结果与待处理任务的结果相同。如果任务的
State
为FINISHED
,则表示任务已成功完成。如果不是,请检查ErrMsg
字段以获取任务失败的原因。
资源控制
由于 StarRocks 通过将 tablet 从一个 BE 节点克隆到另一个 BE 节点来修复和平衡 tablet,因此如果节点在短时间内过于频繁地执行此类任务,BE 节点的 I/O 负载可能会急剧增加。为避免这种情况,StarRocks 为每个 BE 节点的克隆任务设置了并发限制。资源控制的最小单位是磁盘,它是您在 BE 配置文件中指定的数据存储路径 (storage_root_path
)。默认情况下,StarRocks 为每个磁盘分配两个槽位来处理 tablet 修复任务。克隆任务占用源 BE 节点上的一个槽位和目标 BE 节点上的一个槽位。如果 BE 节点上的所有槽位都被占用,StarRocks 将停止向该节点调度任务。您可以通过增加 FE 动态参数 tablet_sched_slot_num_per_path
的值来增加 BE 节点上的槽位数。
StarRocks 专门为 tablet 平衡任务分配了两个槽位,以避免因 tablet 修复任务不断占用槽位而导致高负载 BE 节点无法通过平衡 tablet 来释放磁盘空间的情况。