这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

逻辑模型

Pigsty 的实体概念模型:集群、实例、服务、节点——用简单的概念管理复杂的系统。

如果您只有一分钟,请记住这张图:

flowchart TB
    subgraph Cluster["🏢 集群 (Cluster): pg-test"]
        direction TB
        ClusterNote["自治业务单元,顶级命名空间"]

        subgraph Instances["💻 实例 (Instance)"]
            direction LR
            I1["pg-test-1<br/>(primary)"]
            I2["pg-test-2<br/>(replica)"]
            I3["pg-test-3<br/>(replica)"]
        end

        subgraph Nodes["🖥️ 节点 (Node)"]
            direction LR
            N1["10.10.10.11"]
            N2["10.10.10.12"]
            N3["10.10.10.13"]
        end

        subgraph Services["🌐 服务 (Service)"]
            S1["pg-test-primary:5433 → 读写请求 → pg-test-1"]
            S2["pg-test-replica:5434 → 只读请求 → pg-test-2, pg-test-3"]
            S3["pg-test-offline:5438 → 分析查询 → pg-test-3"]
        end

        Instances --> |1:1 部署| Nodes
    end

    Summary["📋 一段配置,自动生成所有标识、服务和监控标签"]

核心价值:用四个简单的概念(集群、实例、服务、节点)描述任意复杂的数据库拓扑。一次定义,处处一致:配置、监控、日志、告警自动关联。


本章内容

章节 说明 核心问题
实体关系 四种核心实体的定义与相互关系 集群、实例、服务、节点是什么?
身份标识 命名规范与衍生标识符设计 如何给数据库起名字?

为什么需要逻辑模型?

没有模型的困境

flowchart TB
    subgraph Problems["❌ 命名混乱的日常"]
        direction TB
        P1["❌ 名称随意<br/>主机名:db01、database-server、pg_prod_1<br/>实例名:postgres、postgresql、pg-instance<br/>服务名:pg、pgsql、database、5432<br/>谁也记不住,每次都要查文档"]

        P2["❌ 关联困难<br/>这个告警是哪个集群的?<br/>这条日志对应哪个实例?<br/>这个指标来自哪台机器?<br/>排查问题像破案,信息碎片化"]

        P3["❌ 扩容混乱<br/>新加的机器叫什么名字?<br/>序号从几开始?<br/>和现有命名冲突怎么办?"]
    end

Pigsty 的解决方案

flowchart TB
    subgraph Solutions["✅ 统一逻辑模型"]
        direction TB
        S1["✅ 命名一致<br/>集群名:pg-order、pg-user(语义化,全局唯一)<br/>实例名:pg-order-1、pg-order-2(集群名+序号)<br/>服务名:pg-order-primary、pg-order-replica(自动生成)<br/>规则简单,看名知义"]

        S2["✅ 自动关联<br/>监控标签:cls=pg-order, ins=pg-order-1<br/>日志标签:自动携带集群和实例信息<br/>告警通知:明确标识问题来源<br/>一个查询找到所有相关信息"]

        S3["✅ 规范扩容<br/>新实例:pg-order-4(序号递增,自动命名)<br/>新服务:pg-order-standby(自定义服务,规范后缀)<br/>无冲突,可预测"]
    end

四种核心实体

实体概览

flowchart TB
    subgraph ClusterEntity["🏢 集群 (Cluster)"]
        C1["自治的业务服务单元<br/>顶级命名空间,衍生出其他所有名称<br/>配置管理、监控告警、服务发现的基本单位<br/>例如:pg-order、pg-user、pg-meta"]
    end

    ClusterEntity --> InstanceEntity & ServiceEntity & NodeEntity

    subgraph InstanceEntity["💻 实例 (Instance)"]
        I1["单个数据库进程<br/>明确的复制角色<br/>pg-order-1"]
    end

    subgraph ServiceEntity["🌐 服务 (Service)"]
        S1["能力的命名抽象<br/>HAProxy 暴露<br/>pg-order-primary"]
    end

    subgraph NodeEntity["🖥️ 节点 (Node)"]
        N1["硬件资源抽象<br/>IP 地址标识<br/>10.10.10.11"]
    end

