暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

关于Citus的10个为什么

呆呆的私房菜 2025-03-27
155
    Whoami5年+金融、政府、医疗领域工作经验的DBA
    Certificate:PGCM、OCP、YCP
    Skill:Oracle、Mysql、PostgreSQL、国产数据库
    Platform:CSDN、墨天轮、公众号(呆呆的私房菜)
    今天给客户做PostgreSQL Citus分布式架构技术培训,故本文分享下关于Citus的FAQ内容吧。

    01

    概述
    • Citus是一个开源的PostgreSQL扩展程序,旨在将原生的PostgreSQL数据库转换成一个分布式数据库。它显著提升了数据库处理大规模数据集的能力,尤其在复杂查询和高并发场景下表现突出。
    • Citus不仅保留了PostgreSQL的强大功能特性,如事务处理、ACID特性等,还增加了分布式计算所需的场景,例如数据分区、负载均衡和故障恢复机制。

    02

    Citus FAQ
    • Q1:分布式表上可以创建主键吗?
    • 目前,Citus仅在分布式列是主键的一部分时才允许添加主键约束,这确保了约束只需要在一个分片中检查以确保唯一性。

    • Q2:如何向现有的Citus集群中添加节点?
    • 在向现有集群中添加节点后,新节点将不包含任何数据(分片),新创建的分片才会分配到该节点上。因此需要将现有分片从旧节点重新平衡到新节点上。
      -- 添加新 Worker 节点(假设新节点 IP 为 10.0.0.4,端口 5432)
      SELECT master_add_node('10.0.0.4'5432);
      -- 查看所有 Worker 节点
      SELECT * FROM master_get_active_worker_nodes();
      -- 检查节点元数据
      SELECT * FROM pg_dist_node;


      -- 设置分片迁移阈值(默认 0.5,即节点间负载差异超过 50% 时触发迁移)
      SET citus.shard_rebalancer.log_verbose = on;
      -- 对所有表执行分片再平衡
      SELECT rebalance_table_shards();
      -- 或针对特定表(如 orders)
      SELECT rebalance_table_shards('orders');


      -- 查看正在迁移的分片
      SELECT * FROM citus_shard_moves;
      -- 查看历史任务
      SELECT * FROM citus_move_shard_placement_events;


      -- 查看所有分片的位置和大小
      SELECT 
          shardid, 
          nodename, 
          nodeport,
          pg_size_pretty(shard_size) AS size 
      FROM citus_shards 
      WHERE table_name = 'orders'::regclass;

      • Q3:如何预防Worker节点故障?
      • 通过流复制方式创建Worker节点的备用节点。

      • Q4:如何预防Coordinator节点故障?
      • 通过流复制方式创建Coordinator节点的备用节点。

      • Q5:Citus支持所有PostgreSQL功能吗?
      • 由于Citus通过扩展的方式实现分布式功能,因此它使用了标准的PostgreSQL SQL 结构。绝大多数的查询都支持。存在的限制如下:
        常规限制:
        1. 不支持rule system;
        2. 不支持INSERT INTO...SELECT;
        3. 不支持多级分区表;
        4. update查询中涉及的函数不能声明为volatile;
        5. update查询使用stable函数要注意参数不能直接引用表的列;
        6. 不支持对视图进行修改操作。


        跨节点查询:
        1. 仅支持单分片执行 select ... for update 查询;
        2. 仅支持单分片执行 tablesample 查询;
        3. 相关子查询仅支持基于分布列的关联;
        4. 分布式表外连接仅支持分布列;
        5. 递归CTE仅支持单分片查询;
        6. 分组集仅支持单分片查询;
        7. 仅常规表、外部分区表或分区表可被分布
        8. merge 命令如下表类型的组合
          基于schema的分片
          1. 分布式schema之间不支持外键;
          2. 分布式schema之间的join受跨节点查询限制;
          3. 无法通过单条SQL创建分布式schema和table

          • Q6:如何选择hash分区的分片数量?
          • 在多租户SaaS数据库中,建议在32-128个分片间选择。对于小于·100GB的小型工作负载场景,建议可以从32个分片开始;对于大型工作负载,建议选择64-128个分片。
          • 在实时分析用例中,分片数量应与工作节点上的cpu数相关。初始化创建分片时,建议配置为cpu核数的2-4倍。

          • Q7:哈希分区表的分片数量能更改吗?
          • 可以使用 alter_distributed_table 函数更改分布式表的分片数量。

          • Q8:如何在citus集群中创建数据库用户、函数、扩展?
          • create role/user、create database、alter...set schema、alter table all in tablespace、create table在协调节点上创建不会同步到工作节点。
            -- citus提供了一个在所有工作节点上执行查询的函数
            SELECT run_command_on_workers($cmd$
              /* the command to run */
              CREATE ROLE ...
            $cmd$);

            • Q9:如果woker节点的ip变更怎么办?
            • 可以使用 citus_update_node 函数进行更新。
              -- update worker node metadata on the coordinator
              -- (remember to replace 'old-address' and 'new-address'
              --  with the actual values for your situation)
              select citus_update_node(nodeid, 'new-address', nodeport)
                from pg_dist_node
               where nodename = 'old-address';

              • Q10:可以基于多个键做分片吗?
              • 不支持通过多个列作为分布列对表进行分片。这种需求的常见场景是时间序列数据。对于这种情况,我们建议在非时间列上使用哈希分区,并将其与PostgreSQL在时间列上的分区相结合。



              本文内容就到这啦,相信读完本文可以给你带来关于citus的一些新的认识~希望本篇内容能给你带来帮助。我们下篇再见!

              点击上方公众号,关注我吧!

              文章转载自呆呆的私房菜,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论