※当サイトの記事には、広告・プロモーションが含まれます。

Azure Blob Storageのクライアント オブジェクトがややこしい

nazology.net

⇧ 太陽に変わるエネルギーが維持できる技術が実現できれば、太陽の寿命を気にしなくても良いと思いきや、

kids.gakken.co.jp

⇧ 子供向けのコンテンツとは思えないほど、ド直球な回答に震える...

いまから50おくねんには太陽たいようんでしまうといわれています。太陽たいようぬとちいさな青白あおじろほしになるのですが、そのまえに、いまよりかなりおおきくなります。そのとき巨大きょだいした太陽たいようは、地球ちきゅうみこんで、あとかたもなくとかしてしまうでしょう。その時点じてん地球ちきゅうはこの宇宙うちゅうからえてなくなるとかんがえられているのです。

⇧ 事実なのかもしれんけども、言い方...

50億年が経過するまでに地球以外で永住できる場所を作らないと、人類は滅びると。

Azure Blob Storageとは

Microsoft Learnのドキュメントによると、

learn.microsoft.com

Azure Blob Storage の概要

Azure Blob Storage は、Microsoftクラウド用オブジェクト ストレージ ソリューションです。 Blob Storage は、テキスト データやバイナリ データなどの大量の非構造化データを格納するために最適化されています。 非構造化データとは、特定のデータ モデルや定義に従っていないデータであり、テキスト データやバイナリ データなどがあります。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blobs-introduction

Azure Blob Storage

Blob Storage は、次の目的で設計されています。

  • 画像またはドキュメントをブラウザーに直接配信する。
  • 分散アクセス用にファイルを格納する。
  • ビデオおよびオーディオをストリーミング配信する。
  • ログ ファイルに書き込む。
  • バックアップと復元、ディザスター リカバリー、アーカイブのためのデータを格納する。
  • オンプレミス サービスまたは Azure ホステッド サービスで分析するデータを格納する。

ユーザーまたはクライアント アプリケーションは、世界のどこからでも、HTTP/HTTPS 経由で Blob Storage 内のオブジェクトにアクセスできます。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blobs-introduction

⇧ とあり、テキスト形式だろうが、バイナリ形式だろうが、基本的にはどんなファイルでも保管できるってことかと。

Azure Blob Storage サービスの構成としては、

Blob Storage のリソース

Blob Storage には、3 種類のリソースがあります。

  • ストレージ アカウント
  • ストレージ アカウント内のコンテナー
  • コンテナー内の BLOB

次の図に、これらのリソースの関係を示します。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blobs-introduction

⇧ 上図のような感じ。

BLOBに、ファイルの実体が保管されるようで、

Azure Storage では、3 種類の BLOB がサポートされています。

  • ブロック BLOB には、テキストとバイナリ データが格納されます。 ブロック BLOB は、個別に管理できるデータ ブロックで構成されます。 ブロック BLOB は、最大約 190.7 TiB のデータを格納できます。
  • 追加 BLOB は、ブロック BLOB と同様にブロックで構成されますが、追加操作用に最適化されています。 追加 BLOB は、仮想マシンのデータのログ記録などのシナリオに最適です。
  • ページ BLOB には、最大 8 TiB のランダム アクセス ファイルを格納できます。 ページ BLOB は、仮想ハード ドライブ (VHD) ファイルを格納し、Azure 仮想マシン用のディスクとして機能します。 ページ BLOB について詳しくは、「Azure ページ BLOB の概要」をご覧ください

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blobs-introduction

⇧ 上記の制限がありますと。

BLOBの説明を確認すると、

BLOB の URI は次のようになります。

https://myaccount.blob.core.windows.net/mycontainer/myblob

または

https://myaccount.blob.core.windows.net/mycontainer/myvirtualdirectory/myblob

BLOB に名前を付けるときは、次の規則に従います。

  • BLOB 名には、任意の文字の組み合わせを含めることができます。
  • Azure Storage の BLOB について、BLOB 名は 1 ~ 1,024 文字で指定する必要があります。
  • BLOB 名では大文字と小文字が区別されます。
  • URL の予約文字は適切にエスケープしてください。
  • BLOB 名を構成するパス セグメントの数には制限があります。 パス セグメントは、ディレクトリまたは仮想ディレクトリに対応する連続する区切り文字 (例えば、スラッシュ /など) の間の文字列です。 次のパス セグメントの制限は、BLOB 名に適用されます:
    • ストレージ アカウントで階層型名前空間が有効になっていない 場合、BLOB 名を構成するパス セグメントの数は 254 を超えることはできません。
    • ストレージ アカウントで階層型名前空間が有効になっている場合、BLOB 名を構成するパス セグメントの数が 63 を超えることはできません (コンテナー名とアカウント ホスト名のパス セグメントを含む)。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blobs-introduction

