💭

Snowpark Container Service上でRstudioを扱う

2024/02/13に公開

はじめに

データエンジニアの是枝です。
皆さんSPCSは使っていますか?アプリケーション以外にもデータ解析に使いたいという方はいるのではないでしょうか。
この記事では、SPCSでRstudioを使う方法を試したのでまとめてみました。Rstudio Serverのimageをsnowflakeにプッシュして使います。
snowflake界隈にはRユーザーがなかなかいませんが、R使ってみたい方はぜひ参考にしてみてください。

snowflake上で行うSPCS設定

snowflake上で行うSPCS設定方法ですが、こちらにまとめましたので省略させた頂きます。
https://zenn.dev/t_koreeda/articles/3437ca8c0eddfc#snowflakeの各種オブジェクトを用意する

今回は解析でボリュームも使いたいので、STAGEをENCRYPTION = (TYPE = 'SNOWFLAKE_SSE');を指定して作り直しておきます。
ちなみにsnowflakeで使うボリュームでは外部ステージは対応していません。

DROP STAGE tutorial_stage;
CREATE STAGE tutorial_stage
  DIRECTORY = ( ENABLE = true )
  ENCRYPTION = (TYPE = 'SNOWFLAKE_SSE');

参考:https://qiita.com/ak-sakatoku/items/ccfc32f11b110e83c1e0
https://docs.snowflake.com/en/developer-guide/snowpark-container-services/specification-reference#label-snowpark-containers-spec-volume

SPCSで使うimage

SPCS上使うRstudio Serverのimageをローカルにダウンロードした後、IMAGE REPOSITORYにPushします。

#imageのpull
docker pull kinngut/single-cell:latest
#tag付け
docker tag kinngut/single-cell:latest <registry_hostname>/tutorial_db/data_schema/tutorial_repository/kinngut/single-cell:latest
# login
docker login <registry_hostname> -u dev_admin
# push
docker push <registry_hostname>/tutorial_db/data_schema/tutorial_repository/kinngut/single-cell:latest

<registry_hostname>は SHOW IMAGE REPOSITORIES SQL コマンドを使用してリポジトリ URL として取得されるURLです。URL内のホスト名はレジストリのホスト名です。(例:myorg-myacct.registry.snowflakecomputing.com)

サービスの作成

サービスを定義します。解析用のファイルがあるので、ボリュームも定義していきます。

CREATE SERVICE singlecell
IN COMPUTE POOL tutorial_compute_pool
FROM SPECIFICATION $$
spec:
  containers:
  - name: singlecell
    image: <registry_hostname>/tutorial_db/data_schema/tutorial_repository/kinngut/single-cell:latest
    env:
      DISABLE_AUTH: true
    volumeMounts:
    - name: rstudio
      mountPath: /rstudio/data
  endpoints:
  - name: rstudioendpoint
    port: 8787
    public: true
  volumes:
  - name: rstudio
    source: "@TUTORIAL_DB.DATA_SCHEMA.tutorial_STAGE"
    uid: 1000
    gid: 1000
$$
MIN_INSTANCES=1
MAX_INSTANCES=1;

specの解説をします。

containers
コンテナの設定を含みます。ここでは、singlecellという名前のコンテナを定義しています。

  • name: コンテナの名前です。
  • image: コンテナイメージの場所を指定します。
  • env: コンテナ内で設定される環境変数を定義します。DISABLE_AUTHtrueに設定してRStudio Serverでの認証を外しています。
  • volumeMounts: コンテナ内の特定のパスにボリュームをマウントする設定です。
    • name: マウントするボリュームの名前です。
    • mountPath: コンテナ内でボリュームがマウントされるパスです。

endpoints
このサービスが外部からアクセス可能なエンドポイントを定義します。

  • name: エンドポイントの名前です。
  • port: エンドポイントがリッスンするポート番号です。
  • public: エンドポイントが公開されているかどうかを示します。trueの場合、エンドポイントは外部からアクセス可能です。

volumes
サービスで使用されるボリュームの設定です。

  • name: ボリュームの名前です。
  • source: ボリュームのソースを指定します。ここでは、Snowflakeのステージを指しています。
  • uid: ボリュームの所有者のユーザーIDです。
  • gid: ボリュームの所有者のグループIDです。

MIN_INSTANCES,MAX_INSTANCES
サービスが実行するコンテナインスタンスの最小数と最大数を指定します。これにより、サービスのスケーラビリティと可用性が管理されます。

uidとgidは、ステージ ボリュームにマウントされたファイルにアクセスするために必要となります。こちらを設定しないと、コンテナーが非root ユーザーとして実行されるためpermission deniedとなります。ファイルのユーザー権限に関連する潜在的なエラーを回避するには、仕様の一部としてコンテナーの UID (ユーザー ID) と GID (グループ ID) を設定することが重要です。

コンテナの UID と GID を取得するには、コンテナ内でidと叩きましょう。ちなみに私はRstudio Serverのターミナルから実行しました。

# (コンテナ内)
$ id
# 出力例
# uid=1000(root) gid=1000(root) groups=1000(root)

参考:https://tech-blog.rakus.co.jp/entry/20200826/docker

https://docs.snowflake.com/en/developer-guide/snowpark-container-services/specification-reference#spec-volumes-field-optional

Rstudio Serverを起動

Rstudio Serverを起動していきます。まずはエンドポイントを確認していきましょう。

SHOW ENDPOINTS IN SERVICE <サービス名>;

最初は「Endpoints provisioning in progress... check back in a few minutes」の表示が出ますが、数分待ってみると「ingress_url」列で無事エンドポイントが確認できるようになります。

