greenplum学习
第1章 Greenplum数据体系结构
Greenplum数据库通过在多个服务器或主机之间分配负载来存储和处理大量数据。Greenplum中的逻辑数据库是一组单独的PostgreSQL数据库,这些数据库协同工作以呈现单个数据库映像。master是Greenplum数据库系统的入口点。它是用户连接并提交SQL语句的数据库实例。master主服务器协调系统中其他数据库实例segements(称为段)的工作负载,这些实例处理数据和存储。这些segements通过互连(Greenplum数据库的网络层)与主节点相互通信。

Greenplum Master
master是Greenplum数据库系统的入口点。它是数据库服务器进程,它接受客户端连接并处理系统用户发出的SQL命令。用户使用兼容PostgreSQL的客户端程序(例如psql或ODBC)通过主服务器连接到Greenplum Database。
master服务器器维护系统目录(一组系统表,其中包含有关Greenplum数据库系统本身的元数据),但是主服务器不包含任何用户数据。数据仅驻留在segments上。
The Segments
在Greenplum数据库中,Segements是数据存储和大多数查询处理发生的位置。用户定义的表及其索引分布在Greenplum数据库系统中的可用段中。每个Segement包含数据的不同部分。段实例是为段提供服务的数据库服务器进程。用户不会直接与Greenplum数据库系统中的细分互动,而是通过master进行互动。
在参考的Greenplum数据库硬件配置中,每个segment主机的段实例数由有效CPU或CPU核心的数量确定。例如,如果segment主机有两个双核处理器,则每个主机可能有两个或四个segment。如果segment主机具有三个四核处理器,则每个主机可能具有三个,六个或十二个segment。性能测试将帮助确定所选硬件平台的最佳段数。
Interconnect
是Master节点与Segment节点、Segment节点与Segment节点之间的数据传输组件,它基于千兆交换机或万兆交换机实现数据在节点间的高速传输;
第2章 配置系统
2.1.主机要求
(1)Greenplum 6在以下操作系统平台上运行:
Red Hat Enterprise Linux 64-bit 7.x
Red Hat Enterprise Linux 64-bit 6.x
CentOS 64-bit 7.x
CentOS 64-bit 6.x
Ubuntu 18.04 LTS
(2)Greenplum可以使用以下Java版本
Oracle JDK 8 or Oracle JDK 11
(3)硬件和网络最低要求

