🗂️

GCS がファイルシステムとして使えるようになっていた

2024/09/10に公開

今更ですが、Google Cloud Next'24 で Google Cloud Storage (以下GCS) の新しい機能として Hierarchical Namespace が発表されていました。これは GCSのデータを階層構造を持った形で保存できる機能です。 この機能を最近知って、まさに自分が欲しかったものだったので記事にまとめてみました。

https://zenn.dev/cloud_ace/articles/7e028bf3e96994

https://cloud.withgoogle.com/next/session-library?session=ARC312&utm_source=copylink&utm_medium=unpaidsoc&utm_campaign=FY24-Q2-global-ENDM33-physicalevent-er-next-2024-mc&utm_content=next-homepage-social-share&utm_term=-

これまでのGCS

GCSはオブジェクトストレージであって、ファイルシステムではありませんでした。 フォルダの概念がなく、データは単一の namespace にフラットに配置されます。GSC のコンソール上ではあたかもファイルシステムのように階層をたどってファイルを探索することができますが、あれはファイル名からシュミュレーションして実現しているもので、実際には階層構造はなく、ファイルパスが名前のファイルがフラットに保存されているだけです。

今回追加された Hierarchical Namespace では実際にファイルが階層構造を持って保存されます。つまり GCS をファイルシステムとして使えるようになりました。

なにが嬉しいのか

フォルダ名の更新がアトミックになる

今までのGCSではフォルダの名前を変えたいときはそのフォルダをパス名に持つ全てのオブジェクトに対して rename する必要がありました。Hierarchical Namespace ではフォルダ名の変更はnamespace の名前を変更するたけなのでアトミックに更新できます。 また単一の処理なので処理時間も大幅に削減することができます。

フォルダの一覧取得が容易になった

そもそもフォルダの概念がないのにフォルダ一覧を取得するのもおかしな話ですが、GCSコンソール上からだと擬似的にフォルダを作成することができ、階層的にデータの閲覧が可能なので、ファイルシステムのような使い方をしたいユースケースがありました。

GCSで擬似フォルダ一覧を取得する場合、prefixdelimiter を使ってファイル名のマッチングを使って検索する方法しかありませんでした。

https://www.kwbtblog.com/entry/2019/07/17/170920

この方法は直感的でなく分かりにくいだけでなく、パフォーマンス的にも良くないです。
例えば以下のような構造でGCSにファイルを置いて、dir 以下のフォルダ一覧を取得しようとすると、内部では a/b/ の全てのファイルを走査してしまいます。また、GCS storage apiのレスポンスにはマッチしたファイル全てのパスが含まれるため、ファイルが多いと通信量も多くなってしまいます。

dir/
├── a/
│   ├── a1.txt
│   ├── a2.txt
│   │.....
│   └── a1000.txt
└── b/

内部構造的にフォルダを持てば単にフォルダを探索すれば良いので、子のファイルを走査する必要がなくなります。

使ってみる

GCS の Hierarchical Namespace を使ってみます。Hierarchical Namespace のバケットは今のところコンソールから作成することはできず、gcloud コマンドかAPIを使って作成する方法しかないようです。

今回は gcloud コマンドで作成してみます。

gcloud alpha storage buckets create gs://hn-test --location=us-east1 --uniform-bu
cket-level-access --enable-hierarchical-namespace

コマンドで作成した後はコンソールからバケットを確認することができました。保護のところにHierarchical Namespace と書かれています。

フォルダ一覧を取得してみる

フォルダー一覧を取得するAPIがすでに用意されています。

https://cloud.google.com/storage/docs/json_api/v1/folders/list

以下のようなフォルダ構成のバケットに対してこのAPIを叩いてみます。

hn-test1/
├── a/
│   ├── a1.txt
│   ├── a2.txt
└── b/

以下のようなレスポンスが返ってきました。ちゃんとフォルダの一覧が取得できていますね。

{
  kind: 'storage#folders',
  items: [
    {
      kind: 'storage#folder',
      name: 'a/',
      bucket: 'hn-test1',
      id: 'hn-test1/a/',
      selfLink: 'https://www.googleapis.com/storage/v1/b/hn-test1/folders/a%2F',
      metageneration: '1',
      createTime: '2024-08-31T14:38:11.824Z',
      updateTime: '2024-08-31T14:38:11.824Z'
    },
    {
      kind: 'storage#folder',
      name: 'b/',
      bucket: 'hn-test1',
      id: 'hn-test1/b/',
      selfLink: 'https://www.googleapis.com/storage/v1/b/hn-test1/folders/b%2F',
      metageneration: '1',
      createTime: '2024-08-31T14:38:19.172Z',
      updateTime: '2024-08-31T14:38:19.172Z'
    }
  ]
}

ちなみに、hierarchical namespacでないバケットでフォルダ一覧APIを叩くと以下のエラーが返ってきました。

 Error: The bucket does not support hierarchical namespace.

いつ使うのか

フォルダでデータを階層的に管理したいユースケースでは基本的にhierarchical namespaceを使用するのがいいかと思います。ただし、以下の機能が使えない制限があります。

  • 復元可能な削除
  • Autoclass
  • オブジェクトのバージョニング
  • オブジェクトの ACL
  • オブジェクト保持ロック
  • バケットロック

https://cloud.google.com/storage/docs/hns-overview?hl=ja#hns-limitations

この制限を許容できる要件であれば積極的に使用していきたいと思いました。また、既存のバケットをhierarchical namespaceに変えることはできないので、既存のバケットに適用するには新規にhierarchical namespaceバケットを作ってデータをコピーする必要があります。

個人的な話ですが、GCSをGoogle Drive, Drop Boxなどのクラウドストレージサービスの代わりに利用しており(料金が安いため)、その閲覧用フロントエンドでフォルダ一覧を取得したい要件があるので、今のデータをhierarchical namespaceのバケットに移行しようか考えています。

まとめ

GCS の Hierarchical Namespace は非常に便利な機能でした。今までGCSがただのkey-valueストレージだったことを考えると Hierarchical Namespace は革新的な機能追加だと思います。もはや今までのバケットとは完全に別物と考えて良さそうです。安価で安定していて、APIから操作できるファイルシステムはあまりなかったので今回のアップデートは非常に嬉しいです。

最後に

AI Shiftではエンジニアの採用に力を入れています!
少しでも興味を持っていただけましたら、カジュアル面談でお話しませんか?
(オンライン・19時以降の面談も可能です!)

【面談フォームはこちら】
https://hrmos.co/pages/cyberagent-group/jobs/1826557091831955459

AI Shift Tech Blog

Discussion