⇧「ファイルシステム」にあるサブディレクトリ構成は疑似的にしか実現できず、

 注意

ドット (.)、スラッシュ (/)、またはこの 2 つの文字のシーケンスあるいは組み合わせで終わる BLOB 名は使用しないでください。 パス セグメントはドット (.) で終わる必要はありません。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blobs-introduction

⇧ BLOB名にも注意が必要ですと。

Azure Blob Storageのクライアント オブジェクトがややこしい

で、Azure Blob Storage サービスには、APIが用意されており、

Azure Storage REST APIAzure PowerShellAzure CLI、または Azure Storage クライアント ライブラリを使用して、Blob Storage 内のオブジェクトにアクセスできます。 各種言語に対応したクライアント ライブラリが用意されています。その例を次に示します。

また、クライアントは、SSH ファイル転送プロトコル (SFTP) を使用して Blob Storage に安全に接続し、ネットワーク ファイル システム (NFS) 3.0 プロトコルを使用して Blob Storage コンテナーをマウントすることもできます。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blobs-introduction

⇧ メジャーどころのプログラミング言語毎に「SDK(Software Development Kit)」が用意されており、各プログラミング言語向けのAPIが用意されておりますと。

で、「SDK(Software Development Kit)」経由でAzure Blob Storage サービスに対してやり取りするには、

learn.microsoft.com

クライアント オブジェクトの作成

SDK を使用して Azure リソースを操作するには、まずクライアント オブジェクトを作成します。 このセクションでは、ストレージ サービス内の 3 種類のリソース (ストレージ アカウント、コンテナー、BLOB) を操作するクライアント オブジェクトを作成する方法について説明します。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-client-management?tabs=java#create-a-client-object

⇧「クライアント オブジェクト」なるものを作成する必要があるのですが、ドキュメントの後続の説明を見た感じでは、

No client object 役割
1 BlobServiceClient ストレージ アカウント レベルでリソースを操作
2 BlobContainerClient 特定のコンテナー リソースを操作
3 BlobClient 特定の BLOB リソースを操作

⇧ 3つの「クライアント オブジェクト」が存在すると。

で、

クライアント オブジェクトの管理

Azure SDK クライアント管理のベスト プラクティスは、クライアントをシングルトンとして扱うことです。つまり、クラスには一度に 1 つのオブジェクトだけを含めることになります。 コンストラクター パラメーターまたはクライアント オプションの特定のセットに対して、クライアントのインスタンスを複数保持する必要はありません。 この概念は、次のような多くの方法で実装できます。

  • 1 つのクライアント オブジェクトを作成し、アプリケーション全体でパラメーターとして渡します。 この方法は、この記事のコード例に示されています。
  • フィールドにクライアント インスタンスを保存します。 C# フィールドの詳細については、「フィールド (C# プログラミング ガイド)」を参照してください。
  • 任意の依存関係挿入コンテナーにクライアント オブジェクトをシングルトンとして登録します。 ASP.NET Core アプリでの依存関係の挿入の詳細については、「Azure SDK for .NET での依存関係の挿入」を参照してください。

この方法は、必要なクライアントごとにコンストラクターを呼び出すよりもはるかに効率的です。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-client-management?tabs=java#manage-client-objects

クライアントの不変性とスレッド セーフ

Azure SDK クライアントは、作成後は変更できません。つまり、接続先のエンドポイント、認可に使用される資格情報、またはクライアント オプションとして渡されるその他の値を変更することはできません。 クライアントの不変性は、クライアントがアプリケーション全体で安全に共有および再利用されることを意味します。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-client-management?tabs=java#client-immutability-and-thread-safety

アプリで同じ種類のクライアントに対して異なる構成または資格情報を使用する必要がある場合は、構成オプションのセットごとにクライアントをインスタンス化できます。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-client-management?tabs=java#client-immutability-and-thread-safety

Azure SDK では、すべてのクライアント インスタンス メソッドがスレッド セーフであり、相互に独立していることが保証されます。 この設計により、クライアント インスタンスの共有および再利用が、たとえスレッド間であっても常に安全であることが保証されます。

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-client-management?tabs=java#client-immutability-and-thread-safety

