AzureストレージBLOBのSAS発行ってどれくらい時間がかかるの?

こんにちは。日山(@hiiyan0402)です。
今回はAzureストレージのBLOBに対して、SAS(Shared Access Signature, 共有アクセス署名)を発行するのにかかる時間を調査しましたので結果をご紹介します。


そもそもSASってなに?

Azureストレージには、パブリックでないリソースに対して、限定的に参照/更新/削除を可能とするための機能として、SAS(Shared Access Signature, 共有アクセス署名)があります。SASは以下の様な文字列であり、AzureストレージリソースのURLに付加して使用します。

SAS の例

?sv=2014-02-14&sr=b&sig=gUF6zik%2BdhLmiOomO6wFncm9dqP%2FEgDN4jRfsuA3DxU%3D&st=2014-06-14T03%3A07%3A11Z&se=2014-06-14T04%3A08%3A11Z&sp=r

URL + SAS の例

https://hiiyanXXX.blob.core.windows.net/container0/blob0.txt?sv=2014-02-14&sr=b&sig=gUF6zik%2BdhLmiOomO6wFncm9dqP%2FEgDN4jRfsuA3DxU%3D&st=2014-06-14T03%3A07%3A11Z&se=2014-06-14T04%3A08%3A11Z&sp=r

SASには有効期限(開始と終了)を設定することができます。これにより、予測しづらいパスワードのような文字列と、時間的な制限により、Azureストレージのリソースをセキュリティを確保して限定的に公開することができます。

詳しくは以下のMSDNをご参照ください。
http://msdn.microsoft.com/ja-jp/library/azure/jj721951.aspx

どんな時にSASを使うの?

例えば、Webサイトで一部のユーザにしか閲覧できない動画コンテンツを配信する場合が挙げられます。

単純に考えると、Webサイトでアクセス権限制御を行い、動画コンテンツを配信すれば実現できます。しかし、Webサイトから動画などのサイズの大きいコンテンツを配信すると、Webサイトのネットワークが圧迫されます。また基本的にWebサイトからでは配信速度が遅いです、ユーザビリティ低下につながります。動画コンテンツの配信にはBLOBストレージを使うべきです。

しかし、パブリックでないBLOBにアクセスするためには認証情報が必要になります。もし、ユーザにストレージアカウントのアクセスキーを通知した場合、全権限を与えることになるため、全コンテンツが見えてしまうし、そもそもセキュリティ的に大問題です。

ここでSASを使います。SASはBLOBまたはコンテナごとに発行することができます。Webサイトは、ユーザから動画のリクエストがあった際に。該当するBLOBのSAS(有効期限を1時間等にして)を発行して、URL+SASをユーザに通知します。ユーザはSASを使い、Azureストレージから直接、動画コンテンツ(BLOB)にアクセスします。ちなみに、SASを持っていないユーザはアクセスできません。なので、アクセス制限付き動画コンテンツ配信においてセキュリティ性とパフォーマンスの両方が実現できます。

20140614_hiyama_01

毎回SAS発行するのって逆に時間かかるんじゃない?

もしSAS発行に時間がかかるのであれば、また別の対策が必要になってしまいます。どの程度、時間がかかるのか、今回調査しました。調査構成図は以下の通りです。

20140614_hiyama_05

同一のサブスクリプション内の東日本リージョンに、Azure Webサイト(標準モード)とストレージアカウント(ローカル冗長)を作成。ストレージアカウントには、プライベートコンテナを10個作成(container0 ~ container9)、各コンテナにはブロックBLOBを10個作成(blob0.txt ~ blob9.txt)。Webサイトから各BLOB(100個)に対して10,000回SASを発行し、その時間を計測しました。

コードはこんな感じです。使用したAzureストレージライブラリのバージョンは4.0.1です。

private List<CheckSasResult> Check()
{
    const string connectionString = "...";
    var account = CloudStorageAccount.Parse(connectionString);
    var client = account.CreateCloudBlobClient();

    var results = new List<CheckSasResult>();
    for (var i = 0; i < 10; i++)
    {
        var containerName = string.Format("container{0}", i);
        var container = client.GetContainerReference(containerName);
        for (var j = 0; j < 10; j++)
        {
            var blobName = string.Format("blob{0}.txt", j);
            var blob = container.GetBlockBlobReference(blobName);
            var policy = new SharedAccessBlobPolicy
            {
                Permissions = SharedAccessBlobPermissions.Read,
                SharedAccessStartTime = DateTime.Now.AddMinutes(-1),
                SharedAccessExpiryTime = DateTime.Now.AddHours(1)
            };

            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var sas = blob.GetSharedAccessSignature(policy);
            stopwatch.Stop();

            var result = new CheckSasResult
            {
                ElapsedTicks = stopwatch.ElapsedTicks,
                ContainerName = containerName,
                BlobName = blobName,
                Sas = sas,
            };
            results.Add(result);
        }
    }
    return results;
}

計測結果

計測結果は以下のとおりです。

データ数 1000000
平均 391Ticks (39μs, 0.04ms)
中央値 337Ticks (34μs, 0.03ms)
最大値 107,572Ticks (10,757μs, 11ms)
最小値 307Ticks (31μs, 0.03ms)
分散 518464.4439
標準偏差 720.0447514

ヒストグラム
20140614_hiyama_03
ほとんど300 ~ 400Ticks台でした。

コンテナ別では平均370~416Ticksの範囲、ブロブ別では平均389~401Ticksの範囲なので、ほとんど差はありません。(当然でしょうが・・・)

まとめ

20140614_hiyama_04

SAS発行にはほとんど時間がかからないので、どんどん発行しましょう!
っていうのは冗談で、発行し過ぎはセキュリティ低下につながりますのでご注意を。
しかし、必要であれば、処理速度を気にせずに発行していただいて問題なさそうです。

ちなみに短時間に100万回SAS発行できたので、SAS発行に制限はない、またはそこまで厳しくなさそうです。

今回も最後までご覧いただきありがとうございました!

TechTarget

クラウドエンジニア  日山 雅之による記事「Microsoft Azure スマート解説」がTechTarget Japanにて好評連載中です (全7回)