指定されたエンドポイントにアクセスすると、snowflakeユーザーで認証を求められるので、ログインしてください。

Rstudioが開けました。

予めspecで設定したステージにファイルをアップロードすると、Rstudioのターミナルでボリュームに設定したパスの位置にファイルが確認できます。

rstudio@statefulset-0:~$ cd /rstudio/data
rstudio@statefulset-0:/rstudio/data$ ls
barcodes.tsv.gz  features.tsv.gz

もし、250MBを超えるファイルを内部ステージにアップロードする場合は、ローカルでsnowSQLを起動し、PUTコマンドを使用する必要がありますのでお気をつけください。

snowsql -a [アカウント名] -u [ユーザー名]
PUT file://[ローカルのファイルパス] @TUTORIAL_DB.DATA_SCHEMA.tutorial_STAGE;

結果

dev_admin#(no warehouse)@(no database).(no schema)>PUT file:///Users/t_koreeda/desktop/r/matrix.mtx.gz
                                                    @TUTORIAL_DB.DATA_SCHEMA.tutorial_STAGE;
+---------------+---------------+-------------+-------------+--------------------+--------------------+----------+---------+
| source        | target        | source_size | target_size | source_compression | target_compression | status   | message |
|---------------+---------------+-------------+-------------+--------------------+--------------------+----------+---------|
| matrix.mtx.gz | matrix.mtx.gz |   489938709 |   489938709 | GZIP               | GZIP               | UPLOADED |         |
+---------------+---------------+-------------+-------------+--------------------+--------------------+----------+---------+
1 Row(s) produced. Time Elapsed: 25.100s

参考:
https://docs.snowflake.com/en/user-guide/data-load-local-file-system-stage-ui?css#uploading-files-onto-a-stage
https://docs.snowflake.com/en/user-guide/data-load-local-file-system-stage#staging-the-data-files

Rstudioでirisデータの可視化

Rでのサンプルファイルと言ったらirisデータが有名です。早速ggplot2で可視化してみようと思います。

if (!requireNamespace("ggplot2", quietly = TRUE)) {
  install.packages("ggplot2")
}

# ggplot2をロード
library(ggplot2)

# irisデータセットを使用して散布図を作成
ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  geom_point() +
  theme_minimal() +
  labs(title = "Iris Dataset: Sepal Length vs Sepal Width",
       x = "Sepal Length",
       y = "Sepal Width")

irisデータも問題なく可視化されることが確認できました。

Rstudio Serverでパッケージのインストール

Rstudioでpackageのインストールを行って見たところ、いくつかのパッケージがインストールできませんでした。cranにアクセスできないようになっているみたいです。
内部でインターネットアクセスに制限がかかっていそうなので、回避方法を探索中です

(追記)こちらの解決策がわかりましたので紹介します。

> install.packages("remotes")
Warning in install.packages :
  unable to access index for repository http://cran.rstudio.com/src/contrib:
  cannot open URL 'http://cran.rstudio.com/src/contrib/PACKAGES'
Installing package into ‘/usr/local/lib/R/site-library’
(as ‘lib’ is unspecified)
Warning in install.packages :
  unable to access index for repository http://cran.rstudio.com/src/contrib:
  cannot open URL 'http://cran.rstudio.com/src/contrib/PACKAGES'
Warning in install.packages :
  package ‘remotes’ is not available for this version of R

A version of this package for your version of R might be available elsewhere,
see the ideas at
https://cran.r-project.org/doc/manuals/r-devel/R-admin.html#Installing-packages

SPCSが外部のインターネットに出るには、ネットワークルールを定義してEXTERNAL ACCESS INTEGRATIONといった操作が必要になります。
https://docs.snowflake.com/en/developer-guide/snowpark-container-services/additional-considerations-services-jobs#network-egress

ネットワークルールを定義してEXTERNAL ACCESS INTEGRATIONといった操作は以下になります。

USE ROLE ACCOUNTADMIN;

CREATE NETWORK RULE allow_all_rule
  TYPE = 'HOST_PORT'
  MODE= 'EGRESS'
  VALUE_LIST = ('0.0.0.0:443','0.0.0.0:80')
;

CREATE EXTERNAL ACCESS INTEGRATION all_access_integration
  ALLOWED_NETWORK_RULES = (allow_all_rule)
  ENABLED = true
;

ネットワークルールとEXTERNAL ACCESS INTEGRATIONを作成したら、先程のspecファイルに追記し、サービスを作り直してください。

CREATE SERVICE singlecell
IN COMPUTE POOL tutorial_compute_pool
FROM SPECIFICATION $$
spec:
  containers:
  - name: singlecell
    image: <registry_hostname>/tutorial_db/data_schema/tutorial_repository/kinngut/single-cell:latest
    env:
      DISABLE_AUTH: true
    volumeMounts:
    - name: rstudio
      mountPath: /rstudio/data
  endpoints:
  - name: rstudioendpoint
    port: 8787
    public: true
  volumes:
  - name: rstudio
    source: "@TUTORIAL_DB.DATA_SCHEMA.tutorial_STAGE"
    uid: 0
    gid: 0
$$
EXTERNAL_ACCESS_INTEGRATIONS = (ALL_ACCESS_INTEGRATION) #こちらに追記
MIN_INSTANCES=1
MAX_INSTANCES=1;

これで問題なくパッケージインストールができるようになります。

最後に

いかがだったでしょうか。これまでsnowflakeではPythonの使用が多かったと思いますが、SPCSのおかげで他の言語も使いやすくなっております。
ぜひとも自分のお気に入り言語をSPCSで使えるように環境構築してみてはいかがでしょうか?それでは、よいSPCSライフを!

GitHubで編集を提案

Discussion