CentOS 7 离线安装 Greenplum:MPP 集群部署与排错指南

发布时间:2026/10/30 8:44:37
CentOS 7 离线安装 Greenplum:MPP 集群部署与排错指南

简介:面向在 CentOS 7 环境中部署 Greenplum 的数据库管理员、运维工程师与大数据平台学习者,这份安装资源围绕 MPP 数据库集群的部署配置与启动管理展开,适合需要搭建海量数据处理与复杂查询环境、希望理清开源集群部署脉络的读者参考。压缩包共 32 个文件,约 66.11MB,以 yml、yaml 编排文件、sh 执行脚本、j2 配置模板和 ini 参数文件为主,辅以 sql、rpm、makefile 及许可说明等,覆盖集群安装、参数注入、服务启停与环境清理等环节。已有 253 人学习。它的价值在于把主机信息、部署编排、启动脚本与模板化参数组织成较完整的目录结构,读者可据此理解 Greenplum 在 CentOS 7 上的部署分层、配置项关系及常见问题的排查思路;随包源码也便于进阶用户做定制与性能优化研究。

1. 先把离线安装这件事拆开:greenplum_installer-centos7 到底解决哪一步

在 CentOS 7 上装 Greenplum,最先卡住的往往不是数据库参数,而是 yum 源不可达、依赖包版本对不上、几台机器之间的环境不一致。greenplum_installer-centos7 这个资源就是冲着这个场景来的:把 CentOS 7 下 Greenplum 安装所需的脚本、依赖包和配置模板整合到一起,让你在离线或半离线环境下把集群搭起来,而不是对着一串报错逐条碰运气。

它适合两类人:一是在内网环境里要把 Greenplum 跑起来的数据平台工程师,二是课程设计或实验环境需要复现一套 MPP 集群的学生和开发者。它不替你规划业务表,也不负责调优 SQL,它解决的是“从裸系统到可登录的 gpdb”这一段最容易出问题的落地环节。下面按顺序讲清资源结构、安装链路、参数怎么设、出错怎么看,再收几个真正省时间的技巧。

2. Greenplum 在 CentOS 7 上的安装链路:从系统基线到集群初始化

Greenplum 是典型的 Shared-Nothing 架构,一个 Master 节点负责接收查询、生成执行计划并分发给 Segment,多个 Segment 节点各自持有数据分片并行计算,节点间通过 Interconnect 交换数据。这意味着安装不是“装一个软件”,而是“让 N 台机器在用户、目录、网络、系统参数上完全对齐”。CentOS 7 的生命周期已经走到末期,默认 yum 源失效是常态,所以安装链路必须建立在“本地包 + 手工校验”的基础上。greenplum_installer-centos7 的价值就在于把这条链路固化成脚本,而不是靠记忆逐条敲。

常见的整体顺序是:系统基线检查 → 创建 gpadmin 用户与目录 → 分发安装包 → 配置 SSH 互信 → 修改内核与资源限制 → 安装 RPM → 交换密钥 → 初始化集群 → 验证。每一步失败都会让后面的步骤失去意义,所以下面按这个顺序拆。

2.1 系统基线:hosts、主机名与时间同步

第一步不是装包,而是让所有节点“认识彼此”。Greenplum 初始化时会解析主机名,如果 /etc/hosts 里缺一条记录,gpssh-exkeys会在某个节点上静默失败,事后排查非常费劲。我一般要求每台机器的主机名是纯小写、不含下划线,并且在所有节点的 /etc/hosts 里写全 Master 与 Segment 的 IP 映射。

# 在每一台节点上执行,假设 mdw 为 Master,sdw1/sdw2 为 Segment hostnamectl set-hostname mdw cat >> /etc/hosts <<'EOF' 192.168.10.10 mdw 192.168.10.11 sdw1 192.168.10.12 sdw2 EOF # 关闭防火墙与 SELinux(实验环境),生产环境请按实际策略放开端口 systemctl stop firewalld && systemctl disable firewalld setenforce 0 sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config # 时间必须一致,否则初始化时节点健康检查会报时钟偏差 yum install -y chrony systemctl enable chronyd && systemctl start chronyd chronyc sources -v

