练习 - 探索 Citus 如何分布表

已完成

在本练习中,你将创建一个多节点 Azure Cosmos DB for PostgreSQL 数据库。 然后,在对数据库运行一些查询之前,你将创建一些表,以详细了解适用于 PostgreSQL 的 Citus 扩展提供的分布式体系结构。

创建 Azure Cosmos DB for PostgreSQL 数据库

若要完成本练习,必须创建 Azure Cosmos DB for PostgreSQL 群集。 群集将具有:

  • 一个协调器节点,包含 4 个 vCore、16-GiB RAM 和 512 GiBM 存储
  • 两个工作器节点,每个节点包含 4 个 vCore、32-GiB RAM 和 512 GiBM 存储
  1. 在 Web 浏览器中,导航到 Azure 门户

  2. 在 Azure 门户中,选择“创建资源”、“数据库”和“Azure Cosmos DB”。 也可以使用搜索功能来查找资源。

    Screenshot of the Azure portal's create a resource screen where Databases and Azure Cosmos DB are highlighted.

  3. 在“选择 API 选项”屏幕上的“Azure Cosmos DB for PostgreSQL”磁贴中,选择“创建”。

    Screenshot of the Azure Cosmos DB for PostgreSQL tile that is highlighted on the Azure Cosmos DB Select API option dialog.

    注意

    选择“创建”后,门户将显示数据库配置屏幕

  4. 在“基本”选项卡上,输入下列信息:

    参数
    项目详细信息
    订阅 选择自己的 Azure 订阅。
    资源组 选择“新建”,然后将资源组命名为 learn-cosmosdb-postgresql
    群集详细信息
    群集名称 输入全局唯一名称,例如 learn-cosmosdb-postgresql
    位置 保留默认值,或使用你附近的区域。
    缩放 请参阅下一步的配置设置。
    PostgreSQL 版本 保留默认版本 (15) 处于选中状态。
    管理员帐户
    管理员用户名 此用户名设置为 citus,不可编辑。
    Password 输入并确认强密码。

    Screenshot of the Basics tab of the Create an Azure Cosmos DB - PostgreSQL cluster dialog. The fields are populated with the values specified in the exercise.

    请记下密码供以后使用。

  5. 对于“缩放”设置,请选择“配置”并在节点配置页上设置以下内容

    参数
    Nodes
    节点计数 选择 2 个节点
    每个节点的计算 选择“4 个 vCore、32 GiB RAM”
    每个节点的存储 选择“512 GiBM”。
    协调器 (可能需要展开本部分)
    协调器计算 选择“4 个 vCore、16 GiB RAM”。
    协调器存储 选择“512 GiBM”。

    高可用性和自动故障转移功能不在本练习的范围内,因此请取消选中“高可用性”复选框

    Screenshot of the Create an Azure Cosmos DB - PostgreSQL cluster configuration dialog.

  6. 在缩放页上选择“保存”以返回到群集配置

  7. 选择“下一步: 网络 >”按钮,转到配置对话框的“网络”选项卡

  8. 在“网络”选项卡上,将“连接方法”设置为“公共访问(允许的 IP 地址)”,并选中“允许从 Azure 内的 Azure 服务和资源对此群集进行公共访问”框

    Screenshot of the Create an Azure Cosmos DB - PostgreSQL cluster Networking tab. The settings specified in the exercise are highlighted.

  9. 选择“审阅 + 创建”按钮,然后在审阅屏幕上选择“创建”以创建群集。

在 Azure Cloud Shell 中使用 psql 连接到数据库

  1. Azure Cosmos DB for PostgreSQL 群集完成预配后,请在 Azure 门户中导航到该资源。

  2. 在左侧导航菜单中,选择“设置”下的“连接字符串”,并复制标记为“psql”的连接字符串

    Screenshot of the Connection strings page of the Azure Cosmos DB Cluster resource.

    在“连接字符串”页上,突出显示 psql 连接字符串右侧的“复制到剪贴板”按钮。

  3. 将连接字符串粘贴到文本编辑器(如记事本)中,并将 {your_password} 令牌替换为在创建群集时分配给 citus 用户的密码。 复制更新的连接字符串,以供后面使用。

  4. 在 Web 浏览器中打开 Azure Cloud Shell

  5. 选择“Bash”作为环境

    Screenshot of the welcome page of Azure Cloud Shell with a prompt to choose an environment between Bash or PowerShell. Bash is highlighted.

  6. 如果系统提示,请选择用于 Azure Cosmos DB for PostgreSQL 帐户的订阅。 然后选择“创建存储”。

    Screenshot of the Azure Cloud Shell wizard showing no storage mounted is displayed. Azure Subscription is showing in the Subscription dropdown.

  7. 现在,使用 psql 命令行实用工具来连接到数据库。 在 Cloud Shell 的提示符处粘贴更新后的连接字符串(包含正确密码的连接字符串),然后运行命令,该命令应类似于以下命令:

    psql "host=c.learn-cosmosdb-postgresql.postgres.database.azure.com port=5432 dbname=citus user=citus password=P@ssword.123! sslmode=require"
    

