随着对 Postgres 的 Citus 扩展的10.1 版本发布,您现在可以监控正在进行的分片重新平衡的进度——此外,您还可以获得性能优化,以及重新平衡器的一些用户体验改进。
https://www.citusdata.com/blog/2021/07/30/citus-10-1-extension-to-postgres-whats-new/
无论您是使用 Citus开源来扩展 Postgres,还是在云中使用 Citus,这篇文章都是您了解 Citus 10.1 中的分片重新平衡器新增功能的指南。
如果您想知道何时可能需要使用分片重新平衡器:当您将新的 Postgres 节点添加到现有的 Citus 数据库集群并且您希望将一些旧数据移动到这个新节点时使用重新平衡器,以“平衡”集群。有时您可能希望平衡 Citus 集群中节点之间的分片以优化性能。一个常见的例子是当你有一个 SaaS 应用程序并且你的一个客户/租户的活动比其他人多得多。
如果您还没有听到激动人心的消息:在 2021 年初的 Citus 10 中,我们开源了 shard rebalancer。我之前的博客文章详细解释了这种变化对您意味着什么。
https://www.citusdata.com/blog/2021/03/13/scaling-out-postgres-with-citus-open-source-shard-rebalancer/
监控分片移动的进度
当您使用 Citus 分发 Postgres 表时,该表通常分布在多个节点上。人们通常将此称为跨集群中多个节点的 Postgres 表“分片”。在 Citus 中,分布式表的这些较小组件称为“分片”。
一旦你开始重新平衡分片,重新平衡器会告诉你它将移动哪个分片。你们中的一些人最常问的问题之一是:“分片移动需要多长时间?” 答案取决于正在移动的分片上的数据量以及移动这些数据的速度:分片重新平衡可能需要几分钟、几小时甚至几天才能完成。
使用 Citus 10.1,您现在可以轻松监控重新平衡的进度。虽然监控进度不会直接告诉您重新平衡需要多长时间,但好消息是您将能够看到重新平衡仍在进行中以及大致走了多远。
要查看进度,您可以使用get_rebalance_progress
功能。这个函数在以前的 Citus 版本中已经存在,但在 Citus 10.1 版本中它变得更加有用:get_rebalance_progress
现在会告诉你源节点和目标节点上的分片大小!要查看此信息,您可以运行以下查询(在与运行重新平衡本身的会话不同的会话中):
SELECT * FROM get_rebalance_progress();
┌───────────┬────────────┬─────────┬────────────┬────────────┬────────────┬────────────┬────────────┬──────────┬───────────────────┬───────────────────┐
│ sessionid │ table_name │ shardid │ shard_size │ sourcename │ sourceport │ targetname │ targetport │ progress │ source_shard_size │ target_shard_size │
├───────────┼────────────┼─────────┼────────────┼────────────┼────────────┼────────────┼────────────┼──────────┼───────────────────┼───────────────────┤
│ 13524 │ customers │ 102008 │ 46718976 │ localhost │ 9701 │ localhost │ 9702 │ 2 │ 46686208 │ 46718976 │
│ 13524 │ orders │ 102024 │ 52355072 │ localhost │ 9701 │ localhost │ 9702 │ 2 │ 52322304 │ 52355072 │
│ 13524 │ customers │ 102012 │ 46628864 │ localhost │ 9701 │ localhost │ 9703 │ 2 │ 46604288 │ 46628864 │
│ 13524 │ orders │ 102028 │ 52264960 │ localhost │ 9701 │ localhost │ 9703 │ 2 │ 52232192 │ 52264960 │
│ 13524 │ customers │ 102016 │ 46669824 │ localhost │ 9701 │ localhost │ 9704 │ 1 │ 46669824 │ 46702592 │
│ 13524 │ orders │ 102032 │ 52297728 │ localhost │ 9701 │ localhost │ 9704 │ 1 │ 52297728 │ 0 │
│ 13524 │ customers │ 102020 │ 46702592 │ localhost │ 9701 │ localhost │ 9702 │ 0 │ 46702592 │ 0 │
│ 13524 │ orders │ 102036 │ 52338688 │ localhost │ 9701 │ localhost │ 9702 │ 0 │ 52338688 │ 0 │
└───────────┴────────────┴─────────┴────────────┴────────────┴────────────┴────────────┴────────────┴──────────┴───────────────────┴───────────────────┘
复制
列中的值progress
具有以下含义:
0:尚未开始
1:进行中
2:已完成
利用这些知识,您可以使用以下 SQL 查询来具体查看 Citus 分片重新平衡器当前正在执行的分片移动的进度,使用以下查询:
-- To show the progress for each shard that's currently being moved
SELECT
table_name,
shardid,
pg_size_pretty(source_shard_size) AS source_shard_size,
pg_size_pretty(target_shard_size) AS target_shard_size,
CASE WHEN shard_size = 0
THEN 100
ELSE LEAST(round(target_shard_size::numeric shard_size * 100, 2), 100)
END AS percent_completed_estimate
FROM get_rebalance_progress()
WHERE progress = 1;
┌────────────┬─────────┬───────────────────┬───────────────────┬────────────────────────────┐
│ table_name │ shardid │ source_shard_size │ target_shard_size │ percent_completed_estimate │
├────────────┼─────────┼───────────────────┼───────────────────┼────────────────────────────┤
│ customers │ 102013 │ 44 MB │ 44 MB │ 100 │
│ orders │ 102029 │ 50 MB │ 23 MB │ 45.85 │
└────────────┴─────────┴───────────────────┴───────────────────┴────────────────────────────┘
-- To show the progress for the colocation group that's being moved as a whole
SELECT
pg_size_pretty(sum(source_shard_size)) AS source_shard_size,
pg_size_pretty(sum(target_shard_size)) AS target_shard_size,
CASE WHEN sum(shard_size) = 0
THEN 100
ELSE LEAST(round(sum(target_shard_size)::numeric / sum(shard_size) * 100, 2), 100)
END AS percent_completed_estimate
FROM get_rebalance_progress()
WHERE progress = 1;
┌───────────────────┬───────────────────┬────────────────────────────┐
│ source_shard_size │ target_shard_size │ percent_completed_estimate │
├───────────────────┼───────────────────┼────────────────────────────┤
│ 95 MB │ 45 MB │ 47.15 │
└───────────────────┴───────────────────┴────────────────────────────┘
复制
您可以通过自己做一些基本的数学运算来粗略地了解分片的移动需要多长时间。如果percent_completed_estimate
在 10 分钟内从 30% 上升到 40%,那么分片移动发生的速率是每 10 分钟 10%。由于还剩下 60%,这意味着您将需要等待大约 60 分钟才能完成分片移动。但是,在某些情况下,有一些重要的警告会使这个时间估计不精确:
此查询中的
percent_completed_estimate
列与其说是精确的进度条,不如说是一个粗略的指示。为什么?移动之后,分片可能会比以前更小——因为通过移动数据,Postgres VACUUM 本质上是在表上运行的。因此,percent_completed_estimate
可能无法达到 100%,因为分片现在的大小比原来的小。如果一个分片似乎卡住了,但另一个分片仍在进行中,则很可能似乎卡住的分片已经完成了数据传输。如果你想知道为什么这样的分片仍然被标记为“进行中”:这是因为一个分片不会被标记为“完成”,直到它所在的所有分片也被成功移动。
在查看分片重新平衡器进度时,还有另一件重要的事情要记住:在重新平衡结束时,会创建索引。索引创建也可能需要很长时间,尽管数据传输通常需要更长的时间。遗憾的是,目前在进度监视器输出中没有指示索引创建过程中的进度。
这对您意味着什么:如果您认为没有任何进展,请不要立即停止重新平衡器,即使所有分片的转移几乎都已完成。如果您的 Citus 表上有 Postgres 索引,那么您很可能只需要等待更长的时间,直到索引完成创建。如果您想确定这是怎么回事,最简单的确认方法是直接连接到 Citus 工作节点并查看pg_stat_activity
. 如果有一个CREATE INDEX
查询正在运行,那么很有可能重新平衡器当前正忙于创建您的 Postgres 索引。
优化分片重新平衡与 Postgres 分区的工作方式
与 Postgres 查询计划类似,分片重新平衡器在重新平衡时所做的第一件事是确定将每个分片移动到何处的计划。为了构建这个计划,重新平衡器需要磁盘上的分片大小。在以前的 Citus 版本中,当集群包含数千个分片时,获取这些大小可能会变得非常慢。这种情况主要发生在集群包含分区表时,因为 Postgres 分区通常会导致创建大量分片(每个分区一个)。从 10.1 开始,重新平衡器获取分片大小的方式得到了优化,即使集群中有大量分片,也可以快速执行此操作。
检查目标节点上是否有空间
磁盘用完是 Postgres 服务器可能发生的最糟糕的事情之一。发生这种情况时,Postgres 将崩溃。再次启动 Postgres 的唯一方法是获取更大的磁盘或删除不必要的文件,例如日志文件。
分片再平衡器经常在分布式集群中的节点之间移动大块数据。这就是为什么我们为分片重新平衡器添加了一个新的安全功能:在实际移动一个分片之前,Citus 重新平衡器将首先检查目标节点上是否有足够的空间来实际存储它(加上一些安全余量)。
默认情况下延迟删除分片
Citus 10.1 还解决了你们中的一些人可能遇到的烦人问题:在 Citus 10.1 之前,分片移动有时会在移动正常完成时被取消并回滚。为什么?移动所有数据后,重新平衡器用于将分片放到源节点上。但是,当其他查询仍在读取或写入此分片时,删除可能会导致分布式死锁。这种死锁只会发生在高度并发的事务中,并且当您在很短的时间窗口内以相反的顺序获得锁时。
我们现在默认启用了延迟删除分片,这样可以确保不会发生这种死锁。延迟删除意味着不是立即删除旧节点上的分片,而是仅将分片标记为删除。然后过了一会儿,只有在所有读取查询都完成后,分片才会真正被删除。我们将这种等待被丢弃的碎片称为“孤立碎片”。
此功能在 Citus 10.1 中并不是严格意义上的新功能。在以前的版本中已经可以通过设置citus.defer_drop_after_shard_move
来启用此功能true
。但是,如果不小心使用,以前的实现可能会导致令人困惑的错误。这个版本我们花在了强化这个特性和改进所有的错误信息上,使它们变得有意义。这就是为什么延迟丢弃现在默认打开的原因——因为我们现在确信它可以像我们希望的那样工作。
10.1 中的 Citus 分片再平衡器:更快乐、更快,并且有一种监控方式
使用 Citus 10.1,当使用分片重新平衡器来平衡集群中节点之间的数据大小时,您会更开心。您的碎片将移动得更快。您可以看到正在取得的进展。最后,您的分片移动将不再回滚,因为 Citus 避免了我之前提到的分布式死锁。
如果您想了解有关 Citus 再平衡器(最近开源!)的更多信息,您可能需要查看我以前的帖子(https://www.citusdata.com/blog/2021/03/13/scaling-out-postgres-with-citus-open-source-shard-rebalancer/)或查看有关分片再平衡器(https://docs.citusdata.com/en/stable/develop/api_udf.html?#rebalance-table-shards)和再平衡器策略(https://docs.citusdata.com/en/stable/develop/api_metadata.html#rebalancer-strategy-table)的文档。
如果您是 Citus 的新手,您可以在这里找到很好的在线入门资源(https://www.citusdata.com/getting-started/)集合。和往常一样,如果您有任何问题,您可以在我们的Citus slack(https://slack.citusdata.com/)上找到我和其他 Citus 工程师以及其他用途。