这段脚本做三件事:固定主机名、建立全集群的名称解析、消除防火墙与 SELinux 对端口和文件访问的干扰。时间同步单独强调,是因为 Greenplum 的 Segment 之间会做时间戳比对,偏差过大时gpinitsystem直接拒绝继续。参数上,IP 段要跟你的实际网段一致,不要把示例地址直接抄进生产环境;SELinux 关闭只建议在实验环境使用,正式环境应改为放行对应端口与目录。

2.2 创建 gpadmin 用户与目录规范

Greenplum 不允许用 root 运行,必须有一个专用操作系统用户,惯例叫 gpadmin。这个用户要在所有节点上 UID 一致,家目录路径一致,否则 SSH 互信和后续的gpstate检查都会出问题。资源里的安装脚本通常已经封装了这部分,但我建议先手工确认一遍,知道脚本替你做了什么,出问题时才有排查方向。

# 所有节点执行,UID/GID 保持一致 groupadd -g 530 gpadmin useradd -g 530 -u 530 -m -d /home/gpadmin -s /bin/bash gpadmin echo 'gpadmin:YourPassw0rd' | chpasswd # 数据目录与安装目录分离,便于后续扩容和备份 mkdir -p /data/master /data/primary /data/mirror chown -R gpadmin:gpadmin /data chmod 755 /data # 允许 gpadmin 提权执行系统命令(脚本中修改内核参数时会用到) echo 'gpadmin ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers

UID/GID 统一是血泪经验:如果 Master 上 gpadmin 是 530,Segment 上是 1000,初始化过程中跨节点写文件就会出现属主混乱,报错信息还指不到根因。目录规划上,Master 的数据目录和 Segment 的数据目录必须分开挂载点,否则单块盘写满会同时拖垮元数据和数据分片。sudo 免密是为了让安装脚本能非交互地改内核参数,正式环境建议把权限收敛到具体命令。

2.3 内核参数与资源限制:被忽略的失败源头

Greenplum 对共享内存、信号量、文件句柄有明确要求,CentOS 7 的默认值不够用。这一步改动集中在/etc/sysctl.conf、/etc/security/limits.conf和/etc/security/limits.d/20-nproc.conf三个文件,改完必须重启或重新登录才生效。很多“初始化到一半卡死”的案例,根因就在这儿。

参数建议值作用
kernel.shmmax物理内存一半(字节)单个共享内存段上限
kernel.shmallshmmax / 4096共享内存总页数
kernel.sem250 64000 100 512信号量数组
net.ipv4.ip_local_port_range10000 65535Interconnect 可用端口
net.core.rmem_max2097152网络接收缓冲
fs.file-max655360系统级文件句柄
gpadmin nofile65536用户级文件句柄
cat >> /etc/sysctl.conf <<'EOF' kernel.shmmax = 68719476736 kernel.shmall = 16777216 kernel.sem = 250 64000 100 512 net.ipv4.ip_local_port_range = 10000 65535 net.core.rmem_max = 2097152 net.core.wmem_max = 2097152 fs.file-max = 655360 EOF sysctl -p cat >> /etc/security/limits.conf <<'EOF' gpadmin soft nofile 65536 gpadmin hard nofile 65536 gpadmin soft nproc 131072 gpadmin hard nproc 131072 EOF

shmmax按物理内存的一半设置是常见做法,数值必须用字节,写成 GB 单位会直接被内核忽略。shmall是页数不是字节,用 shmmax 除以 4096 得到。nproc容易翻车,因为 CentOS 7 的limits.d/20-nproc.conf里有一条针对普通用户的默认限制,会覆盖 limits.conf 的设置,必须一并改掉或者确认顺序。改完用ulimit -n和sysctl kernel.shmmax在 gpadmin 用户下复核,别只看文件写没写进去。

2.4 安装包分发与 RPM 安装

资源目录里通常包含 Greenplum 的 RPM 包和 greenplum-cc-web 监控组件。离线环境的关键是确认包架构(x86_64)和系统版本(el7)匹配,然后把包推到所有节点。分发方式用gpscp最省事,但前提是密钥已经配好;如果还没配,就先用 scp 逐台推送。

