Presto構築手順

# はじめに
Prestoを利用してHiveテーブル操作する機会があり、本記事はその時の手順となります。

> 参考: 構築手順(公式)
> https://prestodb.io/docs/current/installation.html

# そもそもPrestoとは？
* facebookが発表した大規模なデータセットに向いた分散クエリエンジン
* インタラクティブに結果を返せることを目指して開発された。
    * そのため、バッチ型のクエリエンジンであるHiveよりも圧倒的にレスポンスが早い。
* 様々なデータソースとの連携が可能。
    * Hive
    * MySQL
    * PostgreSQL
    * Kafka　など
* Biツールとの連携することでマイクロバッチ的に動かすことも可能。
    * Tableau
    * redash など

# バージョン情報
* OS: Ubuntu 16.04
* Presto: 0.213
* Hadoop: 2.7.3
* Python: 2.7.12
* Java: 1.8.0_181

# 事前準備
Prestoを利用するためにPythonとJavaが必要となるため、あらかじめ用意しておく。

## リポジトリ更新
 
```
sudo apt-get update
```

## Pythonインストール

```
sudo apt-get install python-pip python-dev
```

## Javaインストール

```
sudo apt-get install openjdk-8-jre
```

## 確認
* Javaのバージョンが`1.8.x`、Pythonのバージョンが`2.7.x`であることを確認する。

```
# Javaのバージョン確認
$ java -version
openjdk version "1.8.0_181"
OpenJDK Runtime Environment (build 1.8.0_181-8u181-b13-0ubuntu0.16.04.1-b13)
OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)

# Pythonのバージョン確認
$ python -V
Python 2.7.12
```

# Prestoインストール
## 資材ダウンロード & 解凍
まずはPresto用の資材をダウンロードし、希望のディレクトリに解凍する。
また、Prestoはrootユーザで実行させるため、ディレクトリの所有者を変更しておく。
さらに、個人的にディレクトリ名が長いのは好きではないので今回はシンボリックリンクも作成しておいた。

```
# 資材ダウンロード
wget https://repo1.maven.org/maven2/com/facebook/presto/presto-server/0.213/presto-server-0.213.tar.gz

# 解凍
sudo tar -zxvf ~/presto-server-0.213.tar.gz -C /usr/local

# ディレクトリの所有者変更
sudo chown -R root:root /usr/local/presto-server-0.213

# シンボリックリンク作成
sudo ln -s /usr/local/presto-server-0.213 /usr/local/presto
```

## 設定ファイル用ディレクトリ用意
Prestoでは、設定ファイル用のディレクトリを別途作成し、その中に設定ファイルを置く必要がある。
また、ディレクトリ名は`etc`にしろと言われている。他のディレクトリ名での実装も可能であるとは思うが、試したことはない。
資材を用意した時点でディレクトリの所有者をrootユーザに変更してあるため、ここからの作業はrootユーザで行う。

```
# rootユーザになる
sudo su

# 設定ファイル用ディレクトリ作成
mkdir /usr/local/presto/etc
```

## 設定ファイル用意
Prestoの動作には最低限、以下の設定ファイルが必要となる。

* config.properties
    * Prestoサーバの設定。CoordinatorとWorkerでそれぞれ別の設定が必要。
* jvm.config
    * JVMを立ち上げる際のコマンドラインオプション
* log.properties
    * ログレベルの設定
* node.properties
    * ノード固有の設定

これらの設定ファイルを先ほど作成した`etc`配下に順次追加していく。
config.propertiesはCoordinatorになるノードにのみCoordinator用の設定を入れ、残りはWorker用の設定を入れるのみで良い。
また、今回導入した手順はほとんど公式のインストール手順に記載されていたものなので、特にこだわりはない。

### Coordinator用config.properties
`presto/etc`配下に以下の内容の設定を配置する。

```ConfigFile:config.properties
coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8080
query.max-memory=5GB
query.max-memory-per-node=1GB
query.max-total-memory-per-node=2GB
discovery-server.enabled=true
discovery.uri=http://[Coordinator　hostname]:8080
```

### Worker用config.properties
`presto/etc`配下に以下の内容の設定を配置する。

```ConfigFile:config.properties
coordinator=false
http-server.http.port=8080
query.max-memory=50GB
query.max-memory-per-node=1GB
query.max-total-memory-per-node=2GB
discovery.uri=http://[Woker　hostname]:8080
```

