AlloyDBの拡張を使ってVertex AIで公開したAPIを呼び出す

:::note info 
[ZOZO Advent Calendar 2022](https://qiita.com/advent-calendar/2022/zozo) カレンダー Vol.4 の 2日目の記事です。
:::
# はじめに
こんにちは。昨日に引き続きMLOpsブロックの岡本が担当させていただきます。
昨日は[サービングを楽にできる？？ Vertex AIを利用した推論APIの作成検討](https://qiita.com/okmtz/private/f8bf3725eeb0c83f9ffa)というタイトルでVetex AIを使った推論APIのサービングについて書かせていただきました。

本日はGoogle Cloudのデータベースサービスに関する内容になります。
Google I/O 2022でGoogle Cloudの新しいデータベースサービスである[AlloyDB for PostgreSQL](https://cloud.google.com/alloydb?hl=ja)が発表され、2022/11現在はプレビュー版としてサービス提供されています。
自分の所属チームでは今のところAlloyDBを採用した実績はありませんが、利用する機会がないか伺い、技術調査を行なっているような段階です。

本記事ではAlloyDBのドキュメントを読んだ中でも気になった拡張（[google_ml_integration](https://cloud.google.com/alloydb/docs/vertex-ai/invoke-predictions)）について、実際に利用してみた内容を記載しています。

# AlloyDBとは
Google Cloudが提供するフルマネージドなPostgreSQL互換のデータベースサービスです。

## 特長
AlloyDBには以下のような特長があり、標準のPostgreSQLと比較して高い性能を持っています。
- 高可用性
  - AlloyDBは1つのクラスタストレージ, プライマリインスタンスとフェイルオーバー用のレプリカ, リードレプリカから構成されており。可用性についてはメンテナンスを含めた[99.99%のSLA](https://cloud.google.com/alloydb?hl=ja#:~:text=%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82-,%E9%AB%98%E5%8F%AF%E7%94%A8%E6%80%A7,%E3%81%97%E3%81%A6%E5%BE%A9%E6%97%A7%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)を提供しています。
- 優れたパフォーマンス
  - パフォーマンスについては標準的なPostgreSQLと比較して、トランザクションで4倍, 分析クエリで最大100倍の性能を発揮すると言われています。(https://cloud.google.com/blog/ja/products/databases/introducing-alloydb-for-postgresql)

- データ形式の最適化
  - データの保持についてAlloyDBでは行形式のデータを列指向に変換するという機能を持っています。PostgreSQLと聞くと行指向データベースをイメージしますが、AlloyDBでは実行するクエリを元に機械学習エンジンがデータを適切な形式に変換してくれるため、行指向のデータと列指向のデータの両方を扱うことができます。

詳細については[公式ドキュメント](https://cloud.google.com/alloydb/docs/overview)の他、解説記事(https://dev.classmethod.jp/articles/summarize-information-on-the-new-db-alloydb-for-postgresql-in-google-cloud-and-actually-touched-it/) や解説動画(https://youtu.be/B1-phJUntw4) が非常に参考になりました。

# AlloyDBの拡張を使ってVertex AIで公開したAPIを呼び出す
本題です。
[AlloyDBのドキュメント](https://cloud.google.com/alloydb/docs/vertex-ai/invoke-predictions)を見ると`Invoke Vertex AI predictions`なる項目があり、AlloyDBのデータベースからVertex AIのonline predictionsを呼び出す方法について記載されています。
今までデータベースから直接APIを叩きたいケースに遭遇したことがなかったため、興味があり実際にVertex AI Endpointを呼び出せるか実験してみました。

## 準備
#### 1. Vertex AI EndpointにAPIを公開する
Vertex AIにAPIをデプロイします。
本記事とは内容がずれるため、こちらの手順については説明を省きます。
自分は過去記事（[サービングを楽にできる？？ Vertex AIを利用した推論APIの作成検討](https://qiita.com/okmtz/private/f8bf3725eeb0c83f9ffa)）で作成したAPIをサンプルとして利用しました。
#### 2. AlloyDBのクラスタを構成する
AlloyDBのクラスタを構成します。
こちらの手順についても本記事では省かせていただきます。
[公式ドキュメント](https://cloud.google.com/alloydb/docs/project-enable-access)に記載されていますが、ドキュメントは2022/11時点では英語版のみの提供となっているため、前述した解説記事(https://dev.classmethod.jp/articles/summarize-information-on-the-new-db-alloydb-for-postgresql-in-google-cloud-and-actually-touched-it/) が丁寧でわかりやすいかと思います。

#### 3. AlloyDBで利用するサービスアカウントに権限を付与する
AlloyDBで利用するサービスアカウントに`roles/aiplatform.user`を付与します。
Google提供のサービスアカウントについてはデフォルトだとコンソールに表示されないため、`Google提供のロール付与を含める`にチェックを入れる必要があるところに注意です。
`service-PROJECT_NUMBER@gcp-sa-alloydb.iam.gserviceaccount.com`の形式になっているため、PROJECT_NUMBERの部分をご自身のプロジェクト番号で置き換えてください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576866/49bfbc87-64b2-abfc-d1d4-b7998e371c0c.png" width=90%>
鉛筆マークを押下し、`roles/aiplatform.user`を対象のサービスアカウントに付与してください、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576866/6084777e-075b-71cb-13db-8a76f5444cb4.png" width=90%>

#### 4. 拡張のinstall, ユーザーへの実行権限付与
`google_ml_integration`拡張をデータベースに作成します。
これを行うには、psqlコマンドでデータベースにアクセスする必要があります。(https://cloud.google.com/alloydb/docs/connect-psql)
AlloyDBクラスタを作成したのと同じVPCネットワーク上にCompute Engineのインスタンスを起動してSSH接続し、↓のコマンドを実行してください。
※ インスタンスに外部IPが付与されているか、対象のVPCネットワークにNATが構成されている必要があります。
```terminal
sudo apt-get update && sudo apt-get install -y postgresql postgresql-contrib
```
次にクラスタに接続するためにプライマリインスタンスのIPアドレスを確認します。こちらの値をコピーしておきます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576866/47921663-1cb1-6a34-49b8-bb3122030673.png" width=90%>
再びCompute Engineに戻り、以下のコマンドを実行してデータベースにアクセスします。PRIVATE_IPの部分はプライマリインスタンスのIPアドレスで置き換えてください。また、アクセス時にクラスタ作成時に設定したパスワードが必要です。

```terminal
psql -h PRIVATE_IP -U postgres
```
データベースにアクセスできたら、サンプルのデータベースを作成し、データベースの切り替えを行います。
```terminal
postgres=> CREATE DATABASE test;
CREATE DATABASE
postgres=> \c test
psql (13.8 (Debian 13.8-0+deb11u1), server 14.4)
WARNING: psql major version 13, server major version 14.
         Some psql features might not work.
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
You are now connected to database "test" as user "postgres".
```
以下のコマンドにより必要な拡張をインストールできます
```terminal
test=> CREATE EXTENSION IF NOT EXISTS google_ml_integration;
CREATE EXTENSION
```
次に拡張を利用するDBのユーザーに権限を付与します。
```terminal
test=> GRANT EXECUTE ON FUNCTION ml_predict_row TO postgres;
GRANT
```

## APIの呼び出し
ML_PREDICT_ROW関数の引数にVertex AI Endpointのエンドポイントとrequest bodyを指定して実行することでAPIの呼び出しが可能です。
### 関数の引数
以下の`MODEL_ENDPOINT`と`ARGS`を置き換えてください。
```
ML_PREDICT_ROW (MODEL_ENDPOINT, ARGS)
```
`MODEL_ENDPOINT`の形式は以下になります。それぞれの値はVertex AI Endpointのコンソール画面からSample Requestの項目を押下すると確認することができます。
`projects/PROJECT_ID/locations/REGION_ID/endpoints/ENDPOINT_ID`
今回自分がVertex AIで公開したAPIのrequest bodyは以下の形式で指定する必要があるため、この値を`ARGS`に指定します。
```json
{"instances": [{"feature": 0.5}]}
```

### 関数の実行
以下のように関数を指定して実行することでAPIのレスポンスを確認することができました。
```terminal
test=> select ML_PREDICT_ROW ('projects/test-okamoto-370109/locations/us-central1/endpoints/2209195937132183552', '{"instances": [{"feature": 0.5}]}');

# ↓レスポンス
   ml_predict_row                                                                                                                   
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 {"predictions": [{"score": 0.85, "id": 2}], "deployedModelId": "816572101577146368", "model": "projects/866774327361/locations/us-central1/models/8658453957619744768", "modelDisplayName": "vertex-ai-endpoint-tutorial", "modelVersionId": "1"}
(1 row)

```

# まとめ & 所感
AlloyDBでは拡張であるgoogle_ml_integrationをインストールすることでデータベース上でVertex AIにデプロイしたAPIを割と簡単に呼び出すことができました。
SQLのクエリで特定のデータをフィルタして、推論APIの引数に渡し、推論APIを呼び出すことで推論結果を確認するといった作業がDBからできるため、stg環境等で調査・分析を行う際に利用できそうという所感です。
本格的な分析目的では今後もBigQueryを使用することが多いと思いますが、APIから参照しつつデータの中身の分析も行いたいような場合にAlloyDBを利用するという方法もありそうです。
現在はプレビュー版となっていますが、今後Google Cloudの主要なデータベースサービスの1つにはなると思うので引き続き動向を追っていければと思います。