# 在 Master 上准备目录并推送(此处以 scp 为例,密钥配好后可换 gpscp) mkdir -p /home/gpadmin/packages cd /home/gpadmin/packages # 假设包名为 greenplum-db-6.x.x-rhel7-x86_64.rpm for host in sdw1 sdw2; do scp greenplum-db-*.rpm gpadmin@${host}:/home/gpadmin/packages/ done # 所有节点执行安装,--nodeps 仅在确认依赖齐全时使用 rpm -ivh greenplum-db-*.rpm # 确认安装路径与权限 ls -ld /usr/local/greenplum-db* chown -R gpadmin:gpadmin /usr/local/greenplum-db-*

RPM 安装后会在/usr/local下生成带版本号的目录和一个软链接。软链接是后续source greenplum_path.sh的入口,不要手工删改。如果出现依赖缺失,优先找本地 ISO 里的包补齐,而不是临时打开外网源,否则不同节点的依赖版本会悄悄分叉,后面初始化报错时极难定位。安装完在所有节点上执行一次rpm -qa | grep greenplum,确认版本字符串完全一致。

2.5 SSH 互信与集群初始化

gpssh-exkeys负责在 Master 与所有 Segment 之间建立免密登录。这一步要求前面 hosts 解析和 gpadmin 用户都已就绪,否则它会卡在某台机器上等密码。互信建立后,用gpssh验证一次批量执行,再跑gpinitsystem。

su - gpadmin source /usr/local/greenplum-db/greenplum_path.sh # 准备 hostfile,列出除 Master 外的所有 Segment(含 standby 时另配) cat > /home/gpadmin/hostfile_exkeys <<'EOF' mdw sdw1 sdw2 EOF gpssh-exkeys -f /home/gpadmin/hostfile_exkeys # 验证批量连通 gpssh -f /home/gpadmin/hostfile_exkeys -e 'date; hostname'

gpinitsystem需要一个配置文件,资源里一般提供模板,核心字段包括ARRAY_NAME、MACHINE_LIST_FILE、SEG_PREFIX、PORT_BASE、DATA_DIRECTORY、MASTER_DIRECTORY。PORT_BASE是每个 Segment 的起始端口,一个 Segment 实例会占用连续多个端口,所以要留足间隔。DATA_DIRECTORY的数量必须与每台机器上的 primary 实例数对应。

# 简化示例:单机 2 个 primary 实例,无 mirror cat > /home/gpadmin/gpinitsystem_config <<'EOF' ARRAY_NAME="gp_sandbox" MACHINE_LIST_FILE=/home/gpadmin/hostfile_gpinitsystem SEG_PREFIX=gpseg PORT_BASE=6000 DATA_DIRECTORY="/data/primary /data/primary2" MASTER_DIRECTORY="/data/master" TRUSTED_SHELL=ssh ENCODING=UNICODE EOF cat > /home/gpadmin/hostfile_gpinitsystem <<'EOF' sdw1 sdw2 EOF gpinitsystem -c /home/gpadmin/gpinitsystem_config -h /home/gpadmin/hostfile_gpinitsystem

执行前先跑一遍gpinitsystem -c ... --check-only,它会做预检并列出问题,比直接初始化失败后再回头找要省事得多。初始化成功后,环境变量要写进 gpadmin 的.bashrc,否则每次登录都要手动 source。验证阶段用gpstate看实例状态,用psql -l确认能连上 postgres 库,两步都通才算这条链路走完。

3. 参数怎么定:端口、目录与实例数的取舍

装得起来和跑得稳是两件事,区别就在参数。这一章把最容易拍脑袋决定的几个配置拆开讲,给出判断依据,而不是让你抄一组数字了事。

3.1 PORT_BASE 与端口规划

Greenplum 每个 Segment 实例占用的端口不止一个,主端口之外还有 Interconnect 用的 UDP 端口区间。PORT_BASE=6000意味着第一个实例从 6000 开始,而 Interconnect 默认会在ip_local_port_range范围内另取端口。所以端口规划的要点是:主端口段和系统临时端口段不要重叠。

