分布式 PostgreSQL - Citus 架构及概念

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 分布式 PostgreSQL - Citus 架构及概念

节点



Citus 是一种 PostgreSQL 扩展,它允许数据库服务器(称为节点)在“无共享(shared nothing)”架构中相互协调。这些节点形成一个集群,允许 PostgreSQL 保存比单台计算机上更多的数据和使用更多的 CPU 内核。这种架构还允许通过简单地向集群添加更多节点来扩容数据库。

  • 扩展


Coordinator 与 Worker


每个 cluster 都有一个称为 coordinator(协调器) 的特殊节点(其他节点称为 worker 节点)。应用程序将它们的查询发送到 coordinator 节点,coordinator 节点将其转发给相关的 worker 并累积结果。


对于每个查询,coordinator 要么将其路由到单个 worker 节点,要么将其并行化到多个节点,具体取决于所需数据是位于单个节点上还是多个节点上。coordinator 通过查阅其元数据表知道如何做到这一点。这些 Citus 特定表跟踪 worker 节点的 DNS 名称和运行状况,以及跨节点数据的分布情况。


分布式数据



表类型


Citus 集群中有三种类型的表,每种表都以不同方式存储在节点中,并且用于不同的目的。


类型 1:分布式表


第一种类型,也是最常见的,是分布式表。对于 SQL 语句而言,它们看似是普通的表,但在 worker 节点之间水平分区。


image.png


这里 table 的行存储在 worker 的表 table_1001table_1002 等中。组件 worker 表称为分片(shards)

分布列


Citus 使用使用分片算法将行分配到分片。基于表列(称为分布列(distribution column))的值执行分配,此分配具有确定性。集群管理员在分布表时必须指定此列。做出正确的选择,这一点对于性能和功能有重要影响。


类型 2:引用表


引用表 是一种分布式表,其全部内容都集中到单个分片中,并在每个 worker 上复制。因此,对任何 worker 的查询都可以在本地访问 引用 信息,无需从另一个节点请求行,因此也不会产生此类网络开销。引用表没有分布列,因为无需区分每行的各个分片。


引用表 通常很小,用于存储与在任何工作节点上运行的查询相关的数据。例如,订单状态或产品类别等枚举值。


当与 引用表 交互时,我们会自动对事务执行两阶段提交 (2PC)。这意味着 Citus 确保您的数据始终处于一致状态,无论您是在写入修改还是删除它。


  • 2PC


类型 3:本地表


当您使用 Citus 时,您连接并与之交互的 coordinator 节点是安装了 Citus 扩展的常规 PostgreSQL 数据库。因此,您可以创建普通表并选择不对其进行分片。这对于不参与连接查询的小型管理表很有用。一个示例是用于应用程序登录和身份验证的用户表。


创建标准 PostgreSQL 表很容易,因为它是默认值。这是你运行 CREATE TABLE 时得到的。在几乎每个 Citus 部署中,我们都会看到标准 PostgreSQL 表与 distributedreference 表共存。事实上,如前所述,Citus 本身使用本地表来保存集群元数据。


Shards


上一节将分片描述为在 worker 节点内的较小表中包含分布式表的行的子集。本节详细介绍了技术细节。


协调器上的 pg_dist_shard 元数据表包含系统中每个分布式表的每个分片的行。该行与分片 ID 相匹配,分片 ID 的范围是一组哈希整数 (shardminvalue, shardmaxvalue)。


SELECT * from pg_dist_shard;
 logicalrelid  | shardid | shardstorage | shardminvalue | shardmaxvalue
---------------+---------+--------------+---------------+---------------
 github_events |  102026 | t            | 268435456     | 402653183
 github_events |  102027 | t            | 402653184     | 536870911
 github_events |  102028 | t            | 536870912     | 671088639
 github_events |  102029 | t            | 671088640     | 805306367
 (4 rows)


如果 coordinator 节点要确定哪个分片包含 github_events 行,它将对行中分布列的值执行哈希算法。然后此节点检查哪个分片的范围包含此哈希值。定义范围后,哈希函数的image(图像)就是两者的并查。


分片放置


假设分片 102027 与相应的行关联。在某个 worker 中的 github_events_102027 表中读取或写入此行。是哪个 worker?这完全由元数据表确定。分片映射到 worker 的过程称为分片放置(shard placement)


