Debian 11によるApache Drillの構築

# 概要
以前構築したHadoop分散環境上のデータをクエリできるようにするため、Apache DrillをDistributed Modeで構築します。

https://qiita.com/eS5tYXRzdWRh/items/e35870046224ec0a2cd6

# 環境
Debian 11 bullseye (AMD64)

# ノード構成
完全分散モードで構築したクラスタをそのまま用います。
Distributed ModeのDrill環境を構築するため、全てのクラスタノードにセットアップを行います。

以下はHadoopの構成です。

|Hostname|IP address|NameNode|DataNode|ResourceManager|NodeManager|
|:-------|:-------|:-------|:-------|:-------|:-------|
|kyoto|192.168.10.111|Yes|Yes|Yes|Yes|
|tokyo|192.168.10.112|No|Yes|No|Yes|
|osaka|192.168.10.113|No|Yes|No|Yes|

# Replicated Zookeeperの構築
Drill環境を構築する前に、Zookeeperをセットアップしますが、今回はこちらも全てのクラスタで動作させるReplicated環境で構築します。

https://zookeeper.apache.org/doc/current/zookeeperStarted.html#sc_RunningReplicatedZooKeeper

まず、インストール先のディレクトリとデータディレクトリを作成します。簡単のために前回作成したHadoop用のユーザーをオーナーとしています。

```bash
root@kyoto:~# mkdir /opt/zookeeper
root@kyoto:~# mkdir /var/zookeeper
root@kyoto:~# chown hadoop:hadoop /opt/zookeeper
root@kyoto:~# chown hadoop:hadoop /var/zookeeper
```
次に、インストール先のディレクトリでパッケージを展開し、インストールします。

```bash
root@kyoto:~# su - hadoop
hadoop@kyoto:~$ cd /opt/zookeeper
hadoop@kyoto:~$ wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
hadoop@kyoto:~$ tar zxvf apache-zookeeper-3.8.4-bin.tar.gz -C /opt/zookeeper --strip-components=1
```

展開が終わったら、設定ファイルを編集します。

```bash
hadoop@kyoto:~$ cd conf/
hadoop@kyoto:~$ cp zoo_sample.cfg zoo.cfg
```

```:/opt/zookeeper/conf/zoo.cfg@kyoto
tickTime=2000
dataDir=/var/zookeeper
clientPort=2181
initLimit=5
syncLimit=2

server.1=0.0.0.0:2888:3888
server.2=tokyo:2888:3888
server.3=osaka:2888:3888
```

ここで、server.1はkyotoノードのIDですが、このホスト名を0.0.0.0としないと他のノードから3888に接続できなかったため、こうしています。

IDを指定するmyidファイルを作成します。これはデータディレクトリに置きます。

```:/var/zookeeper/myid@kyoto
1
```

kyotoノードにおけるZookeeperのインストールと設定は以上です。

同様に他のノードにおいてもディレクトリの作成、パッケージの展開、Zookeeperの設定を行います。インストール方法は全く同じのため、ここでは設定ファイルのみ記載します。

```:/opt/zookeeper/conf/zoo.cfg@tokyo
tickTime=2000
dataDir=/var/zookeeper
clientPort=2181
initLimit=5
syncLimit=2

server.1=kyoto:2888:3888
server.2=0.0.0.0:2888:3888
server.3=osaka:2888:3888
```

```:/var/zookeeper/myid@tokyo
2
```

```:/opt/zookeeper/conf/zoo.cfg@osaka
tickTime=2000
dataDir=/var/zookeeper
clientPort=2181
initLimit=5
syncLimit=2

server.1=kyoto:2888:3888
server.2=tokyo:2888:3888
server.3=0.0.0.0:2888:3888
```

```:/var/zookeeper/myid@osaka
3
```

これで全てのノードにおいてインストールと設定が終わりました。

最後にZookeeperを起動します。全てのノードで起動させます。

```bash
hadoop@kyoto:~$ /opt/zookeeper/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
```

```bash
hadoop@tokyo:~$ /opt/zookeeper/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
```

```bash
hadoop@osaka:~$ /opt/zookeeper/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
```

