Greenplum TPC-H Cookbook

2022-06-07 00:00:00 创建 数据 节点 测试 配置

版本号

Greenplum 6.15.0

环境

内网 3 台机器,每台 40 核 189 GB 内存 NVMe 3TB 磁盘,相互之间已配置好网络连接。

测试逻辑

Standalone 部署的 Greenplum 集群,一共 24 个 Segment 进程,每台机器 8 个。表采用 column orientation 创建,即采用 Greenplum 的列存模式来做性能测试。

测试步骤

搭建 Greenplum 集群

下载 Greenplum 6.15.0 RPM 安装包,上传到测试机器上安装。安装之前可能需要做相应机器特化的配置,具体可以参考官方文档[1],主要是跟网络和文件系统限制有关的配置。

RPM 安装包安装的流程很简单。

    $ rpm -Uvh open-source-greenplum-db-6.15.0-rhel7-x86_64.rpm

    安装完成后,创建 gpadmin 用户并修改安装目录的权限。这是因为 Greenplum 不允许以 root 用户运行。

      $ groupadd gpadmin
      $ useradd gpadmin -g gpadmin
      $ passwd gpadmin
      $ chown -R gpadmin /usr/local/greenplum-db*

      这个步骤要在三台机器上重复运行,可以考虑编写流程脚本自动化。

      修改成功后,以 gpadmin 用户身份执行后续操作。

      首先配置环境变量,这个步骤可以加入到启动脚本中。

        source usr/local/greenplum-db/greenplum_path.sh

        随后检查安装完整性,首先创建一个包含所有节点 hostname 的 hostfile_exkeys
         文件。

          h59
          h82
          h85

          然后执行命令列出安装目录的文件。

            $ gpssh -f hostfile_exkeys -e ls -l $GPHOME

            如果安装成功,不需要用户手动输入其他节点的登录密码,就会显示出所有节点的安装目录。这些节点都应该拥有相同的安装目录,并且这些目录属于 gpadmin 用户。如果要求输入登录密码,就需要重新执行 ssh key 交换命令。

              $ gpssh-exkeys -f hostfile_exkeys

              接下来,在启动 Greenplum 数据库前需要初始化。

              步是创建并配置 gpinitsystem_config
               文件,这个文件可以从模板中复刻并做简单的修改。

                $ cp $GPHOME/docs/cli_help/gpconfigs/gpinitsystem_config gpinitsystem_config

                配置相关参数,其中必须修改的配置的参数如下。

                declare -a DATA_DIRECTORY
                 行,指定了 Segment 节点的数据目录,也指定了该节点上会创建多少个 Segment 实例。
                MASTER_HOSTNAME
                 行,指定了 Matser 的主机名
                MASTER_DIRECTORY
                 行,指定了 Master 元数据的保存目录,后续大量操作需要配置的 MASTER_DATA_DIRECTORY
                 环境变量即该目录下的 Master 数据 Segment 目录,默认是 gpseg-1
                 目录。

                第二步是创建 Segment 节点的主机名信息文件。

                  h59
                  h82
                  h85

                  第三步是运行初始化命令,其中 hostfile_gpinitsystem
                   是上述 Segment 节点的主机名信息文件。

                    $ gpinitsystem -c gpinitsystem_config -h hostfile_gpinitsystem

                    这样创建出来的集群是没有 Mirror Segment 也没有 Standby Master 的,对于性能测试来说,无需考虑太多的容错。

                    根据提示一步一步创建集群,成功后可通过 psql 实用工具访问 Greenplum 数据库,默认地有一个名为 template1 的数据库。

                    准备 TPC-H 数据

                    我们假设 TPC-H 数据已经生成为 Greenplum 可识别即 PostgreSQL 可识别的 CSV 文件,否则可以自行尝试生成数据,例如利用 dbgen[2] 或其他教程。

                    首先我们创建测试用的 tpch_100 数据库,随后执行 DDL 创建表。

                      CREATE TABLE IF NOT EXISTS nation  (
                      N_NATIONKEY INTEGER NOT NULL,
                      N_NAME CHAR(25) NOT NULL,
                      N_REGIONKEY INTEGER NOT NULL,
                      N_COMMENT VARCHAR(152))
                      WITH (appendonly=true, orientation=column)
                          DISTRIBUTED BY (N_NATIONKEY);

                      可以看到重点的不同是 WITH 语句和 DISTRUBUTED BY 语句。我们使用列存并指定主键为分区键。其他表的 DDL 可做相似处理或进一步调优。

                      随后进入 psql 实用工具,通过 PostgreSQL 的 COPY 语句加载数据。

                        tpch_100=# COPY part FROM '/path/to/nation.csv' DELIMITER '|' CSV;

                        类似地,加载全部 8 个表的数据。可以使用 COUNT 语句校验数据的完整性。

                        执行 TPC-H 测试

                        完成数据导入后,就可以通过正常的和 PostgreSQL 交互的方式发起查询请求执行测试了。

                        一行执行测试的命令参考如下。

                          $ psql -a -e tpch_100 > output.txt <<EOF
                          \timing on
                          SELECT 1;
                          EOF

                          查询语句替换为 TPC-H 的查询语句即可,可以编写脚本来自动化测试流程。

                          调优方面,Greenplum 默认的内存配置较小,可以修改 statement_mem 配置项调大内存,具体调优和配置方法可参考官方文档或其他分享。

                          后附上一个 Perl 自动化脚本,里面假设了 Query 的位置、迭代的次数和输出的位置,可以相应改动适配自己的环境。

                            #!/usr/bin/env perl


                            use v5.10.1;
                            use strict;
                            use warnings;


                            use File::Spec ();
                            use FindBin ();


                            use Getopt::Long qw( GetOptions :config no_ignore_case);


                            GetOptions(
                            "d|db=s", \(my $db = "tpch_100"),
                            ) or usage(1);


                            usage(1) unless ($db);


                            my @queries = @ARGV;
                            if ( @queries == ) {
                            @queries = ( 1..22 );
                            }


                            my $q15 = <<'_EOC_';
                            create view revenue (supplier_no, total_revenue) as
                            select
                            l_suppkey,
                            sum(l_extendedprice * (1 - l_discount))
                            from
                            lineitem
                            where
                            l_shipdate >= '1997-07-01'
                            and l_shipdate < date '1997-07-01' + interval '3' month
                            group by
                            l_suppkey;


                            explain analyze select
                            s_suppkey,
                            s_name,
                            s_address,
                            s_phone,
                            total_revenue
                            from
                            supplier,
                            revenue
                            where
                            s_suppkey = supplier_no
                            and total_revenue = (
                            select
                            max(total_revenue)
                            from
                            revenue
                            )
                            order by
                            s_suppkey;


                            select
                            s_suppkey,
                            s_name,
                            s_address,
                            s_phone,
                            total_revenue
                            from
                            supplier,
                            revenue
                            where
                            s_suppkey = supplier_no
                            and total_revenue = (
                            select
                            max(total_revenue)
                            from
                            revenue
                            )
                            order by
                            s_suppkey;


                            drop view revenue;
                            _EOC_


                            for my $i (1..3) {
                            for my $query ( @queries ) {
                            if ($query < 1 || $query > 22) {
                            die "$query should be in (1..22)";
                            }


                            print "Running TPC-H Query $query, iteration=$i...\n";
                            my $sqlpath = File::Spec->catfile($FindBin::RealBin, "query/$query.sql");
                            my $sql = qx(cat $sqlpath);
                            my $realquery = $query != 15
                            ? "explain analyze $sql" . "$sql"
                            : $q15;
                            my $cmd = qq(psql -a -e $db > turn$i/q${query}.txt <<EOF\n\\timing on\n$realquery\nEOF);
                            my $rc = system($cmd);
                            print "rc=$rc\n";
                            }
                            }


                            sub usage {
                            my $rc = shift;
                            my $msg = <<_EOC_;
                            gptpch [options] [query|...]
                            _EOC_


                            if ($rc == ) {
                            print $msg;
                            exit();
                            }


                            warn $msg;
                            exit($rc);
                            }

                            References

                            [1]
                             官方文档: https://docs.greenplum.org/6-8/install_guide/prep_os.html
                            [2]
                             dbgen: http://www.tpc.org/tpc_documents_current_versions/current_specifications5.asp

                            来源 https://www.modb.pro/db/77646

                            相关文章