发现有关群集中节点的信息

协调器元数据表包含有关群集中工作器节点的信息。

  1. 对工作器节点表 pg_dist_node 执行以下查询,以查看有关群集中节点的信息:

    -- Turn on expanded display to pivot the results 
    \x
    
    -- Retrieve node details
    SELECT * FROM pg_dist_node;
    
  2. 查看查询输出的详细信息,包括与每个节点关联的 ID、名称和端口。 此外,还可以查看节点是否处于活动状态,是否应该包含分片以及其他信息。

    -[ RECORD 1 ]----+-----------------------------------------------------------------
    nodeid           | 2
    groupid          | 2
    nodename         | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    nodeport         | 5432
    noderack         | default
    hasmetadata      | t
    isactive         | t
    noderole         | primary
    nodecluster      | default
    metadatasynced   | t
    shouldhaveshards | t
    -[ RECORD 2 ]----+-----------------------------------------------------------------
    nodeid           | 3
    groupid          | 3
    nodename         | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    nodeport         | 5432
    noderack         | default
    hasmetadata      | t
    isactive         | t
    noderole         | primary
    nodecluster      | default
    metadatasynced   | t
    shouldhaveshards | t
    -[ RECORD 3 ]----+-----------------------------------------------------------------
    nodeid           | 4
    groupid          | 0
    nodename         | private-c.learn-cosmosdb-postgresql.postgres.database.azure.com
    nodeport         | 5432
    noderack         | default
    hasmetadata      | t
    isactive         | t
    noderole         | primary
    nodecluster      | default
    metadatasynced   | t
    shouldhaveshards | f
    

    可以使用输出中提供的节点名称和端口号直接连接到辅助角色,这是优化查询性能时的常见做法。 若要直接连接到工作器节点,需在 Azure 门户中的 Azure Cosmos DB for PostgreSQL 资源的“网络”页面上选中“启用对工作器节点的访问”复选框

    Screenshot of the enable access to the worker nodes option in the Networking section. Networking is highlighted and selected in the left-hand navigation menu.

创建分布式表

连接到数据库后,现在即可填充数据库。 你将使用 psql 完成以下操作:

  • 创建用户和付款表。
  • 指示 Citus 分布这两个表,将它们分片到工作器节点。

分布式表在可用的工作器节点之间水平分区。 这种分布意味着表的行存储在称为分片的片段表的不同节点上。

  1. 在 Cloud Shell 中,运行以下查询来创建 payment_userspayment_events 表:

    CREATE TABLE payment_users
    (
        user_id bigint PRIMARY KEY,
        url text,
        login text,
        avatar_url text
    );
    
    CREATE TABLE payment_events
    (
        event_id bigint,
        event_type text,
        user_id bigint,
        merchant_id bigint,
        event_details jsonb,
        created_at timestamp,
        -- Create a compound primary key so that user_id can be set as the distribution column
        PRIMARY KEY (event_id, user_id)
    );
    

    payment_events 表的 PRIMARY KEY 分配是一个复合键,允许将 user_id 字段指定为分布列。

  2. 执行 CREATE TABLE 命令时,将在协调器节点上创建本地表。 若要将表分发给工作器节点,必须为每个表运行 create_distributed_table 函数,指定在对其进行分片时要使用的分布列。 在 Cloud Shell 中,运行以下查询以跨工作器节点分发 payment_eventspayment_users 表:

    SELECT create_distributed_table('payment_users', 'user_id');
    SELECT create_distributed_table('payment_events', 'user_id');
    

    payment_eventspayment_users 表都分配给了相同的分布列,导致这两个表的相关数据共置于同一节点上。 关于选择正确分布列的详细信息超出了本学习模块的范围。 不过,你可以通过阅读 Microsoft 文档中在 Azure Cosmos DB for PostgreSQL 中选择分布列一文来了解有关这一点的详细信息。

创建引用表

接下来,你将使用 psql 执行以下操作:

  • 创建商家表。
  • 指示 Citus 将整个表作为引用表分布到每个工作器节点上。

引用表是一种分布式表,其所有内容都集中到了单个分片中。 针对任何工作器的查询都可以在本地访问引用信息,无需从另一个节点请求行,因此也不会产生此类网络开销。 引用表不需要分布列的规范,因为无需区分每行的不同分片。 引用表通常很小,并用于存储与任何工作器节点上运行的查询相关的数据。

  1. 在 Cloud Shell 中,运行以下查询以创建 payment_merchants 表:

    CREATE TABLE payment_merchants
    (
        merchant_id bigint PRIMARY KEY,
        name text,
        url text
    );
    
  2. 接下来,使用 create_reference_table() 函数将表分发到每个工作器节点。

    SELECT create_reference_table('payment_merchants');
    