实体对比

实体 定义 标识方式 数量 示例
集群 一组复制关联的实例 集群名 1 pg-test
实例 单个数据库服务器 集群名-序号 1+ pg-test-1
服务 流量路由的抽象 集群名-角色 4+ pg-test-primary
节点 运行实例的机器 IP 地址 1+ 10.10.10.11

最小配置示例

只需三个参数,定义完整集群:

# pigsty.yml
pg-test:                                    # ← 集群名
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }   # ← 节点+实例
    10.10.10.12: { pg_seq: 2, pg_role: replica }   # ← 节点+实例
    10.10.10.13: { pg_seq: 3, pg_role: replica }   # ← 节点+实例
  vars:
    pg_cluster: pg-test                     # ← 必填:集群标识

三个必填参数

参数 层级 说明 约束
pg_cluster 集群 集群名称 [a-z][a-z0-9-]*,不含点号
pg_seq 实例 实例序号 集群内唯一正整数
pg_role 实例 实例角色 primary/replica/offline/delayed

自动生成的标识

从上述配置自动衍生:

实体 标识 说明
集群 pg-test 配置文件中显式定义
实例 pg-test-1 ${pg_cluster}-${pg_seq}
实例 pg-test-2 ${pg_cluster}-${pg_seq}
实例 pg-test-3 ${pg_cluster}-${pg_seq}
服务 pg-test-primary 自动创建,端口 5433
服务 pg-test-replica 自动创建,端口 5434
服务 pg-test-default 自动创建,端口 5436
服务 pg-test-offline 自动创建,端口 5438
节点 pg-test-1 主机名默认等于实例名

实例角色

角色类型

flowchart TB
    subgraph Primary["🔴 primary - 主库,有且仅有一个"]
        P1["唯一可写入的实例<br/>产生 WAL 日志,其他实例复制<br/>承载读写业务流量"]
    end

    Primary --> |复制| Replica

    subgraph Replica["🟡 replica - 从库,0到多个"]
        R1["实时同步主库数据<br/>承载只读业务流量<br/>主库故障时可提升为新主库"]
    end

    subgraph Offline["🔵 offline - 离线库,0到多个"]
        O1["不承载在线业务流量<br/>用于 ETL、数据分析、备份等<br/>避免慢查询影响线上业务"]
    end

    subgraph Delayed["🟣 delayed - 延迟库,0到多个"]
        D1["延迟复制主库数据(如延迟 1 小时)<br/>用于误操作恢复,提供时间窗口<br/>不承载在线流量"]
    end

角色对比

角色 可读 可写 承载流量 数量 典型用途
primary 读写 1 核心业务
replica 只读 0+ 读扩展
offline 离线 0+ ETL/分析
delayed 0+ 误操作恢复

服务抽象

默认服务

flowchart TB
    Client["🖥️ 客户端"] --> HAProxy

    subgraph HAProxy["🔀 HAProxy"]
        direction TB
        S1[":5433 pg-test-primary<br/>目标: 主库 (role=primary)<br/>用途: 读写业务、OLTP"]
        S2[":5434 pg-test-replica<br/>目标: 从库 (role=replica)<br/>用途: 只读查询、读扩展"]
        S3[":5436 pg-test-default<br/>目标: 主库 (直连,绕过 Pgbouncer)<br/>用途: 管理操作、DDL、大事务"]
        S4[":5438 pg-test-offline<br/>目标: 离线库 (role=offline)<br/>用途: ETL、分析、慢查询"]
    end

    subgraph Advantages["✅ 服务优势"]
        A1["应用使用服务名连接,无需知道具体实例"]
        A2["主库故障切换后,流量自动路由到新主库"]
        A3["读写分离天然实现,无需修改应用代码"]
    end

连接示例