我一般的做法是把PORT_BASE定在 6000 到 20000 之间的一个段,同时把net.ipv4.ip_local_port_range设为 10000 到 65535 之上不冲突的区间,或者干脆把 Interconnect 的端口范围显式写进postgresql.conf的gp_interconnect_port_range。如果一台机器上要跑多个实例,PORT_BASE之间至少留出 1000 的间隔,因为单个实例的端口占用会向上延伸。

端口冲突的表现很典型:gpinitsystem在启动实例阶段失败,日志里出现Address already in use,但用netstat在初始化前查又查不到占用,因为占用是初始化过程中自己造成的。遇到这种情况不要去杀进程,先回头看PORT_BASE和实例数是否匹配。

3.2 DATA_DIRECTORY 与磁盘布局

DATA_DIRECTORY是一个列表,列表长度决定了每台 Segment 机器上创建几个 primary 实例。这个数字不是越多越好,它应该等于该机器上能独立提供 IO 的磁盘数量。一块盘上放两个实例,等于让两个进程抢同一个 IO 队列,并发查询时延迟会明显抖动。

判断方法是看挂载点。如果/data/primary和/data/primary2其实在同一块物理盘上,那配两个实例只有心理安慰作用。合理做法是按盘挂载,每个挂载点对应一个实例目录,再配合gp_vmem_protect_limit控制单实例内存上限。资源里给的模板默认可能是单目录,务必按自己的硬件改,不要照抄。

Master 目录单独放在MASTER_DIRECTORY,它存放系统表和元数据,IO 特征与数据盘不同,建议单独一块盘。mirror 目录同理,最好与 primary 不同盘,否则一块盘坏了主备一起丢,mirror 就失去意义了。

3.3 内存相关参数:gp_vmem_protect_limit 与 statement_mem

gp_vmem_protect_limit是每个 Segment 实例可用的虚拟内存上限,单位 MB。设得太大,系统会触发 OOM;设得太小,复杂查询直接报内存不足。经验公式是:单机物理内存 × 0.8 ÷ 该机器上的 primary 实例数,再留一点余量给操作系统。

-- 在 psql 中查看与调整,需根据实际内存核算 SHOW gp_vmem_protect_limit; SHOW statement_mem; -- 示例:单机 64GB,2 个 primary 实例,单实例上限约 24GB ALTER SYSTEM SET gp_vmem_protect_limit = 24576;

statement_mem是单条查询在每个 Segment 上可用的内存,它不能超过gp_vmem_protect_limit除以该 Segment 上可能并发的查询数。这两个参数是联动的,只调一个往往没效果。调整后需要重启集群才生效,所以要在业务低峰期做,并用一组典型查询压一遍,看有没有出现 spill 到磁盘的迹象。

4. 避坑与排查:五条装完才会显形的坑

这一章记录的是装完之后才暴露、但根因在安装阶段的问题。每条按现象、原因、解决三段写,方便你对照自己的环境。

4.1 gpssh-exkeys 成功但 gpssh 仍要密码

现象是gpssh-exkeys输出全部成功,紧接着gpssh -e 'hostname'却提示输入密码。原因通常是 gpadmin 家目录权限过宽,OpenSSH 认为~/.ssh或authorized_keys可被他人写入而拒绝使用密钥。CentOS 7 上如果之前用 root 建过目录,属主或权限很容易不对。

解决方法是逐台修正权限:chmod 700 ~/.ssh、chmod 600 ~/.ssh/authorized_keys、chmod 700 ~,并确认家目录属主是 gpadmin 而不是 root。修完重新跑一次gpssh-exkeys,不要只重跑 gpssh,因为密钥本身可能没写进去。

4.2 初始化卡在“Checking for port availability”

现象是gpinitsystem长时间停在端口检查,最后超时失败。原因多是防火墙没关干净,或者 iptables 规则仍在拦截节点间的探测包;也可能是 hosts 里某台机器的 IP 写错,导致探测包发往了不存在的地址。

解决方法是先在 Master 上用ping和nc -zv sdw1 22逐台确认连通,再检查systemctl status firewalld与iptables -L。确认网络层没问题后,用gpinitsystem --check-only重跑预检,看它具体卡在哪台主机、哪个端口。

4.3 初始化成功但 psql 连不上