将数据加载到事件表中

Woodgrove Bank 以 CSV 文件的形式向你提供了他们的历史事件数据,因此你在安装和测试请求的扩展时可以使用一些数据。 他们将通过安全的 Azure Blob 存储帐户提供用户数据,以便你在下一练习中填充 payment_users 表。 events.csv 文件可通过可公开访问的 URL 获得。

可以使用 COPY 命令将此数据一次性大容量加载到 payment_events 表中。

  1. 运行以下命令以下载包含用户和付款信息的 CSV 文件,然后使用 COPY 命令将数据从下载的 CSV 文件加载到分布式表 payment_userspayment_events 中:

    SET CLIENT_ENCODING TO 'utf8';
    
    \COPY payment_events FROM PROGRAM 'curl https://raw.githubusercontent.com/MicrosoftDocs/mslearn-create-connect-postgresHyperscale/main/events.csv' WITH CSV
    

    在发出的 COPY 命令中,FROM PROGRAM 子句通知协调器从运行在协调器上的应用程序(在本例中为 curl)检索数据文件。 WITH CSV 选项提供有关要引入的文件的格式的信息。

  2. 执行以下命令以验证数据是否已使用 COPY 命令加载到 payment_events 表中。

    SELECT COUNT(*) FROM payment_events;
    

查看有关分布式表的详细信息

现在,你已经创建了几个分布式表,让我们使用 citus_tables 视图来检查这些表。

  1. 执行以下查询以查看分布式表的详细信息:

    SELECT table_name, citus_table_type, distribution_column, table_size, shard_count FROM citus_tables;
    
  2. 观察查询的输出及其提供的详细信息。

    table_name        | citus_table_type | distribution_column | table_size | shard_count 
    ------------------+------------------+---------------------+------------+-------------
    payment_events    | distributed      | user_id             | 26 MB      |          32
    payment_merchants | reference        | <none>              | 48 kB      |           1
    payment_users     | distributed      | user_id             | 512 kB     |          32
    

    注意

    请注意 shard_count 以及用于分布式表和引用表的分片数之间的差异。 这种差异提供了一些关于 Citus 如何在内部处理数据分布的见解。 citus_table 视图还包括有关表大小的信息。

检查表分片

接下来,查看 Citus 为分发每个表的数据而创建的分片:

  1. pg_dist_shard 元数据表包含群集中分片的详细信息。 执行以下查询以查看为每个表创建的分片:

    SELECT * from pg_dist_shard;
    
  2. 查看上述查询的输出。 回想一下,payment_merchants 表存在于单个分片中。 将其与 payment_events 表和 payment_users 表进行比较,每个表包含 32 个分片。

  3. 若要查看 Citus 如何处理分片引用表,你可以使用 citus_shards 视图来查看工作器节点上分片的位置。 执行以下查询:

    SELECT table_name, shardid, citus_table_type, nodename FROM citus_shards WHERE table_name = 'payment_merchants'::regclass;
    

    在输出中,payment_merchants 表的单个分片分布在群集中的每个节点上。

    table_name        | shardid | citus_table_type |                             nodename                             
    ------------------+---------+------------------+-----------------------------------------------------------------
    payment_merchants |  102072 | reference        | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_merchants |  102072 | reference        | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_merchants |  102072 | reference        | private-c.learn-cosmosdb-postgresql.postgres.database.azure.com
    
  4. 若要进行比较,请执行以下查询以查看 payment_events 表的分片分布:

    SELECT table_name, shardid, citus_table_type, nodename FROM citus_shards WHERE table_name = 'payment_events'::regclass;
    

    对于 distributed 表,每个 shardid 在结果中仅出现一次,并且每个分片仅存在于单个节点上。

    table_name     | shardid | citus_table_type |                             nodename                             
    ---------------+---------+------------------+-----------------------------------------------------------------
    payment_events |  102040 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102041 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102042 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102043 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102044 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102045 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102046 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102047 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102048 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102049 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102050 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102051 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102052 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102053 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102054 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102055 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102056 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102057 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102058 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102059 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102060 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102061 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102062 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102063 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102064 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102065 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102066 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102067 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102068 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102069 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102070 | distributed      | private-w0.learn-cosmosdb-postgresql.postgres.database.azure.com
    payment_events |  102071 | distributed      | private-w1.learn-cosmosdb-postgresql.postgres.database.azure.com
    

    祝贺你! 已使用 Azure Cosmos DB for PostgreSQL 成功创建了多节点分布式数据库。 使用元数据表和视图,你探讨了 Citus 扩展如何分布数据并为 PostgreSQL 提供附加功能。

  5. 在 Cloud Shell 中运行以下命令,断开与数据库的连接:

    \q
    

    可将 Cloud Shell 保持在打开状态,然后继续学习下一单元。