# 读写业务(连接主库)
psql postgres://dbuser_app:password@10.10.10.11:5433/mydb

# 只读查询(负载均衡到从库)
psql postgres://dbuser_app:password@10.10.10.11:5434/mydb

# 管理操作(直连主库)
psql postgres://dbuser_dba:password@10.10.10.11:5436/mydb

# ETL 分析(连接离线库)
psql postgres://dbuser_etl:password@10.10.10.11:5438/mydb

监控集成

标签体系

监控系统自动使用身份参数作为标签:

# 指标示例
pg_up{cls="pg-test", ins="pg-test-1", ip="10.10.10.11", job="pgsql"} 1
pg_up{cls="pg-test", ins="pg-test-2", ip="10.10.10.12", job="pgsql"} 1
pg_up{cls="pg-test", ins="pg-test-3", ip="10.10.10.13", job="pgsql"} 1
标签 来源 说明
cls pg_cluster 集群名,用于集群级聚合
ins pg_cluster-pg_seq 实例名,用于实例级查询
ip 节点 IP 节点地址,用于主机关联
job 固定值 pgsqlpgrds

查询示例

# 查看集群 pg-test 的所有实例状态
pg_up{cls="pg-test"}

# 查看实例 pg-test-1 的连接数
pg_stat_activity_count{ins="pg-test-1"}

# 聚合集群总连接数
sum(pg_stat_activity_count{cls="pg-test"})

# 查看复制延迟
pg_replication_lag_seconds{cls="pg-test", ins=~"pg-test-[2-3]"}

命名最佳实践

集群命名

flowchart TB
    subgraph BasicFormat["📝 推荐格式:pg-{业务}"]
        B1["pg-order → 订单服务"]
        B2["pg-user → 用户服务"]
        B3["pg-payment → 支付服务"]
    end

    subgraph EnvFormat["🏷️ 带环境前缀:pg-{环境}-{业务}"]
        E1["pg-prod-order → 生产订单库"]
        E2["pg-stag-order → 预发订单库"]
        E3["pg-dev-order → 开发订单库"]
    end

    subgraph Rules["📋 规则约束"]
        R1["✅ 小写字母、数字、连字符"]
        R2["✅ 必须以字母开头"]
        R3["❌ 不能包含点号、下划线、大写字母"]
        R4["📐 正则:[a-z][a-z0-9-]*"]
    end

序号分配

原则 说明
不要复用 实例销毁后,序号应保留,避免混淆历史数据
预留空间 为将来扩容预留序号范围
记录映射 维护序号与用途的映射文档
从 1 开始 序号从 1 开始,表示第一个实例

接下来

深入了解逻辑模型的细节:

相关话题:

1 - 实体关系

集群、实例、服务、节点的定义与关系。

本节详细介绍 Pigsty 逻辑模型中各实体的定义、属性和相互关系。


集群(Cluster)

集群是 Pigsty 中最重要的逻辑实体,是自治的业务服务单元。

定义

  • 由一组通过复制关联的数据库实例组成
  • 有且仅有一个主库(Primary)
  • 可以有零个或多个从库(Replica)
  • 作为顶级命名空间,衍生出实例名和服务名

属性

属性 说明 示例
名称 集群的唯一标识符 pg-test
成员 组成集群的实例列表 pg-test-1, pg-test-2
服务 集群对外暴露的服务 pg-test-primary

集群类型

┌─────────────────────────────────────────────────────────────────┐
│                        标准集群                                  │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐                         │
│  │ Primary │─►│ Replica │─►│ Replica │                         │
│  └─────────┘  └─────────┘  └─────────┘                         │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                        级联复制                                  │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐                         │
│  │ Primary │─►│ Replica │─►│ Cascade │                         │
│  └─────────┘  └─────────┘  └─────────┘                         │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                        备库集群                                  │
│  ┌─────────┐      ┌─────────┐  ┌─────────┐                     │
│  │ Primary │─ ─ ─►│ Standby │─►│ Replica │                     │
│  │ (集群A) │      │ (集群B) │  │ (集群B) │                     │
│  └─────────┘      └─────────┘  └─────────┘                     │
└─────────────────────────────────────────────────────────────────┘

