40

Azure Storageを使用して静的ファイルBLOBを提供していますが、帯域幅のコストを削減するために、提供時にCache-ControlおよびExpiresヘッダーをファイル/BLOBに追加したいと思います。

CloudXplorerやCerebrataのCloudStorageStudioなどのアプリケーションには、コンテナーとBLOBにメタデータプロパティを設定するオプションがありますが、Cache-Controlを追加しようとすると動揺します。

これらのヘッダーをファイルに設定できるかどうか誰か知っていますか?

4

9 に答える 9

26

約600kのBLOBでバッチジョブを実行する必要があり、本当に役立つ2つのことがわかりました。

  1. 同じデータセンターのワーカーロールから操作を実行します。同じアフィニティグループに属している限り、Azureサービス間の速度は非常に高くなります。さらに、データ転送コストはありません。
  2. 操作を並行して実行します。.net v4のタスク並列ライブラリ(TPL)を使用すると、これが非常に簡単になります。コンテナ内のすべてのBLOBに並列にcache-controlヘッダーを設定するコードは次のとおりです。

    // get the info for every blob in the container
    var blobInfos = cloudBlobContainer.ListBlobs(
        new BlobRequestOptions() { UseFlatBlobListing = true });
    Parallel.ForEach(blobInfos, (blobInfo) =>
    {
        // get the blob properties
        CloudBlob blob = container.GetBlobReference(blobInfo.Uri.ToString());
        blob.FetchAttributes();
    
        // set cache-control header if necessary
        if (blob.Properties.CacheControl != YOUR_CACHE_CONTROL_HEADER)
        {
            blob.Properties.CacheControl = YOUR_CACHE_CONTROL_HEADER;
            blob.SetProperties();
        }
    });
    
于 2011-04-08T17:42:46.313 に答える
11

これは、Azure.Storage.BlobsのNet5とV12を使用したJoelFillmoreの回答の更新バージョンです。(余談ですが、デフォルトのヘッダープロパティを親コンテナに設定できたら素晴らしいと思いませんか?)

Webサイトを作成してWorkerRoleを使用する代わりに、Azureには「WebJobs」を実行する機能があります。ストレージアカウントが配置されているのと同じデータセンターのWebサイトで実行可能ファイルをオンデマンドで実行して、キャッシュヘッダーまたはその他のヘッダーフィールドを設定できます。

  1. ストレージアカウントと同じデータセンターに使い捨ての一時的なウェブサイトを作成します。アフィニティグループについて心配する必要はありません。空のASP.NETサイトまたはその他の単純なサイトを作成します。内容は重要ではありません。少なくともB1サービスプランを使用する必要がありました。そうしないと、WebJobが5分後に中止されました。
  2. 更新されたAzureStorageAPIで動作する以下のコードを使用して、コンソールプログラムを作成します。リリース用にコンパイルしてから、実行可能ファイルと必要なすべてのDLLを.zipファイルに圧縮するか、VisualStudioから公開して以下の#3をスキップします。
  3. WebJobを作成し、手順2の.zipファイルをアップロードします。
  4. WebJobを実行します。コンソールに書き込まれたものはすべて、作成されたログファイルで表示でき、WebJobコントロールページからアクセスできます。 ここに画像の説明を入力してください
  5. 一時的なWebサイトを削除するか、無料枠([スケールアップ]の下)に変更します。

以下のコードは、コンテナーごとに個別のタスクを実行し、1分あたり最大100Kのヘッダーを更新しています(時刻によって異なりますか?)。下り料金はありません。