起動させると、Zookeeperはお互いに通信し、どのノードがリーダーとなるかを決定します。稼働状況を確認します。

```bash
hadoop@kyoto:~$ /opt/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: leader
```

```bash
hadoop@tokyo:~$ /opt/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower
```

```bash
hadoop@osaka:~$ /opt/zookeeper/bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: follower
```

これにより、kyotoノードがリーダーとなり、他のノードはフォロワーになっていることが確認できました。

# Distributed Mode Apache Drillの構築

Zookeeperが稼働したら次はDrillの構築です。Drillもクラスタ化させるために、Distributed Modeで構築します。

まず、インストール先のディレクトリとデータディレクトリを作成します。こちらも簡単のためにHadoopユーザーをオーナーとしています。

```bash
root@kyoto:~# mkdir /opt/drill
root@kyoto:~# chown hadoop:hadoop /opt/drill
```
次に、インストール先のディレクトリでパッケージを展開し、インストールします。

```bash
root@kyoto:~# su - hadoop
hadoop@kyoto:~$ cd /opt/drill
hadoop@kyoto:~$ wget https://dlcdn.apache.org/drill/1.21.1/apache-drill-1.21.1.tar.gz
hadoop@kyoto:~$ tar zxvf apache-drill-1.21.1.tar.gz -C /opt/drill --strip-components=1
```

展開が終わったら、設定ファイルを編集します。

```:/opt/drill/conf/drill-override.conf@kyoto
drill.exec: {
  cluster-id: "drill-cluster",
  zk.connect: “kyoto:2181,tokyo:2181,osaka:2181”
}
```

このままでは、クラスタの認識がされなかったので、drill-env.shでDRILL_HOST_NAMEをコメントアウトします。

```:/opt/drill/conf/drill-env.sh@kyoto
export DRILL_HOST_NAME=`hostname`
```

以上でインストールと設定は終了です。他のノードでも全く同様のインストールと設定を行います。

最後にDrillを起動します。全てのノードで起動させます。

```bash
hadoop@kyoto:~$ /opt/drill/bin/drillbit.sh start
Starting drillbit, logging to /opt/drill/log/drillbit.out
```
```bash
hadoop@tokyo:~$ /opt/drill/bin/drillbit.sh start
Starting drillbit, logging to /opt/drill/log/drillbit.out
```
```bash
hadoop@osaka:~$ /opt/drill/bin/drillbit.sh start
Starting drillbit, logging to /opt/drill/log/drillbit.out
```

起動していれば以下のURLからWeb UIにアクセスできます。

http\://kyoto:8047/
http\://tokyo:8047/
http\://osaka:8047/

テストとしてQuery画面で
```SQL
SELECT * FROM dfs.`/opt/drill/sample-data/nation.parquet`;
```
とすると、Drillに付属するサンプルデータをクエリすることができます。

## HDFS上のファイルをクエリ

HDFS上のファイルをクエリするには、Storage設定を変更する必要があります。既存のdfsストレージ設定を編集してもいいですが、今回は新たにhdfsストレージ設定を作成します。

Storage -> Plugin Management -> Create

Storage Name: hdfs

```Json:Configuration
{
  "type": "file",
  "connection": "hdfs://kyoto:8020/",
  "workspaces": {
    "root": {
      "location": "/",
      "writable": false,
      "defaultInputFormat": null,
      "allowAccessOutsideWorkspace": false
    }
  },
  "formats": {
    "parquet": {
      "type": "parquet"
    }
  },
  "authMode": "SHARED_USER",
  "enabled": true
}
```

設定はいずれか1つのDrillノードで行えば、他のDrillノードにも自動的に反映されます。

テストするために、データをHDFSへコピーしてクエリします。

```bash
hadoop@osaka:~$ hdfs dfs -mkdir /data
hadoop@osaka:~$ hdfs dfs -put /opt/drill/sample-data/nation.parquet /data/
```

DrillのQuery画面で

```SQL
SELECT * FROM hdfs.`/data/nation.parquet`;
```

とすると、HDFS上のデータをクエリすることができます。