Pivotal Greenplumを試してみる


仕事で必要になったので触ってみる。とりあえずcreate tableができるまで。

最近OSS化されまいたが。が、ソースからビルドする必要は無いので、バイナリをインストールします。
standaloneモードもありますが、仕事の都合上、マルチノードでの設定をしてみます。

##事前知識

Greenplumは、元々EMCが扱ってて、いろいろな経緯を経て、現在はPivotal Greenplumとなっています。
シェアードナッシング型の分散型RDBで、PostgreSQLを拡張してDWH用に特化させている。
そういう意味ではRedshiftに近い。

masterとsegment(slave)型を取る。

重要な役割を担うmasterはリダンダント構成を取ることもできる。が、ここでは省略します。

![gp](http://www.bluecode.jp/qiita/gp/001.png)

##前準備

###環境
今回は、MacのVMWare Fusion上にmaster,slaveともにCentOS6.7でVMを作成し、構築をしてみる。
もちろん、AzureやAWS上のサーバで物理サーバでもよい。

* master (CentOS6.7 RAM2GB)
* slave1 (CentOS6.7 RAM1GB)
* slave2 (CentOS6.7 RAM1GB)

インストールのテストなので、最低限の構成である。ちなみに、Greenplumの推奨RAMは16GBです。
また、DBはI/Oが全てなので、実運用においてはメモリ、ディスクともに高速な環境じゃないと意味がありません。

###OSの設定

テスト環境と変な手間を書けないため、

* selinuxをdisable
* iptablesをstop

としました。

```bash
#設定ファイル
vi /etc/selinx/conf

#設定コマンド
service iptables stop
chkconfig iptables off
```

という感じ。

###ツールのインストール

MinimalでインストールしたCentOSに以下のツールをインストールしました。
逆に言えば、下記以外はいりません。

* yum update
* yum groupinstall 'Development tools'
* yum install wget（必須ではない。ファイルの取得に利用）
* yum install ed（なぜか必須）

###hostnameの設定

####/etc/hosts

今回は、作業を効率化するために/etc/hostsに下記のように記述しました。なお、hostsの記述は、master,slave1,slave2の全てで行って下さい（相互に名前解決できる必要があるようです）。

IPは適当に変更して下さい。

```
192.168.77.140 master
192.168.77.141 slave1
192.168.77.142 slave2
```

###rootでssh証明書（パスフレーズ無し）ログインできるようにしておく

>ここからの作業は特に断らない限りmasterサーバのrootで行ないます。

masterサーバでslaveもコントロールできるように、masterからslave1,2に対してssh証明書でパスフレーズ無しでログインできるようにしておきます。

masterでkeyを生成し、slaveへ転送します。

```bash
cd
ssh-keygen -t rsa
cd .ssh

ssh-copy-id -i id_rsa.pub root@slave1
ssh-copy-id -i id_rsa.pub root@slave2
```

各サーバにログインできるか確認しておきます。

##インストール

インストール作業は、

* ファイルのダウンロードと解凍
* インストーラーによるファイルの展開
* 実行ユーザー作成やディレクトリ作成
* 設定スクリプトの実行
* Greenplumの起動
* psqlで使う

のようなステップです。ややこしいのは実行ユーザー(gpadmin)の作成や設定スクリプトの設定かなと。

###ダウンロード

Greenplumは、[Pivotalのサイトからダウンロード](https://network.pivotal.io/products/pivotal-gpdb)できます（登録必要）。

>直接のダウンロードURLがわからなったため、wgetが使えず、一度、ローカルにダウンロードしてから、masterにアップしました。

###解凍

とりあえず、rootのホームディレクトリである/rootに移動させ、解凍しました。

```bash
unzip greenplum-db-4.3.6.2-build-1-RHEL5-x86_64.zip
```

解凍するとインストーラーであるgreenplum-db-4.3.6.2-build-1-RHEL5-x86_64.binが展開されるのでそれを実行します。

```bash
./greenplum-db-4.3.6.2-build-1-RHEL5-x86_64.bin
```

インストーラーが起動し、いろいろ聞いてきますが、全てyes（一部ただEnterを押すだけ）で進めます。

###gpadminの作成と設定

####設定対象となるhostリストファイルを作成する

スクリプトを実行する対象のファイルをリスト化したファイルを作成します。

```bash
vi /tmp/hostfile_all

master
slave1
slave2
```
各ホスト名を記述します。/tmpに作成したのは、/root以下に作成すると、次に実行するスクリプト中でsu gpadminとして実行される際、読取り権限が無い！とエラーになるためです。

####スクリプトの実行

```bash
#環境変数の読み込み
source /usr/local/greenplum-db/greenplum_path.sh
#実行
gpseginstall -f /tmp/hostfile_all -u gpadmin -p <password>
```
\<password>は独自のものを設定して下さい。
このスクリプトの実行が完了すると、各マシンにgpadminユーザーが作成され、かつssh証明書ログインが可能となります。

####設定のチェック

下記スクリプトを実行するとgpadmin関連の設定が正しく行われているかチェックできます。

```bash
gpssh-exkeys -f /tmp/hostfile_all
.
.
[INFO] completed successfully
```

###マスターデータディレクトリを作成する

masterサーバが利用するデータエリアを作成します。

```bash
mkdir -p /data/master
chown gpadmin:gpadmin /data/master
```

###segment(slave)サーバが利用するディレクトリを作成する

データが置かれるエリアを作成します。

####スクリプト実行対象のホストリストファイルを作成

segmentだけを対象とするので、下記のようなリストを作成します。
今回は/tmpとする必要がありません。

```bash
vi hostfile_segonly

slave1
slave2
```

では、リストファイルを利用して実行します。
ここではsegment(slave)が2台ですが、20台あっても手間は同じなので、すごいですね。

```bash
#ディレクトリ作成
gpssh -f hostfile_segonly -e 'mkdir -p /data/primary'
gpssh -f hostfile_segonly -e 'mkdir -p /data/mirror'

#パーミッション変更
gpssh -f hostfile_segonly -e 'chown -R gpadmin:gpadmin /data/primary'
gpssh -f hostfile_segonly -e 'chown gpadmin:gpadmin /data/mirror'
```
上記ディレクトリ名からもわかるように、Greenplumでは、各ノードにデータをミラーすることができるようです。
ミラーは必須ではありません。

###設定ファイルを用意する

いくつかのテンプレートファイルが用意されているので、それをコピーして使います。
なお、ここからの作業はgpadminで行ないます。

```bash
#スイッチ
su - gpadmin
#環境変数読み込み
source /usr/local/greenplum-db/greenplum_path.sh
#テンプレートファイルのコピー
cp /usr/local/greenplum-db-4.3.6.2/docs/cli_help/gpconfigs/gpinitsystem_config ~/
#書込み権限付与
chmod 644 gpinitsystem_config
#編集
vi gpinitsystem_config
```

####設定例
長いですが、いじる箇所は少しです。

```bash
################################################
#### REQUIRED PARAMETERS
################################################

#### Name of this Greenplum system enclosed in quotes.
ARRAY_NAME="EMC Greenplum DW"

#### Naming convention for utility-generated data directories.
SEG_PREFIX=gpseg

#### Base number by which primary segment port numbers
PORT_BASE=40000

#### File system location(s) where primary segment data directories
declare -a DATA_DIRECTORY=(/data/primary)

#### OS-configured hostname or IP address of the master host.
MASTER_HOSTNAME=master

#### File system location where the master data directory
MASTER_DIRECTORY=/data/master

#### Port number for the master instance.
MASTER_PORT=5432

#### Shell utility used to connect to remote hosts.
TRUSTED_SHELL=ssh

#### Maximum log file segments between automatic WAL checkpoints.
CHECK_POINT_SEGMENTS=8

#### Default server-side character set encoding.
ENCODING=UNICODE

################################################
#### OPTIONAL MIRROR PARAMETERS
################################################


#### OS-configured hostname or IP address of the master host.
MASTER_HOSTNAME=master

#### File system location where the master data directory
MASTER_DIRECTORY=/data/master

#### Port number for the master instance.
MASTER_PORT=5432

#### Shell utility used to connect to remote hosts.
TRUSTED_SHELL=ssh

#### Maximum log file segments between automatic WAL checkpoints.
CHECK_POINT_SEGMENTS=8

#### Default server-side character set encoding.
ENCODING=UNICODE

################################################
#### OPTIONAL MIRROR PARAMETERS
################################################

#### Base number by which mirror segment port numbers
MIRROR_PORT_BASE=50000

#### Base number by which primary file replication port
REPLICATION_PORT_BASE=41000

#### Base number by which mirror file replication port
MIRROR_REPLICATION_PORT_BASE=51000

#### File system location(s) where mirror segment data directories
declare -a MIRROR_DATA_DIRECTORY=(/data/mirror)
```

###初期化実行

####対象ホストのリストファイルを作成する

先ほどもsegmentだけのリストを作成しましたが、再度作成します。
コピーしてもいいです。

```bash
vi hostfile_segonly

slave1
slave2
```
とします。

####初期化スクリプトの実行

クラスタを構成するスクリプトを実行します。

```bash
gpinitsystem -c gpinitsystem_config -h hostfile_segonly
```

>masterのリダンダント構成をとる場合はここで-Sオプションをつけるらしい。

途中で、

```bash
Continue with Greenplum creation Yy/Nn>
```
と聞いてくるのでyとします。

幾つか[WARN]もでるかもしれませんが、[ERROR]がでなければインストールは完了です。

###Greenplumの実行

```bash
#環境変数の定義
export MASTER_DATA_DIRECTORY=/data/master/gpseg-1
#デーモンのスタート
gpstart

#デーモンの停止
gpstop
```
exportは必要に応じて.bashrc等に記述します。

```bash
gpstart -d /data/master/gpgeg-1
gpstart -d /data/master/gpseg-1
```
ともできるようです。

>上記の操作はgpadminユーザーで行う。

##Greenplumを利用する
GreenplumはPostgreSQL拡張なのでクライアントとしてはpsqlが利用できます。

```bash
$ createdb testdb
$ psql -d testdb

testdb=#
```
となればOK。

```sql
#create
create table members(
	id int,
	name varchar(32)
)
distributed by (id);

#insert
insert into members(id,name) values(1,'hoge');

#select
select * from members;
```

まあ普通に動きます。

create tableの時にdistributed by (col)とすることで、そのキーで分散が制御できます。
Redshiftのdistkeyと同じ役割（たぶん）。

ベンチーマークや詳細設定は別の機会に実施してみたいと思います。

ノードの追加も試してみたい。とりあえず[メモ](https://support.pivotal.io/hc/en-us/articles/201202707-gpexpand-example-working-with-one-host-)だけ。