using Azure;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace AzureHeaders
{
    class Program
    {
        private static string connectionString = "DefaultEndpointsProtocol=https;AccountName=REPLACE_WITH_YOUR_CONNECTION_STRING";
        private static string newCacheControl = "public, max-age=7776001"; // 3 months
        private static string[] containersToProcess = { "container1", "container2" };

        static async Task Main(string[] args)
        {
            BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);

            var tasks = new List<Task>();
            foreach (var container in containersToProcess)
            {
                BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(container);
                tasks.Add(Task.Run(() => UpdateHeaders(containerClient, 1000)));  // I have no idea what segmentSize should be!
            }
            Task.WaitAll(tasks.ToArray());
        }

        private static async Task UpdateHeaders(BlobContainerClient blobContainerClient, int? segmentSize)
        {
            int processed = 0;
            int failed = 0;
            try
            {
                // Call the listing operation and return pages of the specified size.
                var resultSegment = blobContainerClient.GetBlobsAsync()
                    .AsPages(default, segmentSize);

                // Enumerate the blobs returned for each page.
                await foreach (Azure.Page<BlobItem> blobPage in resultSegment)
                {
                    var tasks = new List<Task>();

                    foreach (BlobItem blobItem in blobPage.Values)
                    {
                        BlobClient blobClient = blobContainerClient.GetBlobClient(blobItem.Name);
                        tasks.Add(UpdateOneBlob(blobClient));
                        processed++;
                    }
                    Task.WaitAll(tasks.ToArray());
                    Console.WriteLine($"Container {blobContainerClient.Name} processed: {processed}");
                }
            }
            catch (RequestFailedException e)
            {
                Console.WriteLine(e.Message);
                failed++;
            }
            Console.WriteLine($"Container {blobContainerClient.Name} processed: {processed}, failed: {failed}");
        }

        private static async Task UpdateOneBlob(BlobClient blobClient) {
            Response<BlobProperties> propertiesResponse = await blobClient.GetPropertiesAsync();
            BlobHttpHeaders httpHeaders = new BlobHttpHeaders
            {
                // copy any existing headers you wish to preserve
                ContentType = propertiesResponse.Value.ContentType,
                ContentHash = propertiesResponse.Value.ContentHash,
                ContentEncoding = propertiesResponse.Value.ContentEncoding,
                ContentDisposition = propertiesResponse.Value.ContentDisposition,
                // update CacheControl
                CacheControl = newCacheControl  
            };
            await blobClient.SetHttpHeadersAsync(httpHeaders);
        }
    }
}
于 2014-10-11T20:31:49.337 に答える
5

Cerebrata Cloud Storage Studioの最新バージョンv2011.04.23.00は、個々のBLOBオブジェクトでのキャッシュ制御の設定をサポートしています。BLOBオブジェクトを右クリックし、[BLOBプロパティの表示/編集]を選択して、Cache-Control属性の値を設定します。(例public, max-age=2592000)。

curlを使用してblobオブジェクトのHTTPヘッダーを確認すると、設定した値で返されたcache-controlヘッダーが表示されます。

于 2011-05-20T06:15:27.403 に答える
3

時には、最も単純な答えが最良の答えです。少量のBLOBを管理するだけの場合は、AzureManagementを使用てBLOBのヘッダー/メタデータを変更できます。

  1. [ストレージ]をクリックしてから、ストレージアカウント名をクリックします。
  2. [コンテナ]タブをクリックしてから、コンテナをクリックします。
  3. ブロブをクリックしてから、画面の下部にある[編集]をクリックします。

その編集ウィンドウで、キャッシュコントロールコンテンツエンコーディングコンテンツ言語などをカスタマイズできます。

注:現在、 Azureポータルからこのデータを編集することはできません

于 2015-08-07T15:37:21.570 に答える
2

最新のCloudBerryExplorerがCache-Controlをサポートするようになりました: http ://www.cloudberrylab.com/forum/default.aspx?g = posts&t = 3047

于 2011-08-13T23:39:57.140 に答える
1

これは、WindowsAzure.Storagev9.3.3を使用するJoelFillmoreの回答の更新バージョンです。ListBlobsSegmentedAsyncは5,000のページサイズを返すことに注意してください。これがBlobContinuationTokenが使用される理由です。

    public async Task BackfillCacheControlAsync()
    {
        var container = await GetCloudBlobContainerAsync();
        BlobContinuationToken continuationToken = null;

        do
        {
            var blobInfos = await container.ListBlobsSegmentedAsync(string.Empty, true, BlobListingDetails.None, null, continuationToken, null, null);
            continuationToken = blobInfos.ContinuationToken;
            foreach (var blobInfo in blobInfos.Results)
            {
                var blockBlob = (CloudBlockBlob)blobInfo;
                var blob = await container.GetBlobReferenceFromServerAsync(blockBlob.Name);
                if (blob.Properties.CacheControl != "public, max-age=31536000")
                {
                    blob.Properties.CacheControl = "public, max-age=31536000";
                    await blob.SetPropertiesAsync();
                }
            }               
        }
        while (continuationToken != null);
    }

    private async Task<CloudBlobContainer> GetCloudBlobContainerAsync()
    {
        var storageAccount = CloudStorageAccount.Parse(_appSettings.AzureStorageConnectionString);
        var blobClient = storageAccount.CreateCloudBlobClient();
        var container = blobClient.GetContainerReference("uploads");
        return container;
    }
于 2019-09-02T13:49:03.810 に答える
1

これは、PowerShellを搭載したWindowsマシンに座っていないすべての人のためのbatch/unixスクリプトです。次のスクリプトは、すべてのBLOBをループし、BLOBにContent-Cacheプロパティ(Cache-Control httpヘッダー)を個別に設定します。

