Citus 是 Postgres 的扩展,可让您将应用程序的工作负载分布在多个节点上。无论您是使用 Citus 开源还是使用 Citus 作为云中托管 Postgres 服务的一部分,当您开始使用 Citus 时,您要做的第一件事就是分发您的表。在分发 Postgres 表时,您需要确定一些属性,例如分布列、分片计数、托管。甚至在你决定你的分布列(有时称为分布键或分片键)之前,当你创建一个 Postgres 表时,你的表是使用访问方法创建的。
以前,您必须预先决定这些表属性,然后再进行决定。或者如果你真的想改变你的决定,你需要重新开始。好消息是,在 Citus 10 中,我们引入了 2 个新的用户定义函数 (UDF),以便您更轻松地更改分布式 Postgres 表。
在 Citus 9.5 之前,如果您想更改分布式表的任何属性,您必须创建一个具有所需属性的新表并将所有内容移动到这个新表中。但在 Citus 9.5 中,我们引入了一个新函数 undistribute_table。使用 undistribute_table 函数,您可以将分布式 Citus 表转换到本地 Postgres 表,然后使用您希望的属性再次分发它们。但是取消分配然后再次分配是……2个步骤。除了不得不写 2 条命令的不便之外,取消分发然后再次分发还有一些问题:
- 移动一个大表的数据可能需要很长时间,非分布和分布都需要移动表的所有数据。因此,您必须移动数据两次,这要长得多。
- Undistributing 将表的所有数据移动到 Citus 协调器节点。如果您的协调器节点不够大,而协调器节点通常不必如此,您可能无法将表放入您的协调器节点。
因此,在 Citus 10 中,我们引入了 2 个新功能来减少更改表格所需的步骤:
- alter_distributed_table
- alter_table_set_access_method
在这篇文章中,您将找到一些关于如何使用 alter_distributed_table 函数更改分布式 Citus 表的分片数、分布列和托管的技巧。我们将展示如何使用 alter_table_set_access_method 函数来更改访问方法。重要说明:您可能永远不需要更改 Citus 表属性。我们只是想让您知道,如果您这样做,您将拥有灵活性。通过这些 Citus 提示,您将知道如何进行更改。

