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 为 Mastersdw1/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.*/SELINUXdisabled/ /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/sudoersUID/GID 统一是血泪经验如果 Master 上 gpadmin 是 530Segment 上是 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 EOFshmmax按物理内存的一半设置是常见做法数值必须用字节写成 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; hostnamegpinitsystem需要一个配置文件资源里一般提供模板核心字段包括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_NAMEgp_sandbox MACHINE_LIST_FILE/home/gpadmin/hostfile_gpinitsystem SEG_PREFIXgpseg PORT_BASE6000 DATA_DIRECTORY/data/primary /data/primary2 MASTER_DIRECTORY/data/master TRUSTED_SHELLssh ENCODINGUNICODE 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_BASE6000意味着第一个实例从 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_memgp_vmem_protect_limit是每个 Segment 实例可用的虚拟内存上限单位 MB。设得太大系统会触发 OOM设得太小复杂查询直接报内存不足。经验公式是单机物理内存 × 0.8 ÷ 该机器上的 primary 实例数再留一点余量给操作系统。-- 在 psql 中查看与调整需根据实际内存核算 SHOW gp_vmem_protect_limit; SHOW statement_mem; -- 示例单机 64GB2 个 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 FAIL0 check() { local desc$1; shift if $ /dev/null 21; then echo [PASS] $desc else echo [FAIL] $desc FAIL1 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 的失败往往不在改动本身而在你以为没变的那些前提上。希望帮到你。本文还有配套的精品资源点击获取