接入新客户的数据,处理的数据量比之前上了一个量级。以前的索引数据库用的 PostgreSQL ,客户端代码暂时没空修改,为了支持这批数据,打算迁移到 Greenplum。
Greenplum 是先进的基于 PostgreSQL 的开源分布式数据库之一。因为兼容 PostgreSQL 的接口,客户端无需做太多的修改就可以使用。本身是基于MPP架构设计的一套数据分析系统,方便扩展,系统稳定,很适合我们的场景。Greenplum是Pivotal旗下的产品,有商业公司开发和维护,会有更好的技术支持和服务。
架构
Greenplum基于MPP架构,如上。 Master 节点作为系统的入口,处理SQL请求。 Segment 节点存储和处理数据。 Master 和 Segment 之间通过 Interconnect 这个网络层连接起来。
一个SQL查询到 Master 节点, Master 会分发到 Segment 节点进行计算,计算结果最后再汇总到 Master 节点,处理好之后返回数据。 Master 和 Segment 分别通过 StandBy Master 和 Mirror 节点提供高可用。 Segment 节点之间并没有太多的数据交互。这种架构好处是简单,好扩展,但是感觉 Master 节点容易成为系统的瓶颈。整个系统的入口和数据最后的汇总都在 Master 节点上,负载可不轻松。
安装
Greenplum提供了详细的安装文档, 6.0 新版本刚发布,我直接使用的新版本。
主要安装步骤如下:
- 检查系统、硬件是否满足条件
- 操作系统配置修改
- Greenplum 用户创建
- Greenplum 系统安装
- Greenplum 系统初始化
提供了 ansible 脚本:https://gpdb.docs.pivotal.io/6-0/install_guide/ansible-example.html
软硬件要求
- 主流的操作系统都行
- 必须使用 XFS 文件系统
实测其他的也行,不过最好按照官方文档用XFS,其他可能影响性能 - 内存 16G +,硬盘要求导入数据后可用空间大于30%
实测够用就行 - 10Gbps 内网宽带
不满足也能用
操作系统配置修改
主要三个:
- 关闭 SELinux: 在
/etc/selinux/config
中设置SELINUX=disabled
,重启即可 - 关闭防火墙:CentOS firewalld / Ubuntu ufw
- 同步系统时间:系统NTP服务需要打开,时间必须一致
Greenplum 用户创建
也是三个,首先创建 gpadmin 用户和用户组
1 | sudo groupadd gpadmin |
再生成密钥对
1 | sudo su gpadmin |
最后将管理用户设置为 sudo 免密,方便以后自己操作
1 | echo 'pgadmin ALL=(ALL) NOPASSWD: ALL' | EDITOR='tee -a' visudo |
Greenplum 系统安装
Ubuntu 系统有现成的PPA源,Pivotal也提供编译好的二进制包。我选择的是最新版本的 greenplum-db。
1 | sudo add-apt-repository ppa:greenplum/db |
Greenplum 系统初始化
文档在此,需要在 master 节点上操作。
创建用于初始化的 host 文件
创建 hostfile_gpinitsystem
包括所有 segment 节点的地址,不包括 master 和 standby master。更改配置文件,确保 master 到各个 segment 节点的连接正确。
1 | ssh-keyscan -f hostfile_gpinitsystem || sudo tee -a /etc/ssh/ssh_known_hosts |
创建 Greenplum 数据库配置文件
1 | source /opt/greenplum-db-6.0.1/greenplum_path.sh |
主要修改的几个参数按照文档要求的填对就行。
创建数据存储区域
需要在各个类型的节点上创建 Greenplum 用于存储数据的路径,并配置好权限。数据存储路径需要和配置文件的保持一致。可以利用 Greenplum 提供的工具在 master 节点操作整个网络。
Master
1 | mkdir -p /data/master |
Standby master
1 | source /opt/greenplum-db-6.0.1/greenplum_path.sh |
Segment
1 | source /opt/greenplum-db-6.0.1/greenplum_path.sh |
Mirror
1 | source /opt/greenplum-db-6.0.1/greenplum_path.sh |
初始化数据库
上面都整好了,就可以执行命令初始化数据库了。
1 | gpinitsystem -c gpinitsystem_config -h hostfile_gpinitsystem |
为了方便以后的操作,可以增加下面内容到 .bashrc
,不用每次 source
引入环境变量。
1 | source /opt/greenplum-db-6.0.1/greenplum_path.sh |
迁移
生产环境使用的 PostgreSQL 11,使用了很多新特性,包括BRIN等。Greenplum 6 还是基于 PG 9.4 版本,一些东西老版本的不支持,需要特别注意,处理一下。
迁移使用PG自带的工具 pg_dump 和 psql ,很快可以灌入数据。
碰到的问题
小问题就不提了,看 log 和文档定位到修改就好了,说一个奇葩的问题。
查询一个SQL语句,只要带 Group By 就无法返回结果,而 sum 却可以拿到结果。查看日志没有报错。查询就是等待返回数据,非常诡异。master 和 segment 节点是有超时设置的,如果是 segment 查询超时,应该会有错误日志,但是很诡异,就是没有详细的异常日志。根据Greenplum的架构图,猜测应该是 master 节点处理的问题,但是继续检查配置文件、检查Log,依旧找不到问题。
搜索结果中看到了三罐可乐带你读懂Greenplum的interconnect,可能是 Greenplum 的 interconnect 导致 master 对 segment 返回的结果处理有奇怪的逻辑。整个网络状态是正常的,端口监听也正常。反思整个部署过程,打开了 /etc/hosts
文件。
1 | 127.0.0.1``````hostname1 |
云服务器的系统会在 hosts 文件将自己的 hostname 配置成 127.0.0.1
,搭建 Greenplum 集群的时候设置的 hosts 添加在这一行下面。删除本机 127.0.0.1
的配置,重启系统,恢复正常。