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

PolarDB-PG 社区版部署测试体验

2176
前面文章分享了 PolarDB-X 社区版部署测试体验,本文继续分享 PolarDB-PG 社区版部署测试体验。
PolarDB for PostgreSQL(下文简称为 PolarDB-PG)完全兼容 PostgreSQL,采用基于 shared-storage 的存储计算分离架构。具有极致弹性、毫秒级延迟、HTAP 的能力和高可靠、高可用、弹性扩展等企业级数据库特性。同时,PolarDB 具有大规模并行计算能力,可以应对OLTP与OLAP混合负载。 
PolarDB X 支持多种部署形态:单机本地部署、存储计算分离部署、X-Paxos三节点部署(不是 PG, 忽略这句)。这次仅分享存储计算分离部署方法。共享存储可以使用传统共享存储、或者云盘、Ceph分布式存储等,这里我条件有限,使用物理机上的 SSD 硬盘的一个物理分区来模拟共享存储。计算节点使用 PolarDB-PG 的多个 Docker 容器,分别有 1 个主实例 2 个只读实例。部署的方法主要用 Docker 技术。

Docker 启动 PolarDB-PG 容器
Docker 版本不低于 18.04 。安装方法如下
    yum install -y  docker-ce docker-ce-cli containerd.io

    安装完成后根据需要调整 docker 目录,防止后面目录空间写超。

      (polardb) [root@sfx110008 polardb-test]# cat etc/docker/daemon.json
      {
      "exec-opts": ["native.cgroupdriver=systemd"],
      "data-root":"/opt/docker"
      }


      (polardb) [root@sfx110008 polardb-test]# ll opt/docker
      lrwxrwxrwx 1 root root 20 Feb 13 16:28 opt/docker -> data/nvme1n1/docker
      (polardb) [root@sfx110008 polardb-test]#

      拉取 PolarDB-PG docker 镜像并启动 3个容器。这里选择镜像 polardb_pg_binary:pfs 。

        docker pull polardb/polardb_pg_binary:pfs


        docker run -itd --cap-add=SYS_PTRACE --privileged=true --name polardb_pg_rw --shm-size=32g --memory=64g --cpus=16 polardb/polardb_pg_binary:pfs
        docker run -itd --cap-add=SYS_PTRACE --privileged=true --name polardb_pg_ro1 --shm-size=32g --memory=64g --cpus=16 polardb/polardb_pg_binary:pfs
        docker run -itd --cap-add=SYS_PTRACE --privileged=true --name polardb_pg_ro2 --shm-size=32g --memory=64g --cpus=16 polardb/polardb_pg_binary:pfs


        部署后镜像和容器如下


        PolarFS 初始化

        PolarDB File System,简称 PFS 或 PolarFS,是由阿里云自主研发的高性能类POSIX的用户态分布式文件系统,服务于阿里云数据库PolarDB产品。
        PFS(PostgreSQL版)是以后台进程(pfsdaemon)的方式提供服务。PFS的管理通过命令 pfs 。上面的容器里已经包含了 pfs 命令。如果独立部署的话需要下载源码编译,地址:https://github.com/ApsaraDB/PolarDB-FileSystem 。
        开源的 PFS 只包括Filesystem,而不包括下面的分布式块存储。所以在部署的时候我们还需要有共享存储或者其他分布式存储(如Curve、Ceph)结合使用。这里我通过宿主机上 SSD 的物理分区来模拟共享存储。
        首先用 pfs 格式化共享存储,然后启动后台进程 pfsdaemon 即可。
          postgres@6b5fbf632daa:~$ sudo lsblk dev/nvme0n1
          NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
          nvme0n1 259:0 0 3.5T 0 disk
          `-nvme0n1p1 259:2 0 1000G 0 part


          postgres@6b5fbf632daa:~$ sudo pfs -C disk mkfs nvme0n1p1
          pfs tool cmd record:mkfs nvme0n1p1
          [PFS_LOG] Feb 14 10:50:37.830967 INF [27] pfs build version:libpfs_version_("pfsd-build-desc-_-Tue Jan 31 22:56:28 CST 2023")
          [PFS_LOG] Feb 14 10:50:37.831035 INF [27] pid: 26, caller: sudo pfs -C disk mkfs nvme0n1p1
          [PFS_LOG] Feb 14 10:50:37.831056 INF [27] pid: 13, caller: bash
          [PFS_LOG] Feb 14 10:50:37.831078 INF [27] open device cluster disk, devname nvme0n1p1, flags 0x13
          [PFS_LOG] Feb 14 10:50:37.831090 INF [27] disk dev path: dev/nvme0n1p1
          [PFS_LOG] Feb 14 10:50:37.831092 INF [27] open local disk: open(/dev/nvme0n1p1, 0x4002)
          [PFS_LOG] Feb 14 10:50:37.831102 INF [27] ioctl status 0
          [PFS_LOG] Feb 14 10:50:37.831104 INF [27] pfs_diskdev_info get pi_pbdno 0, pi_rwtype 1, pi_unitsize 4194304, pi_chunksize 10737418240, pi_disksize 1073741824000
          [PFS_LOG] Feb 14 10:50:37.831107 INF [27] pfs_diskdev_info waste size: 0
          [PFS_LOG] Feb 14 10:50:37.831109 INF [27] disk size 0xfa00000000, chunk size 0x280000000
          [PFS_LOG] Feb 14 10:50:37.831194 ERR [27] chunk 0 pfs magic mismatch 0 vs 0x5046534348
          [PFS_LOG] Feb 14 10:50:37.831228 INF [27] mkfs PBD nvme0n1p1 isn't formatted
          Init chunk 0
          metaset 0/1: sectbda 0x1000, npage 80, objsize 128, nobj 2560, oid range [ 0, a00)
          metaset 0/2: sectbda 0x51000, npage 64, objsize 128, nobj 2048, oid range [ 0, 800)
          metaset 0/3: sectbda 0x91000, npage 64, objsize 128, nobj 2048, oid range [ 0, 800)


          Init chunk 1


          < …… >




          Init chunk 99
          metaset 63/1: sectbda 0xf780001000, npage 80, objsize 128, nobj 2560, oid range [ 63000, 63a00)
          metaset 63/2: sectbda 0xf780051000, npage 64, objsize 128, nobj 2048, oid range [ 31800, 32000)
          metaset 63/3: sectbda 0xf780091000, npage 64, objsize 128, nobj 2048, oid range [ 31800, 32000)


          Inited filesystem(1073741824000 bytes), 100 chunks, 2560 blktags, 2048 direntries, 2048 inodes per chunk
          making paxos file
          init paxos lease
          making journal file
          pfs mkfs succeeds!


          postgres@6b5fbf632daa:~$ sudo usr/local/polarstore/pfsd/bin/start_pfsd.sh -p nvme0n1p1 -w 2
          option workers 2
          option pbdname nvme0n1p1
          option server id 0
          option logconf usr/local/polarstore/pfsd/bin/../conf/pfsd_logger.conf
          starting pfsd[67] nvme0n1p1
          pfsdaemon nvme0n1p1 start success


          测试一下文件系统的读写。

            postgres@6b5fbf632daa:~$ pfs -C disk touch nvme0n1p1/hello.txt
            postgres@6b5fbf632daa:~$ pfs -C disk ls nvme0n1p1/
            File 1 4194304 Tue Feb 14 10:50:38 2023 .pfs-paxos
            File 1 1073741824 Tue Feb 14 10:50:38 2023 .pfs-journal
            File 1 0 Tue Feb 14 10:58:52 2023 hello.txt
            total 2105344 (unit: 512Bytes)


            PFS 命令参考 :https://docs.polardbpg.com/1653230754878/PolarDB-FileSystem/PFS-File-System-Operation.html


            部署 PolarDB-PG 主实例
            在主实例容器里按下面步骤初始化。
              postgres@6b5fbf632daa:~$ $HOME/tmp_basedir_polardb_pg_1100_bld/bin/initdb -D $HOME/primary


              -- 创建PG数据共享目录
              postgres@6b5fbf632daa:~$ sudo pfs -C disk mkdir nvme0n1p1/shared_data


              postgres@6b5fbf632daa:~$ sudo $HOME/tmp_basedir_polardb_pg_1100_bld/bin/polar-initdb.sh $HOME/primary/ /nvme0n1p1/shared_data/
              pfs tool cmd record:cp -r home/postgres/primary//base nvme0n1p1/shared_data//
              [PFS_LOG] Feb 14 11:13:38.484330 INF [938] pfs build version:libpfs_version_("pfsd-build-desc-_-Tue Jan 31 22:56:28 CST 2023")
              [PFS_LOG] Feb 14 11:13:38.484396 INF [938] pid: 890, caller: /bin/bash home/postgres/tmp_basedir_polardb_pg_1100_bld/bin/polar-initdb.sh home/postgres/primary/ /nvme0n1p1/shared_data/
              [PFS_LOG] Feb 14 11:13:38.484420 INF [938] pid: 889, caller: sudo home/postgres/tmp_basedir_polardb_pg_1100_bld/bin/polar-initdb.sh home/postgres/primary/ /nvme0n1p1/shared_data/
              [PFS_LOG] Feb 14 11:13:38.484440 INF [938] pid: 13, caller: bash
              <……>
              init polarDB data dir success

              修改 PG 的参数文件 postgresql.conf

                postgres@6b5fbf632daa:~$ vim + ~/primary/postgresql.conf
                port=5432
                polar_hostid=1
                polar_enable_shared_storage_mode=on
                polar_disk_name='nvme0n1p1'
                polar_datadir='/nvme0n1p1/shared_data/'
                polar_vfs.localfs_mode=off
                shared_preload_libraries='$libdir/polar_vfs,$libdir/polar_worker'
                polar_storage_cluster_name='disk'
                logging_collector=on
                log_line_prefix='%p\t%r\t%u\t%m\t'
                log_directory='pg_log'
                listen_addresses='*'
                max_connections=1000
                synchronous_standby_names='replica1'
                shared_buffers = 32GB # min 128kB
                bgwriter_delay = 10ms # 10-10000ms between rounds
                synchronous_commit = off # synchronization level;
                checkpoint_timeout = 30min # range 30s-1d
                max_wal_size = 64GB
                min_wal_size = 16GB
                checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0


                修改权限访问控制配置文件 pg_hba.conf

                  postgres@6b5fbf632daa:~$ vim + ~/primary/pg_hba.conf
                  host all all 172.17.0.0/16 trust
                  host replication postgres 0.0.0.0/0 trust


                  启动 PolarDB-PG 主实例。

                    postgres@6b5fbf632daa:~$ pg_ctl start -D $HOME/primary

                    验证当前实例连接和版本。

                      postgres@6b5fbf632daa:~$ psql -p 5432 -d postgres -c 'select now(),version();'
                      now | version
                      -------------------------------+--------------------------------
                      2023-02-14 11:23:13.473181+08 | PostgreSQL 11.9 (POLARDB 11.9)
                      (1 row)


                      在读写节点上,为对应的只读节点创建相应的复制用的slot,用于只读节点的物理复制。

                        postgres@6b5fbf632daa:~$ psql -p 5432 -d postgres -c "SELECT pg_create_physical_replication_slot('replica1');"
                        pg_create_physical_replication_slot
                        -------------------------------------
                        (replica1,)
                        (1 row)
                        postgres@6b5fbf632daa:~$ psql -p 5432 -d postgres -c "SELECT pg_create_physical_replication_slot('replica2');"
                        pg_create_physical_replication_slot
                        -------------------------------------
                         (replica2,)
                        (1 row)



                        部署 PolarDB-PG 只读实例
                        进入 PolarDB-PG 只读实例容器,启动 pfsdamon 进程,按下面步骤初始化只读实例。
                          postgres@5c15cd84e29e:~$ sudo usr/local/polarstore/pfsd/bin/start_pfsd.sh -p nvme0n1p1 -w 2
                          option workers 2
                          option pbdname nvme0n1p1
                          option server id 0
                          option logconf usr/local/polarstore/pfsd/bin/../conf/pfsd_logger.conf
                          starting pfsd[130] nvme0n1p1
                          pfsdaemon nvme0n1p1 start success


                          postgres@5c15cd84e29e:~$ mkdir -m 0700 $HOME/replica1
                          postgres@5c15cd84e29e:~$ sudo ~/tmp_basedir_polardb_pg_1100_bld/bin/polar-replica-initdb.sh nvme0n1p1/shared_data/ $HOME/replica1/
                          <……>
                          init polarDB replica mode dir success


                          postgres@5c15cd84e29e:~$ sudo chown -R postgres.postgres replica1/


                          postgres@5c15cd84e29e:~$ $HOME/tmp_basedir_polardb_pg_1100_bld/bin/initdb -D /tmp/replica1
                          postgres@5c15cd84e29e:~$ cp /tmp/replica1/*.conf $HOME/replica1/
                          修改 PG 实例参数文件。
                            postgres@5c15cd84e29e:~$ vim + ~/replica1/postgresql.conf


                            port=5433
                            polar_hostid=2
                            polar_enable_shared_storage_mode=on
                            polar_disk_name='nvme0n1p1'
                            polar_datadir='/nvme0n1p1/shared_data/'
                            polar_vfs.localfs_mode=off
                            shared_preload_libraries='$libdir/polar_vfs,$libdir/polar_worker'
                            polar_storage_cluster_name='disk'
                            logging_collector=on
                            log_line_prefix='%p\t%r\t%u\t%m\t'
                            log_directory='pg_log'
                            listen_addresses='*'
                            max_connections=1000
                            shared_buffers = 50GB # min 128kB


                            postgres@5c15cd84e29e:~$ vim + ~/replica1/recovery.conf


                            polar_replica='on'
                            recovery_target_timeline='latest'
                            primary_slot_name='replica1'
                            primary_conninfo='host=172.17.0.2 port=5432 user=postgres dbname=postgres application_name=replica1'


                            启动 PolarDB-PG 只读实例。

                              postgres@5c15cd84e29e:~$ $HOME/tmp_basedir_polardb_pg_1100_bld/bin/pg_ctl start -D $HOME/replica1

                              同样的方法部署第二个只读实例。然后在主实例上查看复制状态。

                                postgres=# select pid, usesysid, usename, application_name, client_addr, client_port, backend_start, state, write_lag, sync_priority, sync_state from pg_stat_replication ;
                                pid | usesysid | usename | application_name | client_addr | client_port | backend_start | state | write_lag | sync_priority | sync_state
                                --------+----------+----------+------------------+-------------+-------------+-------------------------------+-----------+-----------------+---------------+------------
                                1151 | 10 | postgres | replica1 | 172.17.0.3 | 52316 | 2023-02-14 11:42:43.350244+08 | streaming | 00:00:00.000043 | 1 | sync
                                345775 | 10 | postgres | replica2 | 172.17.0.4 | 48322 | 2023-02-14 13:54:16.52181+08 | streaming | 00:00:00.00005 | 0 | async
                                (2 rows)


                                此时也可以在主实例创建数据库和表,并初始化数据,然后到只读实例里观察同步效果。


                                PolarDB-PG HTAP 读写分离测试

                                上面部署了 PolarDB-PG 的主实例和两个只读实例,主实例可以支持 OLTP 业务,只读实例可以支持复杂的 OLAP 业务查询。因此这个架构还可以用于读写分离。传统的读写分离是核心业务读写主实例,复杂的 AP 类查询访问只读实例。也可以前端做一个代理,做这种路由转发。这是一种使用方法,但 PolarDB-PG 的读写分离可以更灵活,所有请求都可以发给主实例,读写分离是通过并行查询计划实现的。PolarDB-PG 会自动将并行的查询发往只读实例节点。这里要求是跨机并行的查询计划。
                                首先要在所有实例设置相关并行参数。
                                  alter system set polar_cluster_map='replica1|172.17.0.3|5433,replica2|172.17.0.4|5433';
                                  alter system set polar_enable_px=on;
                                  alter system set polar_px_optimizer_enable_hashagg=off;
                                  alter system set polar_px_enable_partition =true;
                                  alter system set polar_px_optimizer_multilevel_partitioning = true;
                                  alter system set polar_px_dop_per_node =32;
                                  alter system set polar_px_max_workers_number=768;


                                  select pg_reload_conf();


                                  alter table supplier set (px_workers=500);
                                  alter table region set (px_workers=500);
                                  alter table partsupp set (px_workers=500);
                                  alter table part set (px_workers=500);
                                  alter table orders set (px_workers=500);
                                  alter table nation set (px_workers=500);
                                  alter table lineitem set (px_workers=500);
                                  alter table customer set (px_workers=500);


                                  注意:
                                  1. 修改实例参数后要使用 pg_reload_conf 方法使配置生效,并且还要设置相关表的并行参数。
                                  2. 参数  polar_px_max_workers_number  会限制该实例中能同时为并行查询工作的最大 worker 数量。如果 SQL 需要的并行 worker 数量超过这个限制,目前版本会话 SQL 会执行报错。
                                  3. 查询中涉及到的所有表的 px_workers 都要设置,不管表数据量多少。否则,整个 SQL的执行计划依然不会是跨机并行查询。

                                  如下面 SQL (TPC-H Query3.sql)

                                    [postgres@sfx110008 tpchdb]$cat sqls/3.sql
                                    -- using 1677059909 as a seed to the RNG


                                    select
                                    l_orderkey,
                                    sum(l_extendedprice * (1 - l_discount)) as revenue,
                                    o_orderdate,
                                    o_shippriority
                                    from
                                    customer,
                                    orders,
                                    lineitem
                                    where
                                    c_mktsegment = 'FURNITURE'
                                    and c_custkey = o_custkey
                                    and l_orderkey = o_orderkey
                                    and o_orderdate < date '1995-03-22'
                                    and l_shipdate > date '1995-03-22'
                                    group by
                                    l_orderkey,
                                    o_orderdate,
                                    o_shippriority
                                    order by
                                    revenue desc,
                                            o_orderdate;

                                    执行计划如下:

                                    当最下方执行计划中有提示“Optimizer: PolarDB PX Optimizer”,就表示这是个跨机的并行执行计划。当有只读实例时,这个执行计划会被发往只读实例执行。

                                    PolarDB-PG 提供了 TPC-H 的初始化脚本。

                                      git clone https://github.com/HBKO/tpch-dbgen.git
                                      cd tpch-dbgen
                                      vi build.sh
                                      pg_user=tpch
                                      pg_database=tpchdb
                                      pg_host=172.17.0.4
                                      pg_port=5432
                                      data_scale=10
                                      is_run=-1
                                      test_case=18


                                      sh build.sh

                                      执行脚本之前需要提前创建好数据库和账号。

                                        create user tpch with password 'scaleflux';
                                        create database tpchdb owner tpch;
                                        grant all privileges on database tpchdb to tpch

                                        然后写一个脚本,顺序批量运行 TPC-H 22个查询。

                                          [postgres@sfx110008 tpchdb]$cat polardb_pg_tpch_test.sh
                                          #!/bin/bash


                                          export PGHOST=172.17.0.4
                                          export PGPORT=5432
                                          export PGUSER=tpch
                                          export PGPASSWORD=scaleflux
                                          export PGDATABASE=tpchdb


                                          echo
                                          echo "tpch queries begin at "`date "+%Y%m%d%H%M%S"`
                                          echo
                                          for i in `seq 22`;do
                                          echo " tpch query : " $i " at "`date "+%Y%m%d%H%M%S"`;
                                          /bin/cp -f /data/nvme1n1/tpch-dbgen/finals/$i*.sql ./output/
                                          time psql -f /data/nvme1n1/tpch-dbgen/finals/$i.explain.sql -L ./output/$i.explain.sql.log 1>/dev/null ;
                                          time psql -f /data/nvme1n1/tpch-dbgen/finals/$i.sql -L ./output/$i.sql.log 1>/dev/null ;
                                          echo " tpch query : " $i " end "`date "+%Y%m%d%H%M%S"`;
                                          echo
                                          #echo " sleep 10 seconds ..."
                                          #sleep 10;
                                          echo
                                          done;
                                          echo "tpch queries end at "`date "+%Y%m%d%H%M%S"`
                                          echo

                                          当运行TPC-H 查询的时候,可以观察 PolarDB-PG 的容器 CPU 资源消耗,只读实例 CPU 明显高于主实例,说明读写分离起作用了。

                                          其他参考

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

                                          评论