残念ながら、複数のBLOBに同時にプロパティを設定する方法はないため、これは時間のかかる作業です。通常、ブロブごとに約1〜2秒かかります。ただし、Jay Borsethが指摘しているように、ストレージアカウントと同じデータセンター内のサーバーから実行すると、プロセスが大幅に高速化されます。

# Update Azure Blob Storage blob's cache-control headers
# /content-cache properties
# 
# Quite slow, since there is no `az storage blob update-batch`
#
# Created by Jon Tingvold, March 2021
#
#
# If you want progress, you need to install pv:
# >>> brew install pv  # Mac
# >>> sudo apt install pv  # Ubuntu
#

set -e  # exit when any command fails

AZURE_BLOB_CONNECTION_STRING='DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=XXXXXXXXXXXX;AccountKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=='
CONTAINER_NAME=main

BLOB_PREFIX='admin/'
CONTENT_CACHE='max-age=3600'
NUM_RESULTS=10000000  # Defaults to 5000

BLOB_NAMES=$(az storage blob list --connection-string $AZURE_BLOB_CONNECTION_STRING --container-name $CONTAINER_NAME --query '[].name' --output tsv --num-results $NUM_RESULTS --prefix $BLOB_PREFIX)
NUMBER_OF_BLOBS=$(echo $BLOB_NAMES | wc -w)

echo "Ask Azure for files in Blob Storage ..."
echo "Set content-cache on $NUMBER_OF_BLOBS blobs ..."

for BLOB_NAME in $BLOB_NAMES
do
  az storage blob update --connection-string $AZURE_BLOB_CONNECTION_STRING --container-name $CONTAINER_NAME --name $BLOB_NAME --content-cache $CONTENT_CACHE > /dev/null;
  echo "$BLOB_NAME"

# If you don't have pv install, uncomment  everything after done
done | cat | pv -pte --line-mode --size $NUMBER_OF_BLOBS > /dev/null
于 2021-03-09T23:41:37.447 に答える
0

これは答えるには遅すぎるかもしれませんが、最近、画像のリストがあり、PowerShellスクリプトを使用して適用する必要がある別の方法で同じことをしたいと思いました(もちろんAzureストレージアセンブリの助けを借りて)誰かがこれが役立つことを願っています将来は。

PowerShellスクリプトを使用したAzureBLOBキャッシュ制御の設定で説明されている完全な説明

Add-Type -Path "C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\v2.3\ref\Microsoft.WindowsAzure.StorageClient.dll"

$accountName = "[azureaccountname]"
$accountKey = "[azureaccountkey]"
$blobContainerName = "images"

$storageCredentials = New-Object Microsoft.WindowsAzure.StorageCredentialsAccountAndKey -ArgumentList $accountName,$accountKey
$storageAccount = New-Object Microsoft.WindowsAzure.CloudStorageAccount -ArgumentList $storageCredentials,$true
#$blobClient = $storageAccount.CreateCloudBlobClient()
$blobClient =  [Microsoft.WindowsAzure.StorageClient.CloudStorageAccountStorageClientExtensions]::CreateCloudBlobClient($storageAccount)

$cacheControlValue = "public, max-age=604800"

echo "Setting cache control: $cacheControlValue"

Get-Content "imagelist.txt" | foreach {     
    $blobName = "$blobContainerName/$_".Trim()
    echo $blobName
    $blob = $blobClient.GetBlobReference($blobName)
    $blob.Properties.CacheControl = $cacheControlValue
    $blob.SetProperties()
}
于 2014-06-08T02:01:17.180 に答える
0

PowerShellスクリプトによるストレージBLOBキャッシュ制御プロパティの設定

https://gallery.technet.microsoft.com/How-to-set-storage-blob-4774aca5

#creat CloudBlobClient 
Add-Type -Path "C:\Program Files\Microsoft SDKs\Windows Azure\.NET SDK\v2.3\ref\Microsoft.WindowsAzure.StorageClient.dll" 
$storageCredentials = New-Object Microsoft.WindowsAzure.StorageCredentialsAccountAndKey -ArgumentList $StorageName,$StorageKey 
$blobClient =   New-Object Microsoft.WindowsAzure.StorageClient.CloudBlobClient($BlobUri,$storageCredentials) 
#set Properties and Metadata 
$cacheControlValue = "public, max-age=60480" 
foreach ($blob in $blobs) 
{ 
  #set Metadata 
  $blobRef = $blobClient.GetBlobReference($blob.Name) 
  $blobRef.Metadata.Add("abcd","abcd") 
  $blobRef.SetMetadata() 

  #set Properties 
  $blobRef.Properties.CacheControl = $cacheControlValue 
  $blobRef.SetProperties() 
}
于 2016-08-23T06:01:28.480 に答える