改变 Citus 中分布式 Postgres 表的属性
当您使用 create_distributed_table 函数分发 Postgres 表时,您必须选择一个分布列并设置 distribution_column 参数。在分发过程中,Citus 使用一个名为 shard_count 的配置变量来决定表的分片计数。您还可以提供 colocate_with 参数来选择要与之共置的表(或者如果可能,将自动完成共置)。
但是,在分发之后,如果您决定需要不同的配置,从 Citus 10 开始,您可以使用 alter_distributed_table 函数。
alter_distributed_table 具有三个可以更改的参数:
- 分布柱
- 分片数
- 托管属性
如何更改分布列(又名分片键)
Citus 根据您在分发时选择的分发列将您的表划分为碎片。选择正确的分布列对于获得良好的分布式数据库体验至关重要。一个好的分布列将通过平均划分数据并保持相关数据点彼此靠近,从而帮助您更好地并行化数据和工作负载。但是,刚开始时选择分布列可能有点棘手。或者稍后当您在应用程序中进行更改时,您可能需要选择另一个分布列。
使用新的 alter_distributed_table 函数的 distribution_column 参数,Citus 10 为您提供了一种更改分布列的简单方法。
假设您有客户和客户下的订单。您将创建一些 Postgres 表,如下所示:
CREATE TABLE customers (customer_id BIGINT, name TEXT, address TEXT);
CREATE TABLE orders (order_id BIGINT, customer_id BIGINT, products BIGINT[]);
首次使用 Citus 分发 Postgres 表时,假设您决定将 customers 表分发到 customer_id 上,将 orders 表分发到 order_id 上。
SELECT create_distributed_table ('customers', 'customer_id');
SELECT create_distributed_table ('orders', 'order_id');
稍后您可能会意识到按 order_id 列分配订单表可能不是最好的主意。 即使 order_id 可能是均匀分布数据的好列,但如果您经常需要在 customer_id 上将 orders 表与客户表连接起来,这不是一个好的选择。 当两个表都按 customer_id 分布时,您可以使用同位连接,与其他列上的连接相比,这非常有效。
因此,如果您决定将订单表的分布列更改为 customer_id,请执行以下操作:
SELECT alter_distributed_table ('orders', distribution_column := 'customer_id');
现在订单表由 customer_id 分发。 因此,客户和客户的订单在同一个节点并且彼此靠近,并且您可以拥有包含 customer_id 的快速连接和外键。
您可以在 citus_tables 视图中看到新的分布列:
SELECT distribution_column FROM citus_tables WHERE table_name::text = 'orders';
如何增加(或减少) Citus 中的分片数
分布式 Citus 表的分片数是分布式表被划分的片数。 选择分片数量是在拥有更多分片的灵活性与跨分片的查询计划和执行开销之间取得平衡。 与分布列一样,分片数也是在分布表时设置的。 如果您想为表选择与默认值不同的分片计数,在分发过程中您可以使用 citus.shard_count 配置变量,如下所示:
CREATE TABLE products (id BIGINT, name TEXT);
SET citus.shard_count TO 20;
SELECT create_distributed_table ('products', 'id');
分配表后,您可能会认为您设置的分片计数不是最佳选择。 或者,您对分片数量的第一个决定可能在一段时间内是好的,但您的应用程序可能会随着时间的推移而增长,您可能会向 Citus 集群添加新节点,并且您可能需要更多分片。 alter_distributed_table 函数涵盖了您也想更改分片计数的情况。
要更改分片计数,只需使用 shard_count 参数:
SELECT alter_distributed_table ('products', shard_count := 30);
在上面的查询之后,您的表将有 30 个分片。 您可以在 citus_tables 视图中查看表的分片数:
SELECT shard_count FROM citus_tables WHERE table_name::text = 'products';
如何与不同的 Citus 分布式表共存
当两个 Postgres 表并置在 Citus 中时,分布列中具有相同值的表的行将位于同一个 Citus 节点上。 托管正确的表将帮助您进行更好的关系操作。 与分片计数和分布列一样,托管也是在分布表时设置的。 您可以使用 colocate_with 参数来更改托管。
SELECT alter_distributed_table ('products', colocate_with := 'customers');
同样,与分布列和分片计数一样,您可以在 citus_tables 视图中找到有关表托管组的信息:
SELECT colocation_id FROM citus_tables WHERE table_name IN ('products', 'customers');
您还可以使用带有 colocate_with 参数的 default 和 none 关键字将表的托管组更改为默认值,或破坏表的任何托管。
要托管分布式 Citus 表,分布式表需要具有相同的分片数。 但是,如果您要托管的表没有相同的分片数,请不要担心,因为 alter_distributed_table 会自动理解这一点。 然后您的表的分片计数也将更新以匹配新托管组的分片计数。
如何一次更改多个 Citus 表属性
这里有一个提示! 如果您想同时更改分布式 Citus 表的多个属性,您可以简单地使用 alter_distributed_table 函数的多个参数。
例如,如果您想同时更改表的分片数和分布列,请执行以下操作:
SELECT alter_distributed_table ('products', distribution_column := 'name', shard_count := 35);
如何更改 Citus 托管组
如果您的表与其他一些表位于同一位置,并且您想更改所有表的分片数以保持同一位置,您可能想知道是否必须一一更改它们……这是多个步骤。
是的(您可以在此处看到一个模式) Citus 提示是您可以使用 alter_distributed_table 函数来更改所有托管组的属性。
如果您决定使用 alter_distributed_table 函数所做的更改需要对与您正在更改的表位于同一位置的所有表进行,您可以使用 cascade_to_colocated 参数:
SET citus.shard_count TO 10;
SELECT create_distributed_table ('customers', 'customer_id');
SELECT create_distributed_table ('orders', 'customer_id', colocate_with := 'customers');
-- when you decide to change the shard count
-- of all of the colocation group
SELECT alter_distributed_table ('customers', shard_count := 20, cascade_to_colocated := true);
您可以在 citus_tables 视图中看到两个表的更新分片计数:
SELECT shard_count FROM citus_tables WHERE table_name IN ('customers', 'orders');
如何在 Citus 中更改 Postgres 表的访问方法
Citus 10 中引入的另一个惊人功能是列式存储。这篇 Citus 10 柱状博客文章将引导您了解它的工作原理以及如何将柱状表(或分区)与 Citus 一起使用,并附有快速入门。哦,Jeff 还制作了一个关于新 Citus 10 柱状功能的简短视频演示 - 值得花 13 分钟观看恕我直言。
使用 Citus columnar,您可以选择按列分组存储表,这也为您带来了压缩的好处。当然,您不必使用新的列访问方法——默认访问方法是“堆”,如果您不指定访问方法,那么您的表将是基于行的表(使用堆访问方法.)
引入这种很酷的新 Citus 列式访问方法而不提供将表转换为列式的方法是不公平的。所以 Citus 10 也引入了一种改变表的访问方式的方法。
SELECT alter_table_set_access_method('orders', 'columnar');
您也可以使用 alter_table_set_access_method 将表转换为任何其他访问方法,例如堆,Postgres 的默认访问方法。此外,您的表甚至不需要是分布式 Citus 表。您还可以将 alter_table_set_access_method 与 Citus 参考表以及常规 Postgres 表一起使用。您甚至可以使用 alter_table_set_access_method 更改 Postgres 分区的访问方法。
幕后:这些新的 Citus 功能是如何工作的?
如果你读过关于 undistribute_table 的博客文章,Citus 9.5 引入的用于将分布式 Citus 表转换到本地 Postgres 表的函数,你大多知道 alter_distributed_table 和 alter_table_set_access_method 函数是如何工作的。因为我们使用与 undistribute_table 函数相同的底层方法。好吧,我们改进了它。
alter_distributed_table 和 alter_table_set_access_method 函数:
- 以您想要的方式创建一个新表(使用新的分片计数或访问方法等
- 将旧表中的所有内容移至新表
- 删除旧表并重命名新表
为了重新创建具有不同属性的同一个表而删除一个表并不是一项简单的任务。删除 table 也会删除许多依赖 table 的东西。
就像 undistribute_table 函数一样,alter_distributed_table 和 alter_table_set_access_method 函数在保留您不想更改的表的属性方面做了很多工作。这些函数将处理索引、序列、视图、约束、表所有者、分区等等——就像 undistribute_table 一样。
alter_distributed_table 和 alter_table_set_access_method 也将尽可能在您的表上重新创建外键。例如,如果您使用 alter_distributed_table 函数更改表的分片数,并使用 cascade_to_colocated := true 更改所有并置表的分片数,则托管组内的外键和托管的分布式表中的外键将重新创建到 Citus 参考表的组。
让 Citus 的实验变得更容易——并根据您的需求变化进行调整
如果您想了解更多关于我们之前为 alter_distributed_table 和 alter_table_set_access_method 函数构建的工作,请查看我们关于 undistribute_table 的博客文章。
在 Citus 10 中,我们努力为您提供更多工具和更多功能来更改分布式数据库。当您刚开始使用 Citus 时,新的 alter_distributed_table 和 alter_table_set_access_method 函数以及 undistribute_table 函数都可以帮助您试验并找到最适合您的应用程序的数据库配置。将来,如果您的应用程序发展了,这三个 Citus 功能也将准备好帮助您发展 Citus 数据库。
原文标题:Citus Tips for Postgres: How to alter distribution key, shard count, & more
原文作者:Halil Ozan Akgul
原文地址:https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/citus-tips-for-postgres-how-to-alter-distribution-key-shard/ba-p/2311470