⇧という説明があるのだけど、「Singleton」にした「クライアント オブジェクト」で「スレッドセーフ」が担保されると考えて良いんかね?

というのも、

qiita.com

初老になってくるとStruts1系が懐かしく感じてきます。新人の頃よく上司から「Struts1系のActionクラスはSingletonだからスレッドセーフを意識しろ」と言われたものです。
ここでは、SpringのDIもSingletonでスレッドアンセーフだからスレッドセーフを意識してね、ということを簡易なコードで検証したうえで、どのような点に留意しながら実装すれば良いかを簡潔に述べたいと思います。

ショロカレ 21日目 SpringのDIはSingleton(シングルトン) #Java - Qiita

⇧ 上記サイト様の説明によりますと、Spring Frameworkで「依存性注入(DI:Dependency Injection)」による「Singleton」は「スレッドアンセーフ」らしいので、Azure Blob Storage サービスのドキュメントの、

任意の依存関係挿入コンテナーにクライアント オブジェクトをシングルトンとして登録します。

Azure SDK では、すべてのクライアント インスタンス メソッドがスレッド セーフであり、相互に独立していることが保証されます。 この設計により、クライアント インスタンスの共有および再利用が、たとえスレッド間であっても常に安全であることが保証されます。

の記載によって、Azureで用意されているインスタンスメソッド側で「スレッドセーフ」が担保されているらしい。

つまり、Azure Blob Storage サービスの「クライアント オブジェクト」は「Singleton」にしたとしても「クライアント オブジェクト」を利用して使用するインスタンスメソッドが「スレッドセーフ」を担保してくれているらしいので、「スレッドアンセーフ」の懸念は払拭されると。

ちなみに、Spring Frameworkで「依存性注入(DI:Dependency Injection)」を実現する方法としては、

docs.spring.io

Container Overview

In most application scenarios, explicit user code is not required to instantiate one or more instances of a Spring IoC container. For example, in a plain web application scenario, a simple boilerplate web descriptor XML in the web.xml file of the application suffices (see Convenient ApplicationContext Instantiation for Web Applications). In a Spring Boot scenario, the application context is implicitly bootstrapped for you based on common setup conventions.

https://docs.spring.io/spring-framework/reference/core/beans/basics.html

Configuration Metadata

The Spring IoC container itself is totally decoupled from the format in which this configuration metadata is actually written. These days, many developers choose Java-based configuration for their Spring applications:

https://docs.spring.io/spring-framework/reference/core/beans/basics.html

Spring Frameworkのドキュメントのまとめ方が宜しくないのだけど、

  1. XML-based configuration
    XML-based configuration metadata configures these beans as <bean/> elements inside a top-level <beans/> element. 
  2. Annotation-based configuration
    →Spring provides comprehensive support for annotation-based configuration, operating on metadata in the component class itself by using annotations on the relevant class, method, or field declaration.
  3. Java-based configuration
    →The central artifacts in Spring’s Java configuration support are @Configuration-annotated classes and @Bean-annotated methods.

の3つの方法があるっぽい。

どの方法で「依存性注入(DI:Dependency Injection)」してたとしても、最終的には、利用する側のクラスのフィールドに@Autowiredを付与することで、Beanのインスタンスを呼び出すことができるっぽいのですが、

ik.am

⇧ 同じ型の戻り値だとエラーになってしまうようで、対応が必要など、ハマりどころがあるようなのだけど、公式のドキュメントのどこに記載があるのか一次情報の参照元を載せてくれるとありがたいんですがね...

まぁ、脱線しましたが、Azure Blob Storage サービスの「クライアント オブジェクト」用のクラスを1つ用意して、「依存性注入(DI:Dependency Injection)」する感じにすれば良いってことですかね。

少なくとも「BlobServiceClient」については、情報が変わることは滅多に無いと思いますし。

Azure Blob StorageのJavaのサンプルのソースコードでも、

github.com

⇧ 「クライアント オブジェクト」用のクラスを用意してるっぽいですし。ただ、サンプルは、Azure Blob Storage サービスのライブラリ以外はJava標準のAPIしか利用していないからなのか、「依存性注入(DI:Dependency Injection)」せずに毎度インスタンス化してますけど...

任意の依存関係挿入コンテナーにクライアント オブジェクトをシングルトンとして登録します。

を実現しているサンプルのソースコードが確認したいんですけどね...

毎度モヤモヤ感が半端ない…

今回はこのへんで。