PostgreSQL 实体模型
Pigsty中关于PostgreSQL数据库的逻辑概念模型:ER实体关系模型。
在Pigsty中,PostgreSQL有四类核心实体:
- PGSQL集群 (Cluster),以下简称为集群
- PGSQL服务 (Service),以下简称为服务
- PGSQL实例 (Instance) ,以下简称为实例
- PGSQL节点 (Node) ,以下简称为节点
实体模型
- 集群(Cluster) 是基本自治单元,由用户指定唯一标识,表达业务含义,作为顶层命名空间。
- 集群在硬件层面上包含一系列的节点(Node),即物理机,虚机(或Pod),可以通过IP唯一标识。
- 集群在软件层面上包含一系列的实例(Instance),即软件服务器,可以通过IP:Port唯一标识。
- 集群在服务层面上包含一系列的服务(Service),即可访问的域名与端点,可以通过域名唯一标识。
实体命名规则
- 集群的命名可以使用任意满足DNS域名规范的名称,不能带点(
[a-zA-Z0-9-]+
)。 - 节点命名采用集群名称作为前缀,后接
-
,再接一个整数序号(建议从0开始分配,与k8s保持一致) - PGSQL采用独占式部署,节点与实例一一对应,因此实例命名可与节点命名一致,即
${cluster}-${seq}
的方式。 - 服务命名亦采用集群名称作为前缀,后接
-
连接服务具体内容,如primary
,replica
,offline
,standby
等。
以沙箱环境的测试数据库集群 pg-test
为例:
- 一个集群:用于测试的数据库集群名为“
pg-test
” - 两种角色:
primary
与replica
,分别是集群主库与从库。 - 三个实例:集群由三个数据库实例:
pg-test-1
,pg-test-2
,pg-test-3
组成 - 三个节点:集群部署在三个节点上:
10.10.10.11
,10.10.10.12
,10.10.10.13
上。 - 四个服务:
- 读写服务: pg-test-primary
- 只读服务: pg-test-replica
- 直连管理服务: pg-test-default
- 离线查询服务: pg-test-offline
集群
**集群(Cluster)**是基本的自治业务单元,这意味着集群能够作为一个整体组织对外提供服务。类似于k8s中Deployment的概念。注意这里的集群是软件层面的概念,不要与PG Cluster(数据库集簇,即包含多个PG Database的单个PG实例的数据目录)或Node Cluster(机器集群)混淆。
集群是管理的基本单位之一,是用于统合各类资源的组织单位。例如一个PG集群可能包括:
- 三个物理机器节点
- 一个主库实例,对外提供数据库读写服务。
- 两个从库实例,对外提供数据库只读副本服务。
- 两个对外暴露的服务:读写服务,只读副本服务。
集群命名规则
每个集群都有用户根据业务需求定义的唯一标识符,本例中定义了一个名为pg-test
的数据库集群。
集群名称,其实类似于命名空间的作用。所有隶属本集群的资源,都会使用该命名空间。
集群标识符(cls
)必须在一套环境中唯一,建议采用符合DNS标准 RFC1034 命名规则的标识符。
良好的集群名称应当仅使用小写字母,数字,以及 减号连字符(hyphen)-
,且只使用字母启头。这样集群中所有对象都可以该标识符作为自己标识符的前缀,严格约束的标识符可以应用于更广泛地场景。
cluster_name := [a-z][a-z0-9-]*
集群命名中不应该包括点(dot).
,之所以强调不要在集群名称中用点,是因为有一种流行的命名方式便是采用点号分隔的层次标识符,例如com.foo.bar
。这种命名方式虽然简洁名快,但用户给出的名字中域名层次数目不可控。如果集群需要与外部系统交互,而外部系统对于命名有约束,这样的名字就会带来麻烦。最直观的例子是Kubernetes中的Pod,Pod的命名规则中不允许出现.
。
集群命名的内涵,建议采用-
分隔的两段式,三段式名称,例如:
<集群类型>-<业务>-<业务线>
典型的集群名称包括:pg-meta
, pg-test-fin
, pg-infrastructure-biz
实例
实例(Instance) 指带一个具体的数据库服务器,它可以是单个进程,也可能是共享命运的一组进程,也可以是一个Pod中几个紧密关联的容器。实例的关键要素在于:
- 可以通过实例标识(
ins
)符唯一标识 - 具有处理请求的能力(而不管接收请求的究竟是数据库,还是连接池或负载均衡器)
例如,我们可以把一个Postgres进程,为之服务的独占Pgbouncer连接池,PgExporter监控组件,高可用组件,管理Agent看作一个提供服务的整体,视为一个数据库实例,使用同样的标识符指称。
实例命名规则
实例隶属于集群,每个实例在集群范围内都有着自己的唯一标识用于区分。实例标识符ins
建议采用与Kubernetes Pod一致的命名规则:即集群名称连以从0/1开始递增分配的整数序号<cls>-<seq>
。
Pigsty默认使用从1开始的自增序列号依次为集群中的新数据库实例命名,例如,数据库集群pg-test
有三个数据库实例,那么这三个实例就可以依次命名为:pg-test-1
, pg-test-2
和pg-test-3
。
实例名ins
一旦分配即不可变,该实例将在整个集群的生命周期中使用此标识符。
此外,采用独占节点部署模式时,数据库实例与机器节点可以互相使用对方的标识符。即我们也可用数据库实例标识ins
来唯一指称一个机器节点。
节点
节点 (Node) 是对硬件资源的一种抽象,通常指代一台工作机器,无论是物理机(bare metal)还是虚拟机(vm),或者是Kubernetes 中的Pod。
注意 Kubernetes 中Node是硬件资源的抽象,但在实际管理使用上,这里Node概念类似于Kubernetes中Pod的概念。
节点的关键特征是:
- 节点是硬件资源的抽象,可以运行软件服务,部署数据库实例
- 节点可以使用IP地址作为唯一标识符
节点命名规则
Pigsty使用 ip
地址作为节点唯一标识符,如果机器有多个IP地址,则以配置清单中指定的,实际访问使用的IP地址为准。为便于管理,节点应当拥有一个人类可读的充满意义的名称作为节点的主机名。主机名nodename
,数据库实例标识ins
,节点标识ip
三者在Pigsty中彼此一一对应,可交叉混用做数据库实例、机器节点、HAProxy负载均衡器的标识符。
节点的命名与数据库实例一致,在整个集群的生命周期中保持不变,便于监控与管理。
服务
服务 (Service) 是对软件服务(例如Postgres,Redis)的一种命名抽象(named abstraction)。服务可以有各种各样的实现,但其的关键要素在于:
- 可以寻址访问的服务名称,用于对外提供接入,例如:
- 一个DNS域名(
pg-test-primary
) - 一个Nginx/Haproxy Port
- 一个DNS域名(
- 服务流量路由解析与负载均衡机制,用于决定哪个实例负责处理请求,例如:
- DNS L7:DNS解析记录
- HTTP Proxy: Nginx/Ingress L7:Nginx Upstream配置
- TCP Proxy: Haproxy L4:Haproxy Backend配置
- Kubernetes:Ingress: Pod Selector。
- 服务也需要决定由哪个组件来处理请求:连接池,或是数据库本身。
更多关于服务的介绍,请参考服务一章。
服务命名规则
服务标识 (svc
) 由两部分组成:作为命名空间的 cls
, 与服务承载的角色(role
)
在PostgreSQL数据库集群中,实例可能有不同的身份:集群领导者(主库),普通从库,同步从库,离线从库,延迟从库,不同的实例可能会提供不同的服务;同时直连数据库与通过连接池中间件访问数据库也属于性质不同的服务。通常我们会使用服务目标实例的身份角色来标识服务,例如在数据库集群pg-test
中:
- 指向 主库连接池(
primary
)角色实例的服务,叫做pg-test-primary
- 指向 从库连接池(
replica
)角色实例的服务,叫做pg-test-replica
- 指向 离线从库数据库(
offline
)的服务,叫做pg-test-offline
- 指向 同步复制从库(
standby
)的服务,叫做pg-test-standby
请注意,服务并不够成对实例的划分,同一个服务可以指向集群内多个不同的实例,然而同一个实例也可以承接来自不同服务的请求。例如,角色为 standby
的同步从库既可以承接来自 pg-test-standby
的同步读取请求,也可以承接来自 pg-test-replica
的普通读取请求。
最后修改 2022-06-06: fix offline links (cd122f7)