实例(Instance)

实例是运行在节点上的单个数据库服务器。

定义

  • 一个 PostgreSQL 进程及其数据文件
  • 由集群名和序号唯一标识
  • 具有明确的复制角色

属性

属性 说明 示例
名称 ${cluster}-${seq} pg-test-1
序号 集群内唯一的正整数 1
角色 复制拓扑中的角色 primary
节点 运行实例的节点 IP 10.10.10.11

实例角色

角色 说明 特点
primary 主库 唯一,可读写,产生 WAL
replica 从库 只读,承载在线流量
offline 离线库 只读,不承载在线流量
delayed 延迟库 延迟复制,用于数据恢复

服务(Service)

服务是集群能力的命名抽象,通过 HAProxy 对外暴露。

定义

  • 将流量路由到符合条件的实例
  • 通过端口号区分不同服务
  • 名称由集群名和角色后缀组成

默认服务

服务 端口 目标 用途
primary 5433 主库 读写业务
replica 5434 从库 只读业务
default 5436 主库 管理直连
offline 5438 离线库 ETL/分析

服务路由

┌─────────────────────────────────────────────────────────────┐
│                        HAProxy                               │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  :5433 primary                                         │  │
│  │  目标: role=primary                                    │  │
│  │  路由: → pg-test-1 (primary)                          │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  :5434 replica                                         │  │
│  │  目标: role=replica                                    │  │
│  │  路由: → pg-test-2, pg-test-3 (replicas)              │  │
│  └───────────────────────────────────────────────────────┘  │
│  ┌───────────────────────────────────────────────────────┐  │
│  │  :5438 offline                                         │  │
│  │  目标: role=offline 或 pg_offline_query=true          │  │
│  │  路由: → pg-test-3 (offline)                          │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

节点(Node)

节点是硬件资源的抽象。

定义

  • 运行 Linux 操作系统的计算资源
  • 可以是物理机、虚拟机或容器
  • 由 IP 地址唯一标识

属性

属性 说明 示例
IP 首要内网地址 10.10.10.11
主机名 节点名称 pg-test-1
集群 所属节点集群 pg-test

节点与实例

在 PGSQL 模块中,节点与实例是 1:1 部署关系:

┌─────────────────────────────────────────────────────────────┐
│                    节点 10.10.10.11                          │
│  ┌───────────────────────────────────────────────────────┐  │
│  │                  实例 pg-test-1                        │  │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  │  │
│  │  │Postgres │  │Pgbouncer│  │ HAProxy │  │ Patroni │  │  │
│  │  │ :5432   │  │ :6432   │  │ :543x   │  │ :8008   │  │  │
│  │  └─────────┘  └─────────┘  └─────────┘  └─────────┘  │  │
│  └───────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

实例可以借用节点的身份,使主机名与实例名保持一致。


关系总结

Cluster (1) ───────┬──────► Instance (N)
    │              │             │
    │              │             │ 1:1 部署
    │              │             ▼
    │              └──────► Node (N)
    │
    └──────► Service (M)
                 │
                 │ 路由到
                 ▼
            Instance (subset)
关系 说明
集群 → 实例 一个集群包含多个实例
实例 → 节点 实例与节点 1:1 部署
集群 → 服务 一个集群暴露多个服务
服务 → 实例 服务路由到符合条件的实例

2 - 身份标识

实体命名规范与身份标识符设计。

Pigsty 使用统一的身份标识系统来识别和管理实体,确保命名一致性和可追溯性。


核心身份参数

三项必填参数构成 PGSQL 的最小身份集:

参数 层级 说明 约束
pg_cluster 集群 集群名称 [a-z][a-z0-9-]*
pg_seq 实例 实例序号 唯一正整数,不可复用
pg_role 实例 实例角色 primary/replica/offline/delayed