现象是gpinitsystem报告完成,gpstate也显示实例 running,但psql -l报连接被拒绝。原因通常是pg_hba.conf没有放行客户端 IP,或者环境变量PGPORT、PGHOST没设对,连到了错误的端口或 socket 路径。

解决办法是先确认MASTER_DATA_DIRECTORY环境变量指向正确,再检查$MASTER_DATA_DIRECTORY/pg_hba.conf里是否有对应网段的host all all 192.168.10.0/24 trust或 md5 规则,改完执行gpstop -u重载配置而不是重启整个集群。

4.4 查询报“memory limit exceeded”

现象是简单查询正常,稍复杂的聚合就报内存超限。原因通常是gp_vmem_protect_limit设得偏小,或者statement_mem设得过大导致单查询挤占了其他并发的额度。还有一种情况是系统 swap 没关,内核把内存压力转成了磁盘交换,表现为查询极慢之后才报错。

解决方法是先按 3.3 的公式复核上限,用free -g确认 swap 状态,实验环境可以swapoff -a并注释掉 fstab 里的 swap 行。然后针对具体查询调statement_mem,并在会话级用SET statement_mem做灰度验证,别直接改全局。

4.5 扩容后新 Segment 不被识别

现象是手工加了机器、跑了gpexpand,但新实例状态一直是 down。原因多为新节点的内核参数、gpadmin 用户、Greenplum 安装路径与原集群不一致,或者新节点的pg_hba.conf没同步。

解决办法是把 2.1 到 2.4 的步骤在新节点上完整走一遍,用gpssh批量对比关键文件:sysctl kernel.shmmax、ulimit -n、rpm -qa | grep greenplum。三项都一致后再重跑扩容流程,比反复重试快得多。

5. 收尾技巧:把安装过程变成可回放的检查单

装 Greenplum 最耗时的从来不是敲命令,而是出问题时不知道停在哪一步。我后来养成一个习惯:把整个安装链路写成一个可重复执行的检查脚本,每一步只做校验、不改配置,跑完输出一张“通过/失败”清单。这样无论是新机器上线还是环境重建,先跑一遍检查单,就能把问题挡在初始化之前。

#!/bin/bash # gp_precheck.sh:只读检查,不改任何配置 set -u FAIL=0 check() { local desc="$1"; shift if "$@" >/dev/null 2>&1; then echo "[PASS] $desc" else echo "[FAIL] $desc" FAIL=1 fi } check "hosts 含所有节点" grep -q sdw1 /etc/hosts check "SELinux 已关闭" bash -c '[ "$(getenforce)" = "Disabled" ]' check "shmmax 已生效" bash -c '[ "$(sysctl -n kernel.shmmax)" -ge 68719476736 ]' check "gpadmin 用户存在" id gpadmin check "Greenplum 已安装" bash -c 'ls /usr/local/greenplum-db >/dev/null' check "gpadmin 免密 sudo" sudo -u gpadmin sudo -n true check "Master 目录可写" sudo -u gpadmin test -w /data/master exit $FAIL

这个脚本的关键在于“只读”,它不会替你做决定,只把环境状态摆出来。check函数把命令的退出码翻译成 PASS/FAIL,任何一条失败都返回非零,方便直接嵌进自动化流程。实际使用时把路径、IP、阈值换成你环境里的值,然后通过gpssh在所有节点上各跑一遍,比对输出,哪里不一致一眼就能看出来。

几个使用上的细节值得说清楚。第一,sysctl -n kernel.shmmax取的是运行时值,不是配置文件里的值,能真实反映参数有没有生效,比 grep 配置文件可靠。第二,sudo -u gpadmin sudo -n true验证的是免密提权,如果卡住说明 sudoers 配错了,这个检查要加超时,避免脚本挂死。第三,这个检查单建议在每次改动环境后都跑,包括改内核参数、换机器、升级 RPM,因为它花的时间比事后排查少一个数量级。

从那以后我每次动集群配置前都强制走一遍这个检查单,哪怕是“只改一个端口”这种小改动,因为 Greenplum 的失败往往不在改动本身,而在你以为没变的那些前提上。希望帮到你。

本文还有配套的精品资源,点击获取