### jvm.config
`presto/etc`配下に以下の内容の設定を配置する。

```ConfigFile:jvm.config
-server
-Xmx16G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError
```

### log.properties
`presto/etc`配下に以下の内容の設定を配置する。

```ConfigFile:config.properties
com.facebook.presto=INFO
```

### node.properties
`presto/etc`配下に以下の内容の設定を配置する。
`node.id`は識別用のIDのため、何でも良い。

```ConfigFile:config.properties
node.environment=dev
node.id=[node id]
node.data-dir=/var/presto/data
```

## Hive接続用設定
PrestoからHiveを利用するためには、追加で以下の設定が必要となる。

* catalog/hive.properties
* core-site.xml
* hdfs-site.xml

`core-site.xml`及び`hdfs-site.xml`はHadoopを実装した際にクラスタ内に作成されるファイルをそのまま利用する。

### hive.properties
Prestoから接続する先の設定は`etc`配下にさらに`catalog`というディレクトリを作成し、そこに配置する必要がある。

* ディレクトリ作成

```
mkdir /usr/local/presto/etc/catalog
```

* 設定内容
    * `hive.config.resources`はHadoopクラスタから持ってきたHive及びHDFSの設定の配置先を記す。

```
connector.name=hive-hadoop2
hive.metastore.uri=thrift://[hive hostname]:[hive metastore port]
hive.config.resources=/usr/local/presto/etc/hadoop/core-site.xml,/usr/local/presto/etc/hadoop/hdfs-site.xml
```

### core-site.xml及びhdfs-site.xml
これらの設定ファイルは上述の通り、Hadoopクラスタからscp等でファイルごと持ってくる。
私の環境では、HadoopをHortonworksのHDPで構築したため、以下のディレクトリに置いてあった。

```
/etc/hadoop/conf/core-site.xml
/etc/hadoop/conf/hdfs-site.xml
```

* 設定ファイルの配置
    * 今回はHadoop系の設定をまとめて配置しようと考えたため、`etc`の配下にさらにhadoopの設定用ディレクトリを作成し、そこに設定ファイルを配置した。

```
mkdir /usr/local/presto/etc/hadoop
```

## Presto CLIの導入
動作確認用にPrestoをコマンドラインで操作可能にするPresto CLIを導入した。

```
# Presto CLIダウンロード
wget https://repo1.maven.org/maven2/com/facebook/presto/presto-cli/0.213/presto-cli-0.213-executable.jar

# 希望のディレクトリに配置
mv presto-cli-0.213-executable.jar presto

# ファイルに実行権限を与える
chmod +x presto
```

# 動作確認
## 実行
クラスタ内の各ノードにて下記コマンドでPrestoを起動する。

```
# ディレクトリ移動
cd /usr/local/presto

# Prestoプロセス起動
sudo bin/launcher start
```

## 起動確認
Presto CLIを起動し、クラスタがしっかり起動しているか確認する。
確認としては、Presto CLIからnodeのリストを確認し、起動状況を確認する。
自身がクラスタに導入したマシンが全て記載されていればOK。
また、Coordinatorの割り当てが正しいかも確認しておく。

```
$ ./presto # Presto CLI起動
presto:default> select * from system.runtime.nodes;
 node_id |        http_uri        | node_version | coordinator | state  
---------+------------------------+--------------+-------------+--------
 4       | http://[node hostname]:8080 | 0.213        | false       | active 
 3       | http://[node hostname]:8080 | 0.213        | false       | active 
 2       | http://[node hostname]:8080 | 0.213        | false       | active 
 1       | http://[node hostname]:8080 | 0.213        | true        | active 
(4 rows)

Query 20181029_092400_00014_yxp9n, FINISHED, 2 nodes
Splits: 17 total, 17 done (100.00%)
0:00 [4 rows, 140B] [18 rows/s, 652B/s]
```

上記のようにクラスタ内の全てのノードの`state`が`active`になっていればOK。

## 接続確認
起動確認時と同様にPresto CLIからHive内のテーブルに接続できているか確認する。

```
$ ./presto --catalog hive --schema iris
presto:iris> show tables;
 Table 
-------
 iris  
(1 row)

Query 20190109_071025_00012_pzqat, FINISHED, 4 nodes
Splits: 53 total, 53 done (100.00%)
0:00 [1 rows, 18B] [5 rows/s, 100B/s]
```

上記のようにHive内のテーブルが確認できればOK。