分布式

更新时间:
复制为 MD 格式

PolarDB PostgreSQL分布式版集群是一款基于集中式PolarDB PostgreSQL集群打造的分布式数据库,采用CN/DN的双层架构,实现计算与存储分离的分布式扩展能力。同时支持集中式PolarDB PostgreSQL集群的现有能力,充分满足企业级业务在性能和可靠性方面的多样化需求。

技术架构

PolarDB PostgreSQL分布式版包含两类核心节点:

  • 计算节点(Compute Nodes,CN):作为集群的访问入口,负责解析SQL、制定分布式查询计划及管理元数据。

  • 数据节点(Data Nodes,DN):负责存储表的物理数据分片。

每个计算或数据节点本身都是一个高可用的PolarDB PostgreSQL集群,内置了读写(RW)节点、只读(RO)节点和分布式存储(PolarStore),确保了组件级别的可靠性。

image

架构优势

  • 在线水平扩展:通过在线增加节点来扩展计算与存储能力,突破单机瓶颈,支持PB级海量数据和高并发业务。

  • 灵活的扩展方式:节点采用共享存储(Share Storage)架构,支持通过增加节点(Scale Out)或提升节点规格(Scale Up)两种方式进行扩展。

  • 高可用与低成本:采用ParallelRaft复制协议的三副本分布式存储(PolarStore)确保了数据的高可用性,而费用仅按单副本计算。存储空间根据实际使用情况进行收费,无需手动调整容量。

  • 高性能:基于分布式文件系统(Polar File System, 简称PolarFS)进行深度IO优化,如并行刷脏、批量读写以及表大小缓存等,提供超高IOPS。

  • 秒级备份恢复:支持秒级创建备份,并提供按时间点恢复(PITR)等多种数据恢复方式。

分布式开发模式

PolarDB PostgreSQL分布式版上开发,核心是规划数据的分布方式。您可以根据业务场景选择以下两种模式:

  • 水平拆分(Horizontal Splitting):将单张大表的数据行,按某一列(分布列)的哈希值分散到多个数据节点(DN)上。此模式适用于解决单表数据量过大导致的性能问题,例如用户表、订单表等。为达到最佳性能,查询时应尽量携带分布列作为过滤条件。

    • 分布表(Distributed Table):在逻辑上是一张完整的表,但其数据被物理地拆分存储在多个DN上。例如,应用访问的是sensors_data表,而数据实际存储在sensors_data_shard1sensors_data_shard2等分片中。

    • 分布列(Distribution Column):创建分布表时用于计算哈希值以决定数据分布的列,例如sensor_id

    • 复制表(Reference Table):一种特殊的表,它的全量数据在每个DN上都存有一份完整的副本。它通常用于存储数据量小且需要与大型分布表频繁关联的维度表(如国家、配置信息等),可将跨节点JOIN优化为本地JOIN,显著提升查询性能。

    • 分布式事务:当单个操作(显式BEGIN ... COMMIT/ROLLBACK或隐式事务)需要修改分布在多个DN上的数据时,系统会自动启用分布式事务以保证数据的一致性(ACID)。

      说明

      对复制表的任何修改都会触发分布式事务。

    • 主/从计算节点(Primary/Follower CN):所有CN节点均可处理查询请求。但为保证元数据的一致性,DDL操作(如CREATE TABLE)只能由主CN上执行,变更结果会自动同步至所有其他节点(CN节点与DN节点)。

  • 垂直拆分(Vertical Splitting):将不同业务模块的表分别部署到不同的数据节点(DN)。此模式适用于按业务隔离资源,例如将高频交易业务与后台报表业务的表存放在不同节点,避免相互影响。该模式对应用侵入性极小,因为计算节点(CN)对上层屏蔽了底层细节,应用依然可以像访问单机数据库一样访问所有表。

image