coordinator 节点将查询重写为引用特定表(例如 github_events_102027)的片段,并对相应 worker 运行这些片段。下面的查询示例在后台运行,旨在查找分片 ID102027 的节点。


SELECT
    shardid,
    node.nodename,
    node.nodeport
FROM pg_dist_placement placement
JOIN pg_dist_node node
  ON placement.groupid = node.groupid
 AND node.noderole = 'primary'::noderole
WHERE shardid = 102027;


┌─────────┬───────────┬──────────┐
│ shardid │ nodename  │ nodeport │
├─────────┼───────────┼──────────┤
│  102027 │ localhost │     5433 │
└─────────┴───────────┴──────────┘


github_events 示例中,有四个分片。每个表的分片数量在其在集群中分布时是可配置的。


最后请注意,Citus 允许复制分片以防止数据丢失。有两种复制“模式”:Citus 复制和流复制。前者创建额外的备份分片放置并针对所有更新它们的所有它们运行查询。后者效率更高,利用 PostgreSQL 的流式复制将每个节点的整个数据库备份到一个 follower 数据库。这是透明的,不需要 Citus 元数据表的参与。


共置


由于可以根据需要将分片及其副本放置在节点上,因此将包含相关表的相关行的分片放在同一节点上是有意义的。这样,它们之间的连接查询可以避免通过网络发送尽可能多的信息,并且可以在单个 Citus 节点内执行。


一个示例是包含商店、产品和购买的数据库。如果所有三个表都包含 - 并且由 - store_id 列分布,那么限制在单个存储中的所有查询都可以在单个工作节点上高效运行。即使查询涉及这些表的任意组合也是如此。


并行性


跨多台机器分散查询允许一次运行更多查询,并允许通过向集群添加新机器来扩展处理速度。此外,如上一节所述,将单个查询拆分为片段可以提高专用于它的处理能力。后一种情况实现了最大的并行性,这意味着 CPU 内核的利用率。


读取或影响均匀分布在多个节点上的分片的查询能够以“实时”速度运行。请注意,查询的结果仍然需要通过协调器节点传回,因此当最终结果紧凑时(例如计数和描述性统计等聚合函数),加速效果最为明显。


查询执行


在执行多分片查询时,Citus 必须平衡并行性的收益与数据库连接的开销(网络延迟和工作节点资源使用)。要配置 Citus 的查询执行以获得最佳的数据库工作负载结果,它有助于了解 Citus 如何管理和保存协调节点和工作节点之间的数据库连接。


Citus 将每个传入的多分片查询会话转换为称为任务的每个分片查询。它将任务排队,并在能够获得与相关工作节点的连接时运行它们。对于分布式表 foobar 的查询,下面是连接管理图:


image.png


coordinator 节点为每个会话都有一个连接池。每个查询(例如图中的 SELECT * FROM foo)仅限于为每个 worker 的任务打开最多 citus.max_adaptive_executor_pool_size(整数)个同时连接。该设置可在会话级别进行配置,以进行优先级管理。


在同一连接上按顺序执行短任务比为它们并行建立新连接更快。另一方面,长时间运行的任务受益于更直接的并行性。


为了平衡短任务长任务的需求,Citus 使用 citus.executor_slow_start_interval(整数)。该设置指定多分片查询中任务的连接尝试之间的延迟。当查询首先对任务进行排队时,这些任务只能获取一个连接。在每个有待处理连接的时间间隔结束时,Citus 会增加它将打开的同时连接数。通过将 GUC 设置为 0,可以完全禁用慢启动行为。


当任务完成使用连接时,会话池将保持连接打开以供以后使用。缓存连接避免了 coordinatorworker 之间重新建立连接的开销。但是,每个池一次打开的空闲连接不超过 citus.max_cached_conns_per_worker(整数)个,以限制 worker 中空闲连接资源的使用。


最后,设置 citus.max_shared_pool_size (integer) 充当故障保险。它限制了所有任务之间每个 worker 的总连接数。


查询执行


