cover

dvc と oci object storage で巨大データのバージョン管理をする

巨大なデータをgitで管理する方法

私は普段 git を使ってプログラムのバージョン管理をしています。コードの変更の度にその状態を保存しておくことで、後で変更の経過を追うことができ、元の状態に戻すことも容易にできます。しかし、gitを使ってサイズの大きなデータを扱うのは容易ではありません。git-lfs という専用のツールも使えるのですが、github へのアップロードに容量制限があるため、あまり使いたくありません。

そこで今回は dvc というツールとoci object storageを使ってサイズの大きなファイルのバージョン管理を行ってみたいと思います。

dvcとは何か?Object Storageとは何か?

dvc を利用すると、データ自体は git の管理下とは別の場所に保存し、git ではそのデータのハッシュ値などを管理します。そのため、gitで管理するデータの容量を格段に節約することができます。

関係図

データ保存先としては別のディレクトリやオンプレミスで立てたサーバなどなんでも設定できます。クラウドの利用も可能で、例えば aws の s3 を利用することができますが、少しばかり利用料がかかってしまいます。そこで s3 互換のAPIを提供している oci object storage を使うことで、20GBの容量分を無料で保存することができます。

dvcのインストール

こちらがインストール手順です。

https://dvc.org/doc/install

私はuvを使ってチュートリアルを進めていきます。こうすることでpipパッケージを速くインストールできます。

作業用のフォルダを作成します。

uv init dvc-oci
cd dvc-oci

uv initで作成したフォルダは自動的にgit initされた状態になっています。git管理のフォルダじゃないとdvcが使えないので必ずgit initはしておいてください。

仮想環境を作り、シェルを起動します。

uv venv
source .venv/bin/activate

s3サポートのdvcをインストールします。

uv add --dev dvc[s3]

dvcが使えることを確認します。

dvc --help

ここまででgitのコミットをしておきます。

git add . -A
git commit -m 'install dvc'

プロジェクトの初期化

ここからはGet Startedを進めていきます。

https://dvc.org/doc/start

dvc環境を作成します。

dvc init

.dvcignore.dvcが作られました。.dvcignore.gitignoreなどのようにdvcの管理下から外したいファイルを記入します。.dvcはdvcの作業ディレクトリで基本的に編集することはありません。これらのファイルがgit stagingに勝手に追加されていることを以下で確認します。

git status

コミットします。

git commit -m "Initialize DVC"

データのトラッキング

チュートリアルではxmlを扱っていますが、バイナリの画像データを管理してみたいと思います。画像データはLolem Picsumを使わせていただきます。名前はimage.jpgとします。

mkdir data
curl -o data/image.jpg -LO https://picsum.photos/id/237/200/300

image.jpgをdvc管理にしてみます。

dvc add data/image.jpg

dataの中にimage.jpg.dvcというファイルが生成され、image.jpgの方は.gitignoreによってgit管理から外れました。image.jpg.dvcimage.jpgを一意に識別するためのハッシュ値などの情報が入っているテキストデータで、gitではこちらのみ管理します。

outs:
- md5: b3a6da9d3fbd48339cb2982b5bf41e35
  size: 10839
  hash: md5
  path: image.jpg

生成されたファイルはgitでコミットしておきます。

git add data/image.jpg.dvc data/.gitignore
git commit -m "Add raw data"

クラウドの準備

image.jpgの本体はociに保存していきます。まず、Object Storageを作成します。クラウドの設定は大量にありすぎてしんどいので、名前はbucket-dvcにして、あとは全部デフォルトで大丈夫です。

https://cloud.oracle.com/object-storage/buckets

bucket作成画面

アクセス用のsecret keysも作成します。作成するとsecret_access_keyとaccess_key_idを入手できるので、どこかにメモしておいてください。この2つは秘密情報なのでgit上で管理するのはやめてください。

secret作成画面

https://cloud.oracle.com/identity/domains/my-profile/auth-tokens

接続確認をします。namespaceとociのregionを確認してください。namespaceはbucketの詳細画面から確認できます。regionはap-osaka-1のようなもので、urlの末尾に書かれています。

namespace

データの保存

実際にデータを保存してみます。保存先の設定をします。<namespace><region>は先ほど確認した値をいれます。

dvc remote add -d storage s3://bucket-dvc
dvc remote modify storage endpointurl https://<namespace>.compat.objectstorage.<region>.oci.customer-oci.com

secret_access_keyとaccess_key_idを保存します。xxxxxxを自身のものに変更してください。これはgitでもdvcでも管理されないので、新しいローカル作業環境ではこちらの再設定が必要になります。

dvc remote modify --local storage access_key_id 'xxxxxx'
dvc remote modify --local storage secret_access_key 'xxxxxx'

以下が今回の重要な所なのですが、以下の環境変数を設定しないと上手く動きません。s3互換のストレージを利用する際によく設定する項目のようです。詳細は以下のページに記載されています。

https://www.ateam-oracle.com/post/using-oci-os-s3-interface

export AWS_REQUEST_CHECKSUM_CALCULATION=when_required
export AWS_RESPONSE_CHECKSUM_VALIDATION=when_required

いよいよ保存してみます。

dvc push

1 file pushedと出れば成功です。ociから中身を確認してみましょう。なお、中身を見てもimage.jpgがそのまま入っている訳ではなく、差分管理用のファイルが入っているため一見すると変なファイルが入っていますがそれで成功です。

保存されたファイル

他の作業環境からはgit pulldvc pullを実行すると最新バージョンが入手できます。

まとめ