这三个参数必须在配置清单中显式指定,Pigsty 不会提供默认值。


衍生标识

基于核心参数,Pigsty 自动生成其他实体标识:

实例名

实例名 = ${pg_cluster}-${pg_seq}

示例:

  • pg-test-1
  • pg-test-2
  • pg-meta-1

服务名

服务名 = ${pg_cluster}-${角色后缀}

默认服务:

  • pg-test-primary(读写)
  • pg-test-replica(只读)
  • pg-test-default(直连)
  • pg-test-offline(离线)

节点名

默认情况下,节点名等同于实例名:

节点名 = ${pg_cluster}-${pg_seq}

可通过 node_id_from_pg 参数控制。


命名规范

集群命名

集群名应为有效的 DNS 域名组件:

正确:pg-test, pg-meta, pg-order-db
错误:pg.test, pg_test, PG-TEST

规则

  • 只能包含小写字母、数字和连字符
  • 必须以字母开头
  • 不能包含点号、下划线或大写字母
  • 正则:[a-z][a-z0-9-]*

建议

  • 使用 模块-用途 格式:pg-orderpg-user
  • 使用 模块-环境-用途 格式:pg-prod-order

实例序号

序号是集群内实例的唯一标识:

规则:正整数,从 1 开始,唯一且不可复用

设计理念

  • 表达拓扑顺序和故障转移优先级
  • 一旦分配,即使实例销毁也不应复用
  • 用于监控标签和日志关联

实例角色

角色决定实例在复制拓扑中的位置:

角色 说明 数量
primary 主库,可读写 有且仅有 1 个
replica 从库,承载在线只读 0 到多个
offline 离线库,不承载在线流量 0 到多个
delayed 延迟库,延迟复制 0 到多个

配置示例

pg-test:
  hosts:
    10.10.10.11: { pg_seq: 1, pg_role: primary }
    10.10.10.12: { pg_seq: 2, pg_role: replica }
    10.10.10.13: { pg_seq: 3, pg_role: replica, pg_offline_query: true }
  vars:
    pg_cluster: pg-test

生成的标识

集群 序号 角色 节点 IP 实例名 主机名
pg-test 1 primary 10.10.10.11 pg-test-1 pg-test-1
pg-test 2 replica 10.10.10.12 pg-test-2 pg-test-2
pg-test 3 replica 10.10.10.13 pg-test-3 pg-test-3

服务入口

服务名 端口 目标实例
pg-test-primary 5433 pg-test-1
pg-test-replica 5434 pg-test-2, pg-test-3
pg-test-default 5436 pg-test-1
pg-test-offline 5438 pg-test-3

监控标签

监控系统使用身份参数作为指标标签:

# 实例级指标
pg_up{cls="pg-test", ins="pg-test-1", ip="10.10.10.11", job="pgsql"}

# 集群级聚合
sum(pg_stat_activity_count{cls="pg-test"})

# 特定实例
pg_replication_lag_seconds{ins="pg-test-2"}

标签定义

标签 来源 说明
cls pg_cluster 集群名
ins pg_cluster-pg_seq 实例名
ip 节点 IP 节点地址
job 固定值 pgsqlpgrds

日志标签

VictoriaLogs 使用以下标签:

日志类型 Job 名
PostgreSQL CSV 日志 postgres
pgBackRest 日志 pgbackrest
其他组件(通过 syslog) 各组件名

最佳实践

命名建议

  1. 语义化:名称应反映业务含义

    pg-order    # 订单服务数据库
    pg-user     # 用户服务数据库
    pg-meta     # 元数据库
    
  2. 环境前缀:区分不同环境

    pg-prod-order   # 生产环境
    pg-stag-order   # 预发环境
    pg-dev-order    # 开发环境
    
  3. 保持一致:整个组织使用统一的命名规范

序号分配

  1. 不要复用:实例销毁后,序号应保留
  2. 预留空间:为扩容预留序号范围
  3. 记录映射:维护序号与用途的映射文档