Citus 简介,将 Postgres 转换为分布式数据库

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
3月前
|
存储 分布式计算 大数据
大数据-169 Elasticsearch 索引使用 与 架构概念 增删改查
大数据-169 Elasticsearch 索引使用 与 架构概念 增删改查
79 3
|
8天前
|
存储 Prometheus Cloud Native
分布式系统架构6:链路追踪
本文深入探讨了分布式系统中的链路追踪理论,涵盖追踪与跨度的概念、追踪系统的模块划分及数据收集的三种方式。链路追踪旨在解决复杂分布式系统中请求流转路径不清晰的问题,帮助快速定位故障和性能瓶颈。文中介绍了基于日志、服务探针和边车代理的数据收集方法,并简述了OpenTracing、OpenCensus和OpenTelemetry等链路追踪协议的发展历程及其特点。通过理解这些概念,可以更好地掌握开源链路追踪框架的使用。
61 41
|
18天前
|
设计模式 存储 算法
分布式系统架构5:限流设计模式
本文是小卷关于分布式系统架构学习的第5篇,重点介绍限流器及4种常见的限流设计模式:流量计数器、滑动窗口、漏桶和令牌桶。限流旨在保护系统免受超额流量冲击,确保资源合理分配。流量计数器简单但存在边界问题;滑动窗口更精细地控制流量;漏桶平滑流量但配置复杂;令牌桶允许突发流量。此外,还简要介绍了分布式限流的概念及实现方式,强调了限流的代价与收益权衡。
60 11
|
20天前
|
设计模式 监控 Java
分布式系统架构4:容错设计模式
这是小卷对分布式系统架构学习的第4篇文章,重点介绍了三种常见的容错设计模式:断路器模式、舱壁隔离模式和重试模式。断路器模式防止服务故障蔓延,舱壁隔离模式通过资源隔离避免全局影响,重试模式提升短期故障下的调用成功率。文章还对比了这些模式的优缺点及适用场景,并解释了服务熔断与服务降级的区别。尽管技术文章阅读量不高,但小卷坚持每日更新以促进个人成长。
45 11
|
22天前
|
消息中间件 存储 安全
分布式系统架构3:服务容错
分布式系统因其复杂性,故障几乎是必然的。那么如何让系统在不可避免的故障中依然保持稳定?本文详细介绍了分布式架构中7种核心的服务容错策略,包括故障转移、快速失败、安全失败等,以及它们在实际业务场景中的应用。无论是支付场景的快速失败,还是日志采集的安全失败,每种策略都有自己的适用领域和优缺点。此外,文章还为技术面试提供了解题思路,助你在关键时刻脱颖而出。掌握这些策略,不仅能提升系统健壮性,还能让你的技术栈更上一层楼!快来深入学习,走向架构师之路吧!
55 11
|
24天前
|
自然语言处理 负载均衡 Kubernetes
分布式系统架构2:服务发现
服务发现是分布式系统中服务实例动态注册和发现机制,确保服务间通信。主要由注册中心和服务消费者组成,支持客户端和服务端两种发现模式。注册中心需具备高可用性,常用框架有Eureka、Zookeeper、Consul等。服务注册方式包括主动注册和被动注册,核心流程涵盖服务注册、心跳检测、服务发现、服务调用和注销。
65 12
|
1月前
|
消息中间件 架构师 数据库
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
45岁资深架构师尼恩分享了一篇关于分布式事务的文章,详细解析了如何在10Wqps高并发场景下实现分布式事务。文章从传统单体架构到微服务架构下分布式事务的需求背景出发,介绍了Seata这一开源分布式事务解决方案及其AT和TCC两种模式。随后,文章深入探讨了经典ebay本地消息表方案,以及如何使用RocketMQ消息队列替代数据库表来提高性能和可靠性。尼恩还分享了如何结合延迟消息进行事务数据的定时对账,确保最终一致性。最后,尼恩强调了高端面试中需要准备“高大上”的答案,并提供了多个技术领域的深度学习资料,帮助读者提升技术水平,顺利通过面试。
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
|
1月前
|
存储 算法 安全
分布式系统架构1:共识算法Paxos
本文介绍了分布式系统中实现数据一致性的重要算法——Paxos及其改进版Multi Paxos。Paxos算法由Leslie Lamport提出,旨在解决分布式环境下的共识问题,通过提案节点、决策节点和记录节点的协作,确保数据在多台机器间的一致性和可用性。Multi Paxos通过引入主节点选举机制,优化了基本Paxos的效率,减少了网络通信次数,提高了系统的性能和可靠性。文中还简要讨论了数据复制的安全性和一致性保障措施。
43 1
|
2月前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
76 8
|
2月前
|
关系型数据库 分布式数据库 数据库
PostgreSQL+Citus分布式数据库
PostgreSQL+Citus分布式数据库
75 15
下一篇
开通oss服务