OCI Data Flowを使ってオブジェクト・ストレージからADBへデータをロードする -- Part 3

本ブログは、[オラクル・クラウドの個人シリーズ・ブログ](https://qiita.com/letian/items/10152a4fec813c1b7d98)の1つです。

# 初めに
Oracle Cloud Infrastructure（OCI）Data Flowは、[Apache Spark](https://spark.apache.org/) ™アプリケーションを実行するためのフルマネージド・サービスです。特に大規模なデータの処理に向きます。

OCIオブジェクト・ストレージ上のファイルを読み込み、Autnomous DBへのデータロード処理を例にして、OCI Data Flowでの実現方法を三回を分けて紹介したいと思います。

- [Part 1](https://qiita.com/liu-wei/items/b2408b85c8f258183047): Apache Sparkを使って、ローカル環境でPythonプログラムを実行する方法。
- [Part 2](https://qiita.com/liu-wei/items/eb3c57ed6da656e581cd): アプリケーションをOCIへデプロイし、実行する方法。
- <strong>Part 3 (本文)</strong>: プライベート・エンドポイントを経由し、ADBへデータをロードする方法。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/459a6996-9aa8-71ae-6155-56039515274d.png", width="550">

__ステップ__
- [1. 事前準備](#1-事前準備)
  - [1-1. 関連OCIリソースの作成](#1-1-関連ociリソースの作成)
  - [1-2. ローカル環境での動作確認](#1-2-ローカル環境での動作確認)
  - [1-3. Docker のインストールと起動](#1-3-docker-のインストールと起動)
  - [1-4. アーカイブ(archive.zip)の作成](#1-4-アーカイブarchivezipの作成)
- [2. OCIでアプリケーションの作成と実行](#2-ociでアプリケーションの作成と実行)
  - [2-1. プライベート・エンドポイントの作成](#2-1-プライベートエンドポイントの作成)
  - [2-2. アプリケーションの作成](#2-2-アプリケーションの作成)
  - [2-3. アプリケーションの実行](#2-3-アプリケーションの実行)

# 1. 事前準備
## 1-1. 関連OCIリソースの作成
__IAMリソース__
|リソース・タイプ|名前|コメント|
|:--|:--|:--|
|コンパートメント|PoC|検証用コンパートメント|
|バケット|dataflow-logs|データ・ロード・ログの格納先|
|グループ|Data_Flow_Grp|検証用ユーザーを入れる|
|ポリシー|Data_Flow_Policy||

ポリシーのステートメント：
```
Allow group Data_Flow_Grp to read buckets in compartment PoC
Allow group Data_Flow_Grp to manage dataflow-family in compartment PoC
Allow group Data_Flow_Grp to manage objects in compartment PoC where ALL {target.bucket.name='dataflow-logs', any {request.permission='OBJECT_CREATE', request.permission='OBJECT_INSPECT'}}
```

__ネットワーク・リソースとインスタンス__
|リソース・タイプ|項目|内容|コメント|
|:--|:--|:--|:--|
|Subnet|タイプ|プライベート|ADBとComputeの格納先|
|Service GW|サービス|`All <Region_Key> Services in Oracle Services Network`|データ・フローから、プライベートADBに接続|
|NAT GW|||ローカルのVMから、外部へアクセス|
|Route Table|ルール|ターゲット: Service GW<br>宛先：`All <Region_Key> Services in Oracle Services Network`||
||ルール|ターゲット: NAT GW<br>宛先：0.0.0.0/0||
|Security List|Ingress|XX.XX.XX.XX/32, TCP 22|踏み台のIP アドレスを指定|
||Egress|0.0.0.0/0, 全てのプロトコル||
|Autonomous DB|ワークロード・タイプ|データ・ウェアハウス||
||アクセス・タイプ|プライベート・エンドポイント|Walletで接続|
|Compute|OS|Oracle Linux 8||
||用途|1.ローカル環境での動作確認<br>2. アーカイブファイルの作成|プライベート・サブネットにあるので、踏み台を経由してアクセスする。|

__ADBプライベート・エンドポイントURLの取得__
ADBの詳細画面から、URLをコピーしておいてください（STEP 2-1で使う）。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/9bd1e32d-8b9c-6caf-4e3e-e9bb85ba951c.png", width="500">

## 1-2. ローカル環境での動作確認
アプリケーションをOCIへデプロイする前、ローカル環境での動作確認を強く推奨します。詳細は、[前回（Part 1）の記事](https://qiita.com/liu-wei/items/b2408b85c8f258183047)をご参照ください。

※、検証用のソース(Python)は、パブリックADBの例でしたが、プライベートADBにも適用します。

## 1-3. Docker のインストールと起動
前回の[Part 2](https://qiita.com/liu-wei/items/eb3c57ed6da656e581cd)で紹介した内容と同じです。既に実施した場合、このステップを飛ばしてください。
__Docker のインストール__
```bash
sudo dnf install -y dnf-utils zip unzip
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y docker-ce --nobest
```

__Docker の起動__
```bash
[opc@linux8-private ~]$ sudo systemctl start docker
[opc@linux8-private ~]$ sudo systemctl enable docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service ¨ /usr/lib/systemd/system/docker.service.
[opc@linux8-private ~]$
```

## 1-4. アーカイブ(archive.zip)の作成
前回の[Part 2](https://qiita.com/liu-wei/items/eb3c57ed6da656e581cd)で紹介した内容と同じです。既に実施した場合、このステップを飛ばしてください。

パッケージャ・ツール・イメージをダウンロードします。
コマンド：`sudo docker pull phx.ocir.io/oracle/dataflow/dependency-packager:latest`
```
[opc@linux8-private ~]$ sudo docker pull phx.ocir.io/oracle/dataflow/dependency-packager:latest
latest: Pulling from oracle/dataflow/dependency-packager
<中略>
Status: Downloaded newer image for phx.ocir.io/oracle/dataflow/dependency-packager:latest
phx.ocir.io/oracle/dataflow/dependency-packager:latest
[opc@linux8-private ~]$
```
一時フォルダ(`/tmp/shared`)を用意してください。`requirements.txt`（1行のみ）を作成し、関連のJARファイルと共にその下に保存します。
```bash
mkdir /tmp/shared
chmod 777 /tmp/shared
echo oci > /tmp/shared/requirements.txt
cp -p /home/opc/download/ojdbc/ojdbc11.jar  /tmp/shared
cp -p /home/opc/download/ojdbc/ucp11.jar /tmp/shared
cp -p /home/opc/download/ojdbc/oraclepki.jar /tmp/shared
cp -p /home/opc/download/hdfs/third-party/lib/bcpkix-jdk15on-1.70.jar /tmp/shared
cp -p /home/opc/download/hdfs/third-party/lib/bcprov-jdk15on-1.70.jar /tmp/shared
```

dockerコマンドでアーカイブを作成します。
コマンド：`sudo docker run --rm -v $(pwd):/opt/dataflow --pull always -it phx.ocir.io/oracle/dataflow/dependency-packager:latest -p 3.8`
```bash
[opc@linux8-private ~]$ cd /tmp/shared
[opc@linux8-private shared]$ ll
total 15452
-rw-r--r--. 1 opc opc  963713 Mar 11 05:01 bcpkix-jdk15on-1.70.jar
-rw-r--r--. 1 opc opc 5867298 Mar 11 05:01 bcprov-jdk15on-1.70.jar
-rw-r--r--. 1 opc opc 6971601 Mar 29 08:57 ojdbc11.jar
-rw-r--r--. 1 opc opc  490830 Mar 29 08:57 oraclepki.jar
-rw-rw-r--. 1 opc opc       4 May 24 04:18 requirements.txt
-rw-r--r--. 1 opc opc 1513648 Mar 29 08:57 ucp11.jar
[opc@linux8-private shared]$ sudo docker run --rm -v $(pwd):/opt/dataflow --pull always -it phx.ocir.io/oracle/dataflow/dependency-packager:latest -p 3.8
<中略>
Scanning for local jars in your current folder to be included in archive.zip ...
The following jar files will be included in the archive.zip:
/opt/dataflow/ojdbc11.jar
/opt/dataflow/ucp11.jar
/opt/dataflow/oraclepki.jar
/opt/dataflow/bcpkix-jdk15on-1.70.jar
/opt/dataflow/bcprov-jdk15on-1.70.jar
Are you sure you want to put all these jar files(5) into archive.zip? [Y/n]y
<中略>
archive.zip is generated!
[opc@linux8-private shared]$
```

`archive.zip`と`version.txt`の２つファイルが作成されました。`archive.zip`をOCIオブジェクト・ストレージにアップロードしてください。
```
[opc@linux8-private shared]$ ll archive.zip version.txt
-rw-r--r--. 1 2001 2000 84600576 May 24 13:38 archive.zip
-rw-r--r--. 1 2001 2000      664 May 24 13:38 version.txt
[opc@linux8-private shared]$
```

OCI-CLIは既にインストールと設定済であれば、次のコマンドでアップロードできます。
コマンド例：`oci os object put -bn MyBucket --file archive.zip`

# 2. OCIでアプリケーションの作成と実行
## 2-1. プライベート・エンドポイントの作成
OCIメニュー → Analytics & AI → Data Lake → Data Flow → Create private endpoint

`DNS zones to resolve`: ADBプライベート・エンドポイントURLを入力
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/ae48c54c-9301-ce8f-4e0d-3d1b4a5b79d5.png", width="600">
作成開始後の状態: Creating → Inactive
※、"Inactive"の状態で、アプリケーションの実行は可能です。

作成ボタンをクリックすると、次のようなエラーが発生した場合：
メッセージ：`Unable to process JSON input`
可能な原因：`DNS zones to resolve`は未入力か、入力内容は不正。
対策：ADBのプライベート・エンドポイントURLを正しく入力する。

## 2-2. アプリケーションの作成
OCIメニュー → Analytics & AI  → Data Lake → Data Flow → Create application
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/b9e159ab-2702-1ab7-ba16-19ea51be5707.png)

アプリケーション名を入力し、Sparkバージョンとシェイプを選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/5b70a8b3-a76a-fb30-5a66-0b519f1ab028.png", width="500">

プログラムのタイプ(Python)と置き場所を指定してください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/d8679da0-04f9-bcfc-fcae-fd56e36e9cf6.png", width="500">

アーカイブファイルとログの置き場所を指定します。（`dataflow-logs`というバケットを事前に作成しておく）。

アプリケーション・ログ：`oci://<bucket-name>@<Object_Storage_Namespace>`
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/ce2708be-40a6-21d3-eac9-cb3f474c5767.png", width="500">

画面下部の<strong>Show advanced options</strong>をクリックし、プライベート・エンドポイントを選択してから、作成を開始します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/41ce61c3-cad4-bef5-316d-31518f4a29c4.png", width="500">

## 2-3. アプリケーションの実行
アプリケーション詳細画面に、Run (実行)をクリックして、実行を開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/5bdbf96d-de6a-7048-9e0b-67513b9b0e99.png)
実行する前、シェイプの指定ができますが、この例ではデフォルトのままで進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/ccf2cd74-73fe-289a-4da1-521d74f8d9c0.png)

実行ステータス：
Accepted (受入れ済)　→ In progress (進行中)　→  Succeed (成功)、或いは Failed (失敗)

この例では、<strong>受入れ済から進行中まで</strong>約10分間かかり、<strong>進行中から成功完了まで</strong>の実行時間(Duration)は、2分34秒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/05ec3dbb-547f-509f-0ef7-e25363414e49.png)

アプリケーション実行後、プライベート・エンドポイントの状態は、"Inactive"から"<font color=blue>Active</font>"に変わりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/b59fea40-7fd2-e364-ed45-5b96b29fca68.png)

実行成功後、テーブルの中身を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/b93e20bd-f79e-1c87-f3c0-26f98b3d4bad.png)

以上です。

----
__関連記事__
[オラクル・クラウドの個人シリーズ・ブログ](https://qiita.com/liu-wei/items/10152a4fec813c1b7d98)
[OCI Data Flowを使ってオブジェクト・ストレージからADBへデータをロードする -- Part 1](https://qiita.com/liu-wei/items/b2408b85c8f258183047)
[OCI Data Flowを使ってオブジェクト・ストレージからADBへデータをロードする -- Part 2](https://qiita.com/liu-wei/items/eb3c57ed6da656e581cd)

----
__OCI データ・フロー・ドキュメント__
[製品サイト](https://www.oracle.com/jp/big-data/data-flow/)
[オフィシャル・ドキュメント](https://docs.public.oneportal.content.oci.oraclecloud.com/ja-jp/iaas/data-flow/using/home.htm)
[データ・フロー・チュートリアル](https://docs.oracle.com/ja-jp/iaas/data-flow/data-flow-tutorial/dfs_tut_front.htm)
[データ・フロー・アプリケーションへのサードパーティ・ライブラリの追加](https://docs.oracle.com/ja-jp/iaas/data-flow/using/third-party-libraries.htm)
[プライベート・ネットワークへのデータ・フローのアクセスの許可](https://docs.oracle.com/ja-jp/iaas/data-flow/using/pe-allowing.htm)