在阿里云购买三台主机,分别为greenplum001,greenplum002,greenplum003
2.2 禁用SELINX和防火墙软件
(2)(1)禁用SELINX ,阿里云默认禁用无需修改
[root@greenplum001 ~]# vim /etc/selinux/config
SELINUX=disabled
[root@greenplum002 ~]# vim /etc/selinux/config
SELINUX=disabled
[root@greenplum003~]# vim /etc/selinux/config
SELINUX=disabled
(3)禁用后重启
(4)禁用防火墙,阿里云默认禁用无需修改
[root@greenplum001 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Docs: man:firewalld(1)
2.3 设置系统所需参数
(1)编辑hosts file
[root@greenplum001 ~]# vim /etc/hosts
172.26.31.239 greenplum001 greenplum001
172.26.31.238 greenplum002 greenplum002
172.26.31.237 greenplum003 greenplum003
(2)分发hosts文件
[root@greenplum001 ~]# scp /etc/hosts greenplum002:/etc/
[root@greenplum001 ~]# scp /etc/hosts greenplum003:/etc/
(3)编辑sysctl.conf,需要设置共享内存Greenplum数据库使用共享内存在属于同一postgres实例的postgres进程之间进行通信。kernel.shmall设置可以在系统范围内使用的共享内存总量(以页为单位)。kernel.shmmax设置单个共享内存段的最大大小(以字节为单位)。根据系统的物理内存和页面大小设置kernel.shmall和kernel.shmax值。通常,两个参数的值都应为系统物理内存的一半。使用操作系统变量_PHYS_PAGES和PAGE_SIZE设置参数。
公式:
kernel.shmall = ( _PHYS_PAGES / 2)
kernel.shmmax = ( _PHYS_PAGES / 2) * PAGE_SIZE
查看当前系统的对应大小
[root@greenplum002 ~]# getconf PAGE_SIZE
4096
[root@greenplum002 ~]# getconf _PHYS_PAGES
1965767
知道了_PHYS_PAGES和PAGE_SIZE后配置sysctl.conf
[root@greenplum001 ~]# vim /etc/sysctl.conf
kernel.shmall = 982883
kernel.shmmax = 4025888768
kernel.shmmni = 4096
(4)设置segment内存
[root@greenplum001 ~]# vim /etc/sysctl.conf
vm.overcommit_memory = 2 //官方推荐始终为2
vm.overcommit_ratio = 95 // 百分比
(2)分发sysctl.conf
[root@greenplum001 ~]# scp /etc/sysctl.conf greenplum002:/etc/
[root@greenplum001 ~]# scp /etc/sysctl.conf greenplum003:/etc/
(3)重新加载配置文件
[root@greenplum001~]# sysctl -p
[root@greenplum002 ~]# sysctl -p
[root@greenplum003 ~]# sysctl -p
(4)系统资源限制
[root@greenplum001 ~]# vim /etc/security/limits.conf
* soft nofile 524288
* hard nofile 524288
* soft nproc 131072
* hard nproc 131072
(5)分发
[root@greenplum001 ~]# scp /etc/security/limits.conf greenplum002:/etc/security/
[root@greenplum001 ~]# scp /etc/security/limits.conf greenplum002:/etc/security/
(6)重启(3台都需重启),并测试
[root@greenplum001 ~]# reboot
[root@greenplum001 ~]# ulimit -u
131072
(7)显示131072,配置生效
(8)磁盘IO设置,将每个磁盘设备文件的预读值设为16384
[root@greenplum001 ~]# /sbin/blockdev --getra /dev/vda1
8192
[root@greenplum001 ~]# /sbin/blockdev --setra 16384 /dev/vda1
[root@greenplum001 ~]# /sbin/blockdev --getra /dev/vda1
16384
(13)编辑rc.local,启动时永久生效,并添加操作权限
[root@greenplum001 ~]# vim /etc/rc.d/rc.local
/sbin/blockdev --setra 16384 /dev/vda1
[root@greenplum001 ~]# chmod +x /etc/rc.d/rc.local
(14)三台机器都操作一遍,重启系统让配置生效
(15)禁用透明大页面,阿里云默认禁用,若想禁用使用命令grubby --update-kernel=ALL --args="transparent_hugepage=never"
[root@greenplum001 ~]# cat /sys/kernel/mm/*transparent_hugepage/enabled
[always] madvise never
(16)IPC对象删除,防止Greenplum数据库使用程序gpinitsystem失败并出现信号错误,3台机器都操作
[root@greenplum001 ~]# vim /etc/systemd/logind.conf
RemoveIPC=no
[root@greenplum001 ~]# service systemd-logind restart
(17)防止实用程序超出主机的未认证连接最大阀值,发生错误ssh_exchange_identification,需要增加Greenplum数据库系统的连接阀值
[root@greenplum001~]# vim /etc/ssh/sshd_config
MaxStartups 200
MaxSessions 200
[root@greenplum001 ~]# service sshd restart
(18)Centos7.x须加一下配置,在末尾添加
[root@greenplum001 ~]# vim /etc/default/grub
transparent_hugepage=never
[root@greenplum001 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
(19)三台机器都进行配置并重启
2.4 同步各机器系统时间
(1)因为是阿里云所以不用配置 官方地址:http://docs.greenplum.org/6-4/install_guide/prep_os.html#topic_qst_s5t_wy
2.5 创建Greenplum管理用户
(1)使用Greenplum数据库不能用root管理,需要创建gpadmin账户
[root@greenplum001 ~]# groupadd gpadmin
[root@greenplum001 ~]# useradd gpadmin -r -m -g gpadmin
[root@greenplum001 ~]# passwd gpadmin
(2)配置免密登录
[root@greenplum001 ~]# su gpadmin
[gpadmin@greenplum001 root]$ ssh-keygen -t rsa -b 4096
[gpadmin@greenplum001 root]$ ssh-copy-id greenplum002
[gpadmin@greenplum001 root]$ ssh-copy-id greenplum003
(3)给gpadmin赋予权限,取消%wheel注释,将gpadmin添加到wheel下
[root@greenplum001 ~]# vim /etc/sudoers
%wheel ALL=(ALL) NOPASSWD: ALL
[root@greenplum001 ~]# usermod -aG wheel gpadmin
(4)三台机器都执行相同操作
第3章 安装greenplum
(1)下载并上传greenplum-db-6.7.1-rhel7-x86_64.rpm,3台机器都安装
[root@greenplum001 ~]# mkdir /opt/software
[root@greenplum001 ~]# su gpadmin
[gpadmin@greenplum001 root]$ cd /opt/software/
[gpadmin@greenplum001 software]$ sudo yum install greenplum-db-6.7.1-rhel7-x86_64.rpm
[gpadmin@greenplum001 software]$ sudo chown -R gpadmin:gpadmin /usr/local/greenplum*
(2)启用ssh免密登录,创建hostfile_exkeys,配置greenplum所有主机名
[gpadmin@greenplum001 software]$ source /usr/local/greenplum-db/greenplum_path.sh
[gpadmin@greenplum001 software]$ cd /usr/local/greenplum-db
[gpadmin@greenplum001 greenplum-db-6.7.1]$ vim hostfile_exkeys
greenplum001
greenplum002
greenplum003
(3)对hostfile_exkeys,运行gpssh-exkeys程序
[gpadmin@greenplum001 greenplum-db-6.7.1]$ gpssh-exkeys -f hostfile_exkeys
第4章 创建数据存储区域
4.1 在master上创建数据目录
(1)以root用户创建目录
[root@greenplum001 ~]# mkdir -p /data/master
[root@greenplum001 ~]# chown gpadmin:gpadmin /data/master
(2)在002上备用主数据库上创建目录
[root@greenplum002 software]# mkdir -p /data/master
[root@greenplum002 software]# chown gpadmin:gpadmin /data/master
4.2创建segment的存储
(1)在mast节点001上,创建hostfile_gpssh_segonly文件,填上主机名
[root@greenplum001 greenplum-db-6.7.1]# vim hostfile_gpssh_segonly
greenplum001
greenplum002
greenplum003
(2)使用gpss创建目录和修改权限,需要提前配好root免密登录
[root@greenplum001 greenplum-db]# gpssh -f hostfile_gpssh_segonly -e 'mkdir -p /data/primary'
[root@greenplum001 greenplum-db]# gpssh -f hostfile_gpssh_segonly -e 'mkdir -p /data/mirror'
[root@greenplum001 greenplum-db]# gpssh -f hostfile_gpssh_segonly -e 'chown -R gpadmin /data/*'
第5章 初始化系统
(1)创建hostfile_gpinitsystem文件,确定segment个数
[gpadmin@greenplum001 greenplum-db]$ pwd
/usr/local/greenplum-db
[gpadmin@greenplum001 greenplum-db]$ vim hostfile_gpinitsystem
greenplum001
greenplum002
greenplum003
(2)复制gpinitsystem_config到home
[gpadmin@greenplum001 root]$ cd /home/gpadmin/
[gpadmin@greenplum001 ~]$ mkdir gpconfigs
[gpadmin@greenplum001 ~]$ cd /usr/local/greenplum-db
[gpadmin@greenplum001 greenplum-db]$ cp docs/cli_help/gpconfigs/gpinitsystem_config /home/gpadmin/gpconfigs/
(3)修改配置文件,确定段的个数
[gpadmin@greenplum001 greenplum-db]$ cd ~
[gpadmin@greenplum001 ~]$ cd gpconfigs/
[gpadmin@greenplum001 gpconfigs]$ vim gpinitsystem_config
declare -a DATA_DIRECTORY=(/data/primary /data/primary)
MASTER_HOSTNAME=greenplum001
declare -a MIRROR_DATA_DIRECTORY=(/data/mirror /data/mirror )
(4)运行初始化程序
[gpadmin@greenplum001 ~]$ gpinitsystem -c gpconfigs/gpinitsystem_config -h /usr/local/greenplum-db/hostfile_gpinitsystem
(5)Continue with Greenplum creation Yy|Nn (default=N),输入Y
(6)等待最后初始化成功
(7)给gpadmin设置环境变量,添加以下内容
[gpadmin@greenplum001 ~]$ vim ~/.bashrc
source /usr/local/greenplum-db/greenplum_path.sh
export MASTER_DATA_DIRECTORY=/data/master/gpseg-1
export PGPORT=5432
export PGUSER=gpadmin export PGDATABASE=default_login_database_name
export export LD_PRELOAD=/lib64/libz.so.1 ps
[gpadmin@greenplum001 ~]$ source ~/.bashrc
(8)分发到备用主机002上,
[gpadmin@greenplum001 ~]$ scp ~/.bashrc greenplum002:~/
[gpadmin@greenplum002 software]$ source ~/.bashrc
第6章 Greenplum使用
(1)启动Greenplum
[gpadmin@greenplum001 greenplum-db]$ bin/gpstart
(2)创建数据库
[gpadmin@greenplum001 greenplum-db]$ createdb -p 5432 -e -U gpadmin test
(3)登陆数据库
[gpadmin@greenplum001 greenplum-db]$ psql -d test -U gpadmin
(4)创建表
test=# create table student(id int,name character(10),age int) distributed by(id);
(5)插入数据
test=# insert into student values(1001,'李四',13);
(6)查询数据
test=# select *from student;
id | name | age
------+--------------+-----
1001 | 李四 | 13
(1 row)
(7)退出
test=# \q

(7)关闭greenplum
[gpadmin@greenplum001 greenplum-db]$ bin/gpstop
(7)配置客户端ip,允许指定ip访问,添加指定ip
[gpadmin@greenplum001 gpseg-1]$ cd /data/master/gpseg-1/
[gpadmin@greenplum001 gpseg-1]$ vim pg_hba.conf
host all gpadmin 101.66.195.28/32 trust
(8)加完之后需要重启greenplum,这样101.66.195.28就可以访问greenplum机器了
第7章 代码查询使用
(1)创建配置文件
(1)导入pom包
(1)创建连接数据库工具类
package com.sqchan.qzpoint.util; import java.io.InputStream; import java.util.Properties; /** * * 读取配置文件工具类 */ public class ConfigurationManager { private static Properties prop = new Properties(); static { try { InputStream inputStream = ConfigurationManager.class.getClassLoader() .getResourceAsStream("comerce.properties"); prop.load(inputStream); } catch (Exception e) { e.printStackTrace(); } } //获取配置项 public static String getProperty(String key) { return prop.getProperty(key); } //获取布尔类型的配置项 public static boolean getBoolean(String key) { String value = prop.getProperty(key); try { return Boolean.valueOf(value); } catch (Exception e) { e.printStackTrace(); } return false; } } (2)创建连接池 package com.sqchan.qzpoint.util; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.Serializable; import java.sql.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Properties; /** * 德鲁伊连接池 */ public class DataSourceUtil implements Serializable { public static DataSource dataSource = null; static { try { Properties props = new Properties(); props.setProperty("url", ConfigurationManager.getProperty("jdbc.url")); props.setProperty("username", ConfigurationManager.getProperty("jdbc.user")); props.setProperty("password", ConfigurationManager.getProperty("jdbc.password")); props.setProperty("initialSize", "5"); //初始化大小 props.setProperty("maxActive", "20"); //最大连接 props.setProperty("minIdle", "5"); //最小连接 props.setProperty("maxWait", "60000"); //等待时长 props.setProperty("timeBetweenEvictionRunsMillis", "2000");//配置多久进行一次检测,检测需要关闭的连接 单位毫秒 props.setProperty("minEvictableIdleTimeMillis", "600000");//配置连接在连接池中最小生存时间 单位毫秒 props.setProperty("maxEvictableIdleTimeMillis", "900000"); //配置连接在连接池中最大生存时间 单位毫秒 props.setProperty("validationQuery", "select 1"); props.setProperty("testWhileIdle", "true"); props.setProperty("testOnBorrow", "false"); props.setProperty("testOnReturn", "false"); props.setProperty("keepAlive", "true"); props.setProperty("phyMaxUseCount", "100000"); dataSource = DruidDataSourceFactory.createDataSource(props); } catch (Exception e) { e.printStackTrace(); } } //提供获取连接的方法 public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } // 提供关闭资源的方法【connection是归还到连接池】 // 提供关闭资源的方法 【方法重载】3 dql public static void closeResource(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection) { // 关闭结果集 // ctrl+alt+m 将java语句抽取成方法 closeResultSet(resultSet); // 关闭语句执行者 closePrepareStatement(preparedStatement); // 关闭连接 closeConnection(connection); } private static void closeConnection(Connection connection) { if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } } private static void closePrepareStatement(PreparedStatement preparedStatement) { if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } private static void closeResultSet(ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } } (1)创建sql工具类 package com.sqchan.qzpoint.util import java.sql.{Connection, PreparedStatement, ResultSet} trait QueryCallback { def process(rs: ResultSet) } class SqlProxy { private var rs: ResultSet = _ private var psmt: PreparedStatement = _ /** * 执行修改语句 * * @param conn * @param sql * @param params * @return */ def executeUpdate(conn: Connection, sql: String, params: Array[Any]): Int = { var rtn = 0 try { psmt = conn.prepareStatement(sql) if (params != null && params.length > 0) { for (i <- 0 until params.length) { psmt.setObject(i + 1, params(i)) } } rtn = psmt.executeUpdate() } catch { case e: Exception => e.printStackTrace() } rtn } /** * 执行查询语句 * 执行查询语句 * * @param conn * @param sql * @param params * @return */ def executeQuery(conn: Connection, sql: String, params: Array[Any], queryCallback: QueryCallback) = { rs = null try { psmt = conn.prepareStatement(sql) if (params != null && params.length > 0) { for (i <- 0 until params.length) { psmt.setObject(i + 1, params(i)) } } rs = psmt.executeQuery() queryCallback.process(rs) } catch { case e: Exception => e.printStackTrace() } } def shutdown(conn: Connection): Unit = DataSourceUtil.closeResource(rs, psmt, conn) } (1)使用sql处理,即正常sql操作即可 sqlProxy.executeQuery(connection, "select vip_id from dwd_membervip where vip_id=? and dn=?", Array(baseViplevel.vip_id, baseViplevel.dn), new QueryCallback { override def process(rs: ResultSet): Unit = { while (rs.next()) { vipid = String.valueOf(rs.getInt(1)) } rs.close() } })

浙公网安备 33010602011771号