开发指南

  1. 准备工作:

    1. 创建数据库账号

      您可以前往PolarDB控制台,在集群列表中单击目标集群ID进入集群详情页。在配置与管理 > 账号管理创建数据库账号image

      说明

      数据库账号类型分为高权限账号普通账号,这两种账号的权限存在差异。您可以根据实际业务需求创建相关的数据库账号。

    2. 设置集群白名单

      您可以前往PolarDB控制台,在集群列表中单击目标集群ID进入集群详情页。在配置与管理 > 集群白名单中添加IP白名单安全组image

      说明
      • 如果您是使用ECS访问PolarDB,并且ECSPolarDB位于同一VPC内,您可以选择将ECS的内网IP地址添加至新的IP白名单分组,或将ECS所在的安全组添加至集群白名单中。

      • 如果您是使用ECS访问PolarDB,但ECSPolarDB不在同一VPC内,您可以选择将ECS的公网IP地址添加至新的IP白名单分组,或将ECS所在的安全组添加至集群白名单中。

      • 如果您是在本地环境中访问PolarDB,请将您本地环境的公网IP地址添加至新的IP白名单分组中。

        本地环境的公网IP地址获取方法如下:Linux操作系统:打开终端,输入curl ifconfig.me命令后回车。

        • Windows操作系统:打开命令提示符,输入curl ip.me命令后回车。

        • macOS操作系统:打开终端,输入curl ifconfig.me命令后回车。

        若您的本地网络环境存在代理等情况,以上方式获取的IP可能并非您的真实公网IP。您可以将IP0.0.0.0/0添加至PolarDB集群白名单中,成功连接集群后,执行SELECT pid,usename,datname,client_addr,state,query FROM pg_stat_activity WHERE state = 'active';命令获取真实公网IP地址,并将其加入到集群白名单中。随后删除白名单中的IP0.0.0.0/0

        image

      • IP0.0.0.0/0表示允许所有的访问源访问集群,将其设置在集群白名单中存在极大的风险,如非必要,切勿将其添加至白名单。

    3. 获取数据库连接地址与端口

      您可以前往PolarDB控制台,在集群列表中单击目标集群ID进入集群详情页。在数据库连接区域中获取数据库连接地址image

      说明
      • PolarDB PostgreSQL分布式版集群默认仅包含主地址,且默认端口号为5432。

      • 请根据您的访问环境选择私网地址公网地址

        • 如果您是使用ECS访问PolarDB,并且ECSPolarDB位于同一VPC内,请选择私网地址

        • 如果您是在本地环境中访问PolarDB,请选择公网地址。公网地址单击请点击申请即可。

      • 公网地址即互联网,通过公网地址访问将无法实现PolarDB集群的最佳性能。

      • 暂不支持使用虚拟主机和轻量应用服务器使用私网地址连接PolarDB集群。

  2. 连接分布式版集群

    使用DMS连接集群

    DMS是阿里云提供的图形化的数据管理工具,它是一种集数据管理、结构管理、用户授权、安全审计、数据趋势、数据追踪、BI图表、性能与优化和服务器管理于一体的数据管理服务。您无需借助其他工具,即可直接在DMS上管理您的PolarDB集群。

    1. 前往PolarDB控制台,在集群列表中单击目标集群ID进入集群详情页。在页面右上角单击登录数据库image

    2. 在弹出的对话框中,输入集群中创建的数据库账号数据库密码,单击登录image

    3. 登录后,您可以在左侧导航栏的数据库实例 > 已登录实例列表中查看到所登录的PolarDB集群,并进行相应的管理操作。image

    使用客户端连接集群

    您可以使用任何通用的客户端连接PolarDB集群。此处pgAdmin 4 v9.0版本为例,其它客户端的操作类似。

    1. 下载并安装pgAdmin 4客户端。

    2. 打开pgAdmin 4客户端,右键单击Servers,选择Register > Server...image

    3. General页设置连接名称,Connection页设置要连接的集群信息,并单击Saveimage

      image

      参数

      说明

      Host name/address

      PolarDB集群的数据库连接地址与端口

      • 如果您是使用ECS访问PolarDB,并且ECSPolarDB位于同一VPC内,请选择私网地址与端口。

      • 如果您是在本地环境中访问PolarDB,请选择公网地址与端口。

      • 默认端口号为5432

      Port

      Username

      PolarDB集群的数据库账号和密码

      Password

    4. 查看连接结果。若连接信息无误,会出现如下界面,则表示连接成功。image

      说明

      postgres是默认的系统数据库,请勿在该数据库中进行任何操作。

    使用命令行连接集群

    您可以前往PostgreSQL官网网站下载并使用psql工具连接PolarDB数据库集群。您也可以使用PolarDB提供的PolarDB-Tools工具包中的psql工具连接PolarDB数据库集群

    说明

    语法

    psql -h <host> -p <port> -U <username> -d <dbname>

    参数

    描述

    host

    PolarDB集群的数据库连接地址与端口

    • 如果您是使用ECS访问PolarDB,并且ECSPolarDB位于同一VPC内,请选择私网地址与端口。

    • 如果您是在本地环境中访问PolarDB,请选择公网地址与端口。

    • 默认端口号为5432

    port

    username

    PolarDB集群的数据库账号

    dbname

    需要管理维护的数据库

    示例

    psql -h pc-xxx.rwlb.rds.aliyuncs.com -p 5432 -U testusername -d postgres

    使用应用程序连接集群

    连接PolarDB PostgreSQL集群的方式与连接其他PostgreSQL数据库的方式一样,仅需将数据库连接地址、端口、账号及密码等进行替换即可。以下为您列举部分开发语言如何通过应用程序访问PolarDB数据库:

    Java

    此处以Maven项目为例,使用PostgreSQL JDBC驱动连接PolarDB PostgreSQL集群。

    1. 首先,您需要在pom.xml文件中添加PostgreSQL JDBC驱动的依赖,代码示例:

      <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.2.18</version>
      </dependency>
    2. 连接集群。请将参数<HOST><PORT><USER><PASSWORD><DATABASE><YOUR_TABLE_NAME><YOUR_TABLE_COLUMN_NAME>进行替换。

      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.ResultSet;
      import java.sql.Statement;
      
      public class PolarDBConnection {
          public static void main(String[] args) {
              // 数据库URL, 用户名, 密码
              String url = "jdbc:postgresql://<HOST>:<PORT>/<DATABASE>";
              String user = "<USER>";
              String password = "<PASSWORD>";
      
              try {
                  // 加载JDBC驱动
                  Class.forName("org.postgresql.Driver");
                  
                  // 建立连接
                  Connection conn = DriverManager.getConnection(url, user, password);
                  
                  // 创建Statement对象
                  Statement stmt = conn.createStatement();
                  
                  // 执行SQL查询
                  ResultSet rs = stmt.executeQuery("SELECT * FROM <YOUR_TABLE_NAME>");
                  
                  // 处理结果集
                  while (rs.next()) {
                      System.out.println(rs.getString("<YOUR_TABLE_COLUMN_NAME>"));
                  }
                  
                  // 关闭资源
                  rs.close();
                  stmt.close();
                  conn.close();
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      }

    Python

    此处以Python3为例,使用psycopg2库连接PolarDB PostgreSQL集群。

    1. 首先,您需要安装psycopg2库。如果您还没有安装,可以通过以下命令进行安装:

      pip3 install psycopg2-binary
    2. 连接集群。请将参数<HOST><PORT><USER><PASSWORD><DATABASE><YOUR_TABLE_NAME>进行替换。

      import psycopg2
      
      try:
          # 连接参数
          conn = psycopg2.connect(
              host="<HOST>",  # 数据库主机地址
              database="<DATABASE>",  # 数据库名称
              user="<USER>",  # 用户名
              password="<PASSWORD>",  # 密码
              port="<PORT>"  # 端口
          )
      
          # 创建游标对象
          cursor = conn.cursor()
      
          # 执行查询
          cursor.execute("SELECT * FROM <YOUR_TABLE_NAME>")
      
          # 获取所有结果
          records = cursor.fetchall()
          for record in records:
              print(record)
              
      except Exception as e:
          print("错误:", e)
      finally:
          # 关闭连接
          if 'cursor' in locals():
              cursor.close()
          if 'conn' in locals():
              conn.close()

    Go

    此处以go1.23.0为例,使用database/sql包和lib/pq驱动来连接PolarDB PostgreSQL集群。

    1. 首先,您需要安装lib/pq驱动。您可以通过以下命令进行安装:

      go get -u github.com/lib/pq
    2. 连接集群。请将参数<HOST><PORT><USER><PASSWORD><DATABASE><YOUR_TABLE_NAME>进行替换。

      package main
      
      import (
          "database/sql"
          "fmt"
          "log"
      
          _ "github.com/lib/pq" // 初始化驱动
      )
      
      func main() {
          // 连接字符串格式
          connStr := "user=<USER> password=<PASSWORD> dbname=<DATABASE> host=<HOST> port=<PORT> sslmode=disable"
      
          // 打开数据库连接
          db, err := sql.Open("postgres", connStr)
          if err != nil {
              log.Fatal(err)
          }
          defer db.Close() // 程序退出前关闭连接
      
          // 测试连接是否成功
          err = db.Ping()
          if err != nil {
              log.Fatal(err)
          }
          fmt.Println("Connected to PostgreSQL!")
      
          // 执行查询示例
          rows, err := db.Query("SELECT * FROM <YOUR_TABLE_NAME>")
          if err != nil {
              log.Fatal(err)
          }
          defer rows.Close()
      }
      
  3. 创建与管理分布表和复制表

  4. 分布表DML操作说明

  5. 其他: