だいたいゼロから始めるApache Zeppelin(設定編)

## シリーズのリンク

1. [機能紹介編](https://qiita.com/muterion111/items/d141557e8c551c556de6 "だいたいゼロから始めるApache Zeppelin(機能紹介編)")(一度はお読みください)
1. [インストール・起動・停止編](https://qiita.com/muterion111/items/4caf9c227fac12c1560c "だいたいゼロから始めるApache Zeppelin(インストール・起動・停止編)")
1. 設定編
1. [Sparkインタープリタ編](https://qiita.com/muterion111/items/557197d58a5eaee2af86 "だいたいゼロから始めるApache Zeppelin(Sparkインタープリタ編)")
1. [その他インタープリタ編](http://qiita.com "だいたいゼロから始めるApache Zeppelin(その他インタープリタ編用)")(予定)

## 要約
- リッスンするポートやノートブック保存先などの  
  Apache Zeppelin自体の設定は環境変数またはJavaプロパティの変更によって行う。
- 依存するライブラリの指定などのインタープリタの設定は  
  Apache Zeppelinの設定画面から行う。

## 設定の種類
Apache Zeppelinでの設定対象は大きく分けて下記の２つに分けられます。

- Apache Zeppelin自体
- インタープリタ

Apache Zeppelin自体の設定は下記の２つの内容を変更することで行います。

- 環境変数
- Javaプロパティ

上記それぞれを下記の設定ファイルに定義するのが良いかと思います。

|設定方法|コピー元ファイル|設定ファイル(コピーしたファイルをリネームする)|  
|:-:|:-:|:-:|  
|環境変数変更|conf/zeppelin-env.sh.template|conf/zeppelin-env.sh  
|Javaプロパティ変更|conf/zeppelin-site.xml.template|conf/zeppelin-site.xml|  

## Apache Zeppelin自体の共通の設定方法
前述しました通りApache Zeppelin自体の設定は
環境変数かJavaプロパティを変更することで行います。
これらを変更後にApache Zeppelinを再起動することで設定を反映できます。

### 環境変数
環境変数は下記のように`conf/zeppelin-env.sh`の
各環境変数に付けられたコメントアウトを外しつつ値を設定します。

```sh:conf/zeppelin-env.sh
# 設定前
# export ZEPPELIN_PORT                          # port number to listen (default 8080)

# 設定後
export ZEPPELIN_PORT=8888                       # port number to listen (default 8080)
```

### Javaプロパティ
Javaプロパティは下記のように`conf/zeppelin-site.xml`の
各要素`property`内の要素`value`の値を設定します
(`property`がコメントアウトされていれば外します)。

```xml:conf/zeppelin-site.xml
<!-- 設定前 -->
<!--
<property>
  <name>zeppelin.notebook.s3.kmsKeyRegion</name>
  <value>us-east-1</value>
  <description>AWS KMS key region in your AWS account</description>
</property>
-->

<!-- 設定後 -->
<property>
  <name>zeppelin.notebook.s3.kmsKeyRegion</name>
  <value>ap-northeast-1</value>
  <description>AWS KMS key region in your AWS account</description>
</property>
```

## ノートブック保存先設定
ここからは特記すべき設定について説明していきます。
まずはノートブックの保存先です。
ノートブックの保存先は環境変数`ZEPPELIN_NOTEBOOK_STORAGE`か
Javaプロパティ`zeppelin.notebook.storage`に
下記のようにストレージに対応するクラスをFQCNで指定することで変更できます。
デフォルトはGitのローカルリポジトリである
`org.apache.zeppelin.notebook.repo.GitNotebookRepo`です。

|ストレージ|FQCN|  
|:-:|:-:|  
|Gitローカルリポジトリ|org.apache.zeppelin.notebook.repo.GitNotebookRepo|  
|ローカルファイルシステム|org.apache.zeppelin.notebook.repo.VFSNotebookRepo|  
|HDFS|org.apache.zeppelin.notebook.repo.FileSystemNotebookRepo|  
|Amazon S3|org.apache.zeppelin.notebook.repo.S3NotebookRepo|  
|Azure Storage|org.apache.zeppelin.notebook.repo.AzureNotebookRepo|  
|Google Cloud Storage|org.apache.zeppelin.notebook.repo.GCSNotebookRepo|  
|MongoDB|org.apache.zeppelin.notebook.repo.MongoNotebookRepo|  
|GitHub|org.apache.zeppelin.notebook.repo.GitHubNotebookRepo|  

これらのうちAmazon S3とGoogle Cloud Storage、GitHubを
ストレージにする場合の設定方法について説明していきます。

### Amazon S3
あらかじめ下記のものを用意する必要があります。

- [AWS CLI](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-welcome.html)で用いられる認証プロファイル`.aws/credentials`
- URLが`s3://(バケット名)/(任意のユーザ名)/`である
  [S3フォルダ](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/user-guide/create-configure-bucket.html)

下記のようにS3フォルダのURLを構成するバケット名と任意のユーザ名と
ストレージに対応するクラスをFQCNを設定します。

```sh:conf/zeppelin-env.sh
# 設定前
# export ZEPPELIN_NOTEBOOK_S3_BUCKET        # Bucket where notebook saved
# export ZEPPELIN_NOTEBOOK_S3_ENDPOINT      # Endpoint of the bucket
# export ZEPPELIN_NOTEBOOK_S3_USER          # User in bucket where notebook saved. For example bucket/user/notebook/2A94M5J1Z/note.json
(中略)
# export ZEPPELIN_NOTEBOOK_STORAGE              # Refers to pluggable notebook storage class, can have two classes simultaneously with a sync between them (e.g. local and remote).

# 設定後
export ZEPPELIN_NOTEBOOK_S3_BUCKET=(バケット名) # Bucket where notebook saved
# export ZEPPELIN_NOTEBOOK_S3_ENDPOINT      # Endpoint of the bucket
export ZEPPELIN_NOTEBOOK_S3_USER=(任意のユーザ名) # User in bucket where notebook saved. For example bucket/user/notebook/2A94M5J1Z/note.json
(中略)
export ZEPPELIN_NOTEBOOK_STORAGE=org.apache.zeppelin.notebook.repo.S3NotebookRepo              # Refers to pluggable notebook storage class, can have two classes simultaneously with a sync between them (e.g. local and remote).
```

もしくは

```xml:conf/zeppelin-site.xml
<!-- 設定前 -->
<!-- Amazon S3 notebook storage -->
<!-- Creates the following directory structure: s3://{bucket}/{username}/{notebook-id}/note.json -->
<!--
<property>
  <name>zeppelin.notebook.s3.user</name>
  <value>user</value>
  <description>user name for s3 folder structure</description>
</property>

<property>
  <name>zeppelin.notebook.s3.bucket</name>
  <value>zeppelin</value>
  <description>bucket name for notebook storage</description>
</property>

<property>
  <name>zeppelin.notebook.s3.endpoint</name>
  <value>s3.amazonaws.com</value>
  <description>endpoint for s3 bucket</description>
</property>

<property>
  <name>zeppelin.notebook.storage</name>
  <value>org.apache.zeppelin.notebook.repo.S3NotebookRepo</value>
  <description>notebook persistence layer implementation</description>
</property>
-->

<!-- 設定後 -->
<!-- Amazon S3 notebook storage -->
<!-- Creates the following directory structure: s3://{bucket}/{username}/{notebook-id}/note.json -->
<property>
  <name>zeppelin.notebook.s3.user</name>
  <value>(任意のユーザ名)</value>
  <description>user name for s3 folder structure</description>
</property>

<property>
  <name>zeppelin.notebook.s3.bucket</name>
  <value>(バケット名)</value>
  <description>bucket name for notebook storage</description>
</property>

<property>
  <name>zeppelin.notebook.s3.endpoint</name>
  <value>s3.amazonaws.com</value>
  <description>endpoint for s3 bucket</description>
</property>

<property>
  <name>zeppelin.notebook.storage</name>
  <value>org.apache.zeppelin.notebook.repo.S3NotebookRepo</value>
  <description>notebook persistence layer implementation</description>
</property>
```

上記を設定する場合は`conf/zeppelin-site.xml`内の
デフォルトであるGitNotebookRepoのものをコメントアウトする必要があります。

```xml:conf/zeppelin-site.xml
<!--
<property>
  <name>zeppelin.notebook.storage</name>
  <value>org.apache.zeppelin.notebook.repo.GitNotebookRepo</value>
  <description>versioned notebook persistence layer implementation</description>
</property>
-->
```

### Google Cloud Storage
あらかじめ下記のものを用意する必要があります。

- 役割`ストレージ オブジェクト管理者`が付与された
  [サービスアカウントキー](https://cloud.google.com/iam/docs/creating-managing-service-account-keys?hl=ja#iam-service-account-keys-create-gcloud)
- [Google Cloud Storageフォルダ](https://cloud.google.com/storage/docs/cloud-console?hl=ja)

下記のように`conf/zeppelin-env.sh`の環境変数`GOOGLE_APPLICATION_CREDENTIALS`に
上記のサービスアカウントキーへのパスを設定します。

```sh:conf/zeppelin-env.sh
# 設定前
# export GOOGLE_APPLICATION_CREDENTIALS         # Provide a service account key file for GCS and BigQuery API calls (overrides application default credentials)

# 設定後
export GOOGLE_APPLICATION_CREDENTIALS=(サービスアカウントキーへのパス)         # Provide a service account key file for GCS and BigQuery API calls (overrides application default credentials)
```

下記のようにGoogle Cloud StorageフォルダのURLとストレージに対応するクラスをFQCNを設定します。

```sh:conf/zeppelin-env.sh
# 設定前
# export ZEPPELIN_NOTEBOOK_GCS_STORAGE_DIR      # GCS "directory" (prefix) under which notebooks are saved. E.g. gs://example-bucket/path/to/dir
(中略)
# export ZEPPELIN_NOTEBOOK_STORAGE              # Refers to pluggable notebook storage class, can have two classes simultaneously with a sync between them (e.g. local and remote).

# 設定後
export ZEPPELIN_NOTEBOOK_GCS_STORAGE_DIR=(Google Cloud StorageフォルダのURL)      # GCS "directory" (prefix) under which notebooks are saved. E.g. gs://example-bucket/path/to/dir
(中略)
export ZEPPELIN_NOTEBOOK_STORAGE=org.apache.zeppelin.notebook.repo.GCSNotebookRepo              # Refers to pluggable notebook storage class, can have two classes simultaneously with a sync between them (e.g. local and remote).
```

もしくは

```xml:conf/zeppelin-site.xml
<!-- 設定前 -->
<!-- Google Cloud Storage notebook storage -->
<!--
<property>
  <name>zeppelin.notebook.gcs.dir</name>
  <value></value>
  <description>
    A GCS path in the form gs://bucketname/path/to/dir.
    Notes are stored at {zeppelin.notebook.gcs.dir}/{notebook-id}/note.json
 </description>
</property>

<property>
  <name>zeppelin.notebook.storage</name>
  <value>org.apache.zeppelin.notebook.repo.GCSNotebookRepo</value>
  <description>notebook persistence layer implementation</description>
</property>
-->

<!-- 設定後 -->
<!-- Google Cloud Storage notebook storage -->
<property>
  <name>zeppelin.notebook.gcs.dir</name>
  <value>(Google Cloud StorageフォルダのURL)</value>
  <description>
    A GCS path in the form gs://bucketname/path/to/dir.
    Notes are stored at {zeppelin.notebook.gcs.dir}/{notebook-id}/note.json
 </description>
</property>

<property>
  <name>zeppelin.notebook.storage</name>
  <value>org.apache.zeppelin.notebook.repo.GCSNotebookRepo</value>
  <description>notebook persistence layer implementation</description>
</property>
```

S3と同様に上記を設定する場合は`conf/zeppelin-site.xml`内の
デフォルトであるGitNotebookRepoのものをコメントアウトする必要があります。

```xml:conf/zeppelin-site.xml
<!--
<property>
  <name>zeppelin.notebook.storage</name>
  <value>org.apache.zeppelin.notebook.repo.GitNotebookRepo</value>
  <description>versioned notebook persistence layer implementation</description>
</property>
-->
```

### GitHub
あらかじめ下記のものを用意する必要があります。

- [GitHubアカウント](https://github.com)
- ノートブックの保存先となる[GitHubリポジトリ](https://github.com/new)
- スコープ`repo`が付与されている[アクセストークン](https://github.com/new)

下記のように`conf/zeppelin-site.xml`にGitHubリポジトリのURLとアクセストークンを設定します。

```xml:conf/zeppelin-site.xml
<!-- 設定前 -->
<!-- GitHub configurations
<property>
  <name>zeppelin.notebook.git.remote.url</name>
  <value></value>
  <description>remote Git repository URL</description>
</property>

<property>
  <name>zeppelin.notebook.git.remote.username</name>
  <value>token</value>
  <description>remote Git repository username</description>
</property>

<property>
  <name>zeppelin.notebook.git.remote.access-token</name>
  <value></value>
  <description>remote Git repository password</description>
</property>

<property>
  <name>zeppelin.notebook.git.remote.origin</name>
  <value>origin</value>
  <description>Git repository remote</description>
</property>

<property>
  <name>zeppelin.notebook.cron.enable</name>
  <value>false</value>
  <description>Notebook enable cron scheduler feature</description>
</property>
<property>
  <name>zeppelin.notebook.cron.folders</name>
  <value></value>
  <description>Notebook cron folders</description>
</property>
-->

<!-- 設定後 -->
<!-- GitHub configurations -->
<property>
  <name>zeppelin.notebook.git.remote.url</name>
  <value>(GitHubリポジトリのURL(git cloneで指定するもの))</value>
  <description>remote Git repository URL</description>
</property>

<property>
  <name>zeppelin.notebook.git.remote.username</name>
  <value>token</value>
  <description>remote Git repository username</description>
</property>

<property>
  <name>zeppelin.notebook.git.remote.access-token</name>
  <value>(アクセストークンの文字列)</value>
  <description>remote Git repository password</description>
</property>

<property>
  <name>zeppelin.notebook.git.remote.origin</name>
  <value>origin</value>
  <description>Git repository remote</description>
</property>

<property>
  <name>zeppelin.notebook.storage</name>
  <value>org.apache.zeppelin.notebook.repo.GitHubNotebookRepo</value>
  <description>versioned notebook persistence layer implementation</description>
</property>

<!--
<property>
  <name>zeppelin.notebook.cron.enable</name>
  <value>false</value>
  <description>Notebook enable cron scheduler feature</description>
</property>
<property>
  <name>zeppelin.notebook.cron.folders</name>
  <value></value>
  <description>Notebook cron folders</description>
</property>
-->
```

このストレージはデフォルトのストレージであるGitローカルリポジトリも有効になっています。
ノートブックの変更をコミットするとGitローカルリポジトリへ内容が反映され、
同時にGitHubリポジトリにプッシュされます。

## インタープリタ設定
インタープリタ設定はホーム画面やノートブック画面の
右上にあるユーザ名がリンクとなっているメニューをクリックすることで表示される
下記画像の項目`Interpreter`をクリックします。
![インタープリタ設定項目](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556213/76125254-2513-b000-4a45-89b28cd58ba0.png)  

使用できるインタープリタがそれなりに多いため、
遷移した画面の左上にある検索用テキストボックスに
設定対象のインタープリタの名前を入力してフィルタリングします。
![インタープリタ設定画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556213/c74d2f31-59c3-c534-230f-2ea0bc226b4c.png)  

フィルタリング後に表示されるインタープリタの設定一覧の右上にある
ボタン`edit`をクリックすることで設定の編集が可能になります。
![編集ボタン](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556213/11bca9bd-674c-be28-cf4d-2345fc04167f.png)  

ボタンをクリックすることで一覧`Properties`以下にある
名前が列`name`である設定を列`value`の入力値にすることができるようになります。
列`action`にあるボタンをクリックするとそれに対する設定はデフォルト値をとるようになります。
![設定編集一覧](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556213/8fda4859-4e28-25d5-61e7-7fdfdc5a6fca.png)  

一覧`Properties`の一番下にある行にて設定を追加することができます。
下記画像のある列`name`のテキストボックスに一覧にはない設定の名前、
列`action`にあるセレクトボックスで設定値に適切な入力タイプを指定しつつ、
列`value`に設定値を入力後にセレクトボックスの右隣にあるボタンをクリックすることで
この名前、値の設定を追加できます。
セレクトボックスで選択できる入力タイプは以下の通りです。

- テキストエリア(文字列に改行を含められます)
- 文字列
- 数値(数字のみの文字列になります)
- URL(編集後にリンクが生成されます)
- パスワード(文字列が隠蔽されます)
- チェックボックス

![設定追加](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556213/828be831-f7cf-1036-b29b-ca178d216186.png)  

一覧`Dependencies`以下にてインタープリタが処理するコードが依存する
ライブラリであるJarファイルを指定できます。
***
__注意：__
本来ならMavenの機能を用いるとインタープリタ再起動時に
指定されたJarファイルが自動的にダウンロードされるはずなのですが、
2020-01-15以降Mavenのセントラルリポジトリが
Apache Zeppelin内部で行っているhttpによるアクセスを受け付けなくなりました([参照](https://support.sonatype.com/hc/en-us/articles/360041287334))。
[このような修正](https://github.com/apache/zeppelin/pull/3370)がなされたのですが0.8.2ではこの修正がまだマージされていないため、
代わりに依存するJarファイル等を手動でダウンロードした後で
Jarファイルへのパスを下記テキストボックスに指定する方法を取ります。
***
下記画像のある列`artifact`にMavenでのライブラリのgroupId/artifactId/versionにより
文字列`(groupId):(artifactId):(version)`を入力することで依存性を設定できます。
このようにすると設定保存後にJarファイルが環境に存在しなければ
インタープリタが再起動された際に自動的にダウンロードされます。
またJarファイルが既に環境にあるならばそれへのパスを指定することでも設定できます。
インタープリタ実行時にJarファイルがクラスパスに追加されます。
![依存性設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556213/f89a4e3a-64b4-c151-4710-961873862265.png)  

下記画像にある青いボタン`Save`をクリックすることで設定の変更を保存できます。
この時設定インタープリタの再起動が自動的に行われます。
![設定変更保存](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556213/6f32efd5-85d0-291c-c0fb-8c4cbe36548c.png)

## その他設定(一部抜粋)
これまでの設定以外にも設定を変更する可能性が高いものを
以下に列挙していきます。

### Apache Zeppelinサーバのアドレス
```sh:conf/zeppelin-env.sh
export ZEPPELIN_ADDR="192.168.0.1"                          # Bind address (default 127.0.0.1)
```

もしくは

```xml:conf/zeppelin-site.xml
<property>
  <name>zeppelin.server.addr</name>
  <value>192.168.0.1</value>
  <description>Server binding address</description>
</property>
```

### Apache Zeppelinサーバのポート
```sh:conf/zeppelin-env.sh
export ZEPPELIN_PORT=18080                         # port number to listen (default 8080)
```

もしくは

```xml:conf/zeppelin-site.xml
<property>
  <name>zeppelin.server.port</name>
  <value>18080</value>
  <description>Server port.</description>
</property>
```

### Apache ZeppelinサーバのJavaオプション(メモリ以外)
```sh:conf/zeppelin-env.sh
export ZEPPELIN_JAVA_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Dspark.executor.memory=8g -Dspark.cores.max=8"                     # Additional jvm options. for example, export ZEPPELIN_JAVA_OPTS="-Dspark.executor.memory=8g -Dspark.cores.max=16"
```

### Apache ZeppelinサーバのJavaオプション(メモリ)
```sh:conf/zeppelin-env.sh
export ZEPPELIN_MEM="-Xms1024m -Xmx1024m -XX:MaxMetaspaceSize=512m"                          # Zeppelin jvm mem options Default -Xms1024m -Xmx1024m -XX:MaxPermSize=512m
```

### インタープリタのJavaオプション(メモリ以外)
```sh:conf/zeppelin-env.sh
export ZEPPELIN_INTP_JAVA_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps"                # zeppelin interpreter process jvm options.
```

### インタープリタのJavaオプション(メモリ)
```sh:conf/zeppelin-env.sh
export ZEPPELIN_INTP_MEM="-Xms1024m -Xmx1024m -XX:MaxMetaspaceSize=512m"                          # Zeppelin jvm mem options Default -Xms1024m -Xmx1024m -XX:MaxPermSize=512m
```

### cronスケジューラの有効化
```xml:conf/zeppelin-site.xml
<property>
  <name>zeppelin.notebook.cron.enable</name>
  <value>true</value>
  <description>Notebook enable cron scheduler feature</description>
</property>
<property>
  <name>zeppelin.notebook.cron.folders</name>
  <value></value>
  <description>Notebook cron folders</description>
</property>
```

Apache Zeppelinの設定一覧は[ここ](http://zeppelin.apache.org/docs/0.8.2/setup/operation/configuration.html)で記載されております。

## つづき
次回は[Sparkインタープリタ編](https://qiita.com/muterion111/items/557197d58a5eaee2af86 "だいたいゼロから始めるApache Zeppelin(Sparkインタープリタ編)")です。