watsonx.data 2.0.0 で Data cache を構成してみた (キャッシュ編 その2)

# はじめに
watsonx.data はキャッシュを構成する事により Presto (Java) エンジンを使用した照会のパフォーマンスを向上する事ができます。
本投稿内の Presto は全て Presto (Java) を意味しています。

参考文献
[RaptorX: Building a 10X Faster Presto](http://prestodb.io/blog/2021/02/04/raptorx/)

この文書によると Presto のキャッシュは階層構造になっており、5種類の異なるキャッシュを構成する事により、リモートのストレージからメタデータやデータの取得に要する時間を大幅に短縮する事ができます。
watsonx.data 2.0.0 に含まれる Presto でも この5種類のキャッシュはサポートされており構成する事が可能です。参考文献の内容とwatsonx.dataで キャッシュの名前や指定できるプロパティーが一部異なりますが目的や特徴は同じで、下記の5種類のキャッシュを構成する事ができます。


|キャッシュの種類|キャッシュの場所|キャッシュの場所|特徴|
|:---|:---|:---|:---|
|Metastore versioned cache|コーディネーター|メモリー|メタデータのキャッシュ|
|File list cache|コーディネーター|メモリー|ファイルのリストのキャッシュ|
|File and stripe footer cache|ワーカー|メモリー|ファイルの記述子、Stripe、フッターのキャッシュ|
|Data cache|ワーカー|ディスク|読み取ったデータのキャッシュ|
|Fragment result cache|ワーカー|ディスク|分割して処理されたデータのキャッシュ|

キャッシュのアーキテクチャーを図にすると以下のようになります。
詳しくは参考文献をご覧ください。
5種類のキャッシュの内、Metastore versioned cache と File and stripe footer cache については watsonx.data 2.0.0 ではデフォルトで使用可能となっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1359991/74b833b9-2b0c-de3a-c0d7-0c740753567c.png)

今回は、5種類のキャッシュの中から Data cache について構成方法をご紹介します。
Data cache はデフォルトでは使用可能になっていないため構成手順に従って構成する必要があります。

**File list cache については以下の記事をご参照ください。**
[watsonx.data 2.0.0 で File list cache を構成してみた (キャッシュ編 その1)](https://qiita.com/hkanba/items/f59254364bb5ab79360b)

**Fragment result cache については以下の記事をご参照ください。**
[watsonx.data 2.0.0 で Fragment result cache を構成してみた (キャッシュ編 その3)](https://qiita.com/hkanba/items/79fa05a6082f4981c543)

## Data cache について
ここで Data cache について、もう少し詳しく説明します。
Presto のワーカーは、リモートストレージから読み取ったデータを元のデータの形式 (圧縮や暗号化されている場合でも) で1MBの単位でキャッシュとしてワーカーのローカル・ディスクに保存します。
コーディネーターは、実行要求があったSQLの結果がキャッシュに含まれるワーカーに処理をスケジュールします。もしこのワーカーが忙しかったり使用可能でない場合は、SQLの結果がキャッシュに含まれていなくても 別のワーカーに処理をスケジュールします。この仕組みを Soft affinity scheduling と呼んでいます。
この仕組みにより、一度読み込まれて Data cache に保存されたデータを繰り返し リモート・ストレージから読む事を防いで照会のパフォーマンスを向上する事ができます。以下に Data cache を構成する手順を記述します。

## Data cache の構成手順
参考文献 (watsonx.data 2.0.0 のマニュアル)
[Enhancing the query performance through caching](https://www.ibm.com/docs/en/watsonx/watsonxdata/2.0.x?topic=administering-enhancing-query-performance-through-caching)

Data cache は wxdengine カスタム・リソースに Data cacheのプロパティーを追加する事により構成します。以下が Data cache を構成するプロパティーとなります。
|プロパティー|意味|
|:---|:---|
|cacheStorageClass|Data cacheを作成するストレージ・クラス|
|cacheStorageSize|キャッシュとして使用するストレージのサイズ|
|cache_alluxio_max_cache_size|Data cacheとして使用する最大サイズ|

watsonx.data 2.0.0 の Presto の Data cache では、TTL (キャッシュの有効期間) を設定する事ができませんが、将来のバージョンで設定できるようになる事を期待しましょう。

今回は 新規に作成した Persistent Volume (PV)をData cache のストレージとして使用します。watsonx.data 2.0.x のマニュアル上ではオプションとなっていますが、PVを新規に作成作成する事により、ワーカー・ポッドがマウントしたローカル・ボリュームをキャッシュとして使用する事ができるため、キャッシュの読み書きのパフォーマンスの向上を期待する事ができます。
ODF等の既存のコンテナ・ストレージのストレージ・クラスを使用すると短い手順で Data cache を構成する事ができますが、キャッシュの読み書きがネットワーク経由となり遅延が発生する可能性があります。

### 1.OCPクラスターにログイン
"oc login" コマンドでOCPクラスターにログインします。

### 2.watsonx.data のプロジェクトに変更
作業中のプロジェクトをwatsonx.data がインストールされているプロジェクトに変更します。今回の環境では watsonx.data は 名前スペース zen にインストールされています。
```
$ export PROJECT_CPD_INST_OPERANDS=zen
$ oc project ${PROJECT_CPD_INST_OPERANDS}
```
### 3.ワーカー・ノードの中に必要なディレクトリーを作成
デバッグセッションで、OpenShiftの全ワーカー・ノードの中に必要なディレクトリーを作成します。
#### ① ワーカーノードの確認
"oc get node"でOCPのノードの一覧を出力して、NAMEとROLESからワーカーノードを判断します。ストレージノードは対象外です。
今回の環境では worker-1～worker-5 がワーカーノードになります。
```
$ oc get node
NAME        STATUS   ROLES                  AGE   VERSION
NAME        STATUS   ROLES                  AGE   VERSION
master-1    Ready    control-plane,master   12d   v1.27.14+95b99ee
master-2    Ready    control-plane,master   12d   v1.27.14+95b99ee
master-3    Ready    control-plane,master   12d   v1.27.14+95b99ee
storage-1   Ready    worker                 12d   v1.27.14+95b99ee
storage-2   Ready    worker                 12d   v1.27.14+95b99ee
storage-3   Ready    worker                 12d   v1.27.14+95b99ee
worker-1    Ready    worker                 12d   v1.27.14+95b99ee
worker-2    Ready    worker                 12d   v1.27.14+95b99ee
worker-3    Ready    worker                 12d   v1.27.14+95b99ee
worker-4    Ready    worker                 12d   v1.27.14+95b99ee
worker-5    Ready    worker                 12d   v1.27.14+95b99ee
```
#### ② ワーカー・ノードの中に必要なディレクトリーを作成
全てのワーカーノードの中に、Data cache が使用するディレクトリーを作成します。
このディレクトリーを作成するファイルシステムには、Data cache を作成するために十分な容量が必要となります。今回の環境では /var の下に十分な容量があるため /var の下にサブディレクトリーを作成します。
PV は Data cache が構成される Presto のPodの数だけ必要になります。コーディネーターとワーカー両方のポッドに Data cache が作成されます。今回の環境ではコーディネーターのポッドが1個、ワーカーのポッドが5個稼働していますので6個のPVが必要です。
少々複雑ですが、各PVはワーカーノードの中の特定のディレクトリー (path)を指定して作成します。ポッドが起動する時に Data cahe のためにどのPVを使用するかは制御できませんので、どのPVが使用されても良いように、全てのワーカーノードの中に予めPV用の6個のディレクトリーを作成しておきます。
以下にその手順を示します。
まず、"oc debug node/<ワーカーノード名>" を実行して、ワーカーノードの中に入ります。Warningが表示される場合がありますが無視します。少し待つとプロンプトが表示されますので "chroot /host" を実行します。
この後でPV用の6個のディレクトリーを作成します。ディレクトリーが作成された事を確認したら "exit" を 2回実行してノードのデバッグから抜けます。
この作業を全てのノードで実行します。

```
$ oc debug node/worker-1
Warning: would violate PodSecurity "baseline:v1.24": host namespaces (hostNetwork=true, hostPID=true), hostPath volumes (volume "host"), privileged (container "container-00" must not set securityContext.privileged=true)
Starting pod/worker-1-debug ...
To use host binaries, run `chroot /host`
Pod IP: 192.168.252.14
If you don't see a command prompt, try pressing enter.
sh-4.4# chroot /host
sh-5.1# mkdir -p /var/dataCache/pv1
sh-5.1# mkdir -p /var/dataCache/pv2
sh-5.1# mkdir -p /var/dataCache/pv3
sh-5.1# mkdir -p /var/dataCache/pv4
sh-5.1# mkdir -p /var/dataCache/pv5
sh-5.1# mkdir -p /var/dataCache/pv6
sh-5.1# ls /var/dataCache
pv1  pv2  pv3  pv4  pv5  pv6
sh-5.1# exit
exit
sh-4.4# exit
exit
Removing debug pod ...
```
### 4.PVを作成するYAMLファイルを作成
PVを作成するためのYAMLファイルを作成します。
・storageClassName には任意の名前を指定します。
・path には 2 のステップでワーカーノードに作成したディレクトリーを指定します。
・nodeAffinity の values には、ワーカーノード名を列挙します。
name と path が異なる6個のYAMLファイルを作成します。
data-cache-pv2.yaml では、"name: data-cache-storage-pv2","path: /dev/dataCache/pv2" のような指定をして6個のYAMLファイルを作成します。

例)
```
$ cat data-cache-pv1.yaml
apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: data-cache-storage-pv1
  spec:
    capacity:
      storage: 10Gi
    volumeMode: Filesystem
    accessModes:
    - ReadWriteOnce
    persistentVolumeReclaimPolicy: Delete
    storageClassName: data-cache-storage
      local:
        path: /var/dataCache/pv1
  nodeAffinity:
      required:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - worker-1
            - worker-2
            - worker-3
            - worker-4
            - worker-5
```
### 5.PVを作成
"oc apply -f <YAMLファイル>" で6個のYAMLファイルを指定して、6個のPVを作成します。
```
$ oc apply -f data-cache-pv1.yaml
persistentvolume/data-cache-storage-pv1 created
..........
$ oc apply -f data-cache-pv6.yaml
persistentvolume/data-cache-storage-pv6 created
```
### 6.Data cache を設定する Presto のエンジンIDを確認
```
$ oc get wxdengine -o custom-columns='DISPLAY NAME:spec.engineDisplayName,ENGINE ID:metadata.labels.engineName'
DISPLAY NAME   ENGINE ID
presto-01      presto-01
```
### 7.Data cache を設定する Prestoエンジンのステートフルセットを全て削除
```
$ oc delete statefulset -l engineName=presto-01
statefulset.apps "ibm-lh-lakehouse-presto-01-coordinator-blue" deleted
statefulset.apps "ibm-lh-lakehouse-presto-01-presto-worker" deleted
statefulset.apps "ibm-lh-lakehouse-presto-01-single-blue" deleted
```
### 8.wxdengine カスタム・リソース に patch を適用して Data cache を構成
"oc patch" コマンドは statefulset を削除した直後に実行する必要があるため、コピー＆ペーストできるように用意しておく事をお勧めします。

今回は下記のプロパティーの設定で Data cache を作成します。
cacheStorageSize の単位が **Gi** ,cache_alluxio_max_cache_size の単位が **GB** である事に注意してください。
|プロパティー|値|
|:---|:---|
|cacheStorageClass|data-cache-storage|
|cacheStorageSize|10Gi|
|cache_alluxio_max_cache_size|10GB|

"oc patch"コマンドで Data cache を設定
```
$ oc patch wxdengine/lakehouse-presto-01 --type=merge -p '{ "spec": { "cacheStorageClass":"data-cache-storage","cacheStorageSize":"10Gi","cache_alluxio_max_cache_size": "10GB" } }'
wxdengine.watsonxdata.ibm.com/lakehouse-presto-01 patched
```
しばらくすると Presto のステートフルセットとポッドが再起動しますので確認します。
数分以上かかる場合がありますので辛抱強く待ちます。
```
$ oc get statefulset | grep presto
ibm-lh-lakehouse-presto-01-coordinator-blue    1/1     8m9s
ibm-lh-lakehouse-presto-01-presto-worker       5/5     8m9s
ibm-lh-lakehouse-presto-01-single-blue         0/0     8m11s

$ oc get pod | grep presto
ibm-lh-lakehouse-presto-01-coordinator-blue-0      1/1     Running     0    8m27s
ibm-lh-lakehouse-presto-01-presto-worker-0         1/1     Running     0    8m27s
ibm-lh-lakehouse-presto-01-presto-worker-1         1/1     Running     0    8m27s
ibm-lh-lakehouse-presto-01-presto-worker-2         1/1     Running     0    8m27s
ibm-lh-lakehouse-presto-01-presto-worker-3         1/1     Running     0    8m27s
ibm-lh-lakehouse-presto-01-presto-worker-4         1/1     Running     0    8m27s
```
### 9.ポッドの中に /mnt/flash/data ディレクトリーが作成されている事を確認
```
$ oc exec -it ibm-lh-lakehouse-presto-01-presto-worker-0 -- bash
bash-4.4$ ls /mnt/flash
data
```
/mnt/flash/data ディレクトリーはコーディネーターのポッドの中にも作成されています。念のため全てのポッドの中に /mnt/flash/data ディレクトリーが作成されている事を確認しましょう。

### 10.Persistent Volume Claim (PVC) を確認
マニュアルには記載がありませんが Data cache を作成すると Persistent Volume Claim (PVC) が作成され、4 と 5  のステップで作成したPVと接続 (Bound) されている事が確認できます。
```
$ oc get pvc | grep data-cache
ibm-lh-cache-mount-ibm-lh-lakehouse-presto-01-coordinator-blue-0  Bound  data-cache-storage-pv4  10Gi  RWO  data-cache-storage  13m
ibm-lh-cache-mount-ibm-lh-lakehouse-presto-01-presto-worker-0      Bound  data-cache-storage-pv1  10Gi  RWO  data-cache-storage  13m
ibm-lh-cache-mount-ibm-lh-lakehouse-presto-01-presto-worker-1      Bound  data-cache-storage-pv2  10Gi  RWO  data-cache-storage  13m
ibm-lh-cache-mount-ibm-lh-lakehouse-presto-01-presto-worker-2      Bound  data-cache-storage-pv6  10Gi  RWO  data-cache-storage  13m
ibm-lh-cache-mount-ibm-lh-lakehouse-presto-01-presto-worker-3      Bound  data-cache-storage-pv3  10Gi  RWO  data-cache-storage  13m
ibm-lh-cache-mount-ibm-lh-lakehouse-presto-01-presto-worker-4      Bound  data-cache-storage-pv5  10Gi  RWO  data-cache-storage  13m
```
1番左の列が作成された PVCの名前、3番目の列がPVの名前です。2番目の列が全て Bound であれば、PVC と PV が接続されていて、作成した PV が Data cache として正常に使用可能である事が確認できます。Bound ではなく Available になっている場合は PV が Data cache として使用されませんので Data cache の作成手順に問題が無いか確認して作り直す必要があります。
# おわりに
今回は watsonx.data 2.0.0 の Presto の照会のパフォーマンスを向上するためのキャッシュの1つである Data cache の構成について紹介しました。
watsonx.data 1.1.x でも全く同じ手順で構成する事ができます。

**キャッシュを削除する手順については、以下の記事をご参照ください。**
[watsonx.data 2.0.0 で 構成したキャッシュを削除する (キャッシュ編 その4)](https://qiita.com/hkanba/items/123baa8aacf8ae64ca84)