Microsoft Azure Storage のパフォーマンスとスケーラビリティに対するチェック リストMicrosoft Azure Storage Performance and Scalability Checklist

概要Overview

Microsoft Azure Storage サービスのリリース以来、Microsoft はこれらのサービスを使用して優れたパフォーマンスを達成するための実証済みプラクティスを数多く開発してきました。この記事では、特に重要なプラクティスを選んでチェック リスト形式の一覧にまとめています。Since the release of the Microsoft Azure Storage services, Microsoft has developed a number of proven practices for using these services in a performant manner, and this article serves to consolidate the most important of them into a checklist-style list. この記事は、アプリケーション開発者が Azure Storage で実証済みプラクティスを使用しているかどうかを確認し、適用の検討が望ましい他の実証済みプラクティスを特定するための資料です。The intention of this article is to help application developers verify they are using proven practices with Azure Storage and to help them identify other proven practices they should consider adopting. 実行可能なパフォーマンスとスケーラビリティの最適化を網羅するものではなく、影響が小さいプラクティスや適用範囲の狭いプラクティスは除外しています。This article does not attempt to cover every possible performance and scalability optimization — it excludes those that are small in their impact or not broadly applicable. 設計時に予測できる範囲で、早い段階からアプリケーションの動作に留意しておくことは、パフォーマンスの問題につながる設計を避けるために有用です。To the extent that the application's behavior can be predicted during design, it's useful to keep these in mind early on to avoid designs that will run into performance problems.

Azure Storage を使用するアプリケーション開発者は、この記事をじっくり読み、自分のアプリケーションが下のリストの実証済みプラクティスに従っていることをご確認ください。Every application developer using Azure Storage should take the time to read this article, and check that their application follows each of the proven practices listed below.

チェック リストChecklist

この記事では、実証済みのプラクティスを次のグループにまとめてあります。This article organizes the proven practices into the following groups. 実証済みのプラクティスは、以下のサービスを対象とします。Proven practices applicable to:

  • すべての Azure Storage サービス (BLOB、テーブル、キュー、ファイル)。All Azure Storage services (blobs, tables, queues, and files)
  • BLOBBlobs
  • テーブルTables
  • キューQueues
完了Done 領域Area CategoryCategory 質問Question
  すべてのサービスAll Services スケーラビリティ ターゲットScalability Targets アプリケーションは、スケーラビリティ ターゲットへの接近を回避する設計になっていますか?Is your application designed to avoid approaching the scalability targets?
  すべてのサービスAll Services スケーラビリティ ターゲットScalability Targets 命名規則は負荷分散を向上できるように設計されていますか?Is your naming convention designed to enable better load-balancing?
  すべてのサービスAll Services ネットワークNetworking クライアント側デバイスは、必要なパフォーマンスを達成するのに十分な帯域幅を低遅延で利用できますか?Do client side devices have sufficiently high bandwidth and low latency to achieve the performance needed?
  すべてのサービスAll Services ネットワークNetworking クライアント側のデバイスは十分に質の高い接続を保持していますか?Do client side devices have a high enough quality link?
  すべてのサービスAll Services ネットワークNetworking クライアント アプリケーションはストレージ アカウントの "近く" に配置されていますか?Is the client application located "near" the storage account?
  すべてのサービスAll Services コンテンツ配信Content Distribution コンテンツ配信に CDN を使用していますか?Are you using a CDN for content distribution?
  すべてのサービスAll Services クライアントへの直接アクセスDirect Client Access プロキシではなく、SAS と CORS を使用して、ストレージへの直接アクセスを許可していますか?Are you using SAS and CORS to allow direct access to storage instead of proxy?
  すべてのサービスAll Services キャッシュCaching 繰り返し使用し、ほとんど変更されないデータをアプリケーションでキャッシュしていますか?Is your application caching data that is repeatedly used and changes rarely?
  すべてのサービスAll Services キャッシュCaching アプリケーションでバッチ更新 (クライアント側でキャッシュし、より大きなセットにアップロードする方法) を実行していますか?Is your application batching updates (caching them client side and then uploading in larger sets)?
  すべてのサービスAll Services .NET 構成.NET Configuration 十分な数のコンカレント接続を使用するようにクライアントを構成していますか?Have you configured your client to use a sufficient number of concurrent connections?
  すべてのサービスAll Services .NET 構成.NET Configuration 十分な数のスレッドを使用するように .NET を構成していますか?Have you configured .NET to use a sufficient number of threads?
  すべてのサービスAll Services .NET 構成.NET Configuration ガベージ コレクション機能が向上した .NET 4.5 以降を使用していますか?Are you using .NET 4.5 or later, which has improved garbage collection?
  すべてのサービスAll Services ParallelismParallelism クライアントの機能やスケーラビリティ ターゲットに過剰な負荷がかからないように、並列処理を適切に制限していますか?Have you ensured that parallelism is bounded appropriately so that you don't overload either your client capabilities or the scalability targets?
  すべてのサービスAll Services ツールTools Microsoft が提供する最新バージョンのクライアント ライブラリとツールを使用していますか?Are you using the latest version of Microsoft provided client libraries and tools?
  すべてのサービスAll Services 再試行Retries エラーとタイムアウトの調整に、指数関数的バックオフによる再試行ポリシーを使用していますか?Are you using an exponential backoff retry policy for throttling errors and timeouts?
  すべてのサービスAll Services 再試行Retries 再試行できないエラーに対するアプリケーションの再試行を回避していますか?Is your application avoiding retries for non-retryable errors?
  BLOBBlobs スケーラビリティ ターゲットScalability Targets 1 つのオブジェクトに多数のクライアントが同時にアクセスしますか?Do you have a large number of clients accessing a single object concurrently?
  BLOBBlobs スケーラビリティ ターゲットScalability Targets 1 つの BLOB に関する帯域幅または操作のスケーラビリティ ターゲット内に、アプリケーションが収まっていますか?Is your application staying within the bandwidth or operations scalability target for a single blob?
  BLOBBlobs BLOB のコピーCopying Blobs 効率的な方法で BLOB をコピーしていますか?Are you copying blobs in an efficient manner?
  BLOBBlobs BLOB のコピーCopying Blobs BLOB の一括コピーに AzCopy を使用していますか?Are you using AzCopy for bulk copies of blobs?
  BLOBBlobs BLOB のコピーCopying Blobs 大量のデータ転送に Azure のインポート/エクスポートを使用していますか?Are you using Azure Import/Export to transfer large volumes of data?
  BLOBBlobs メタデータの使用Use Metadata BLOB に関するメタデータで頻繁に使用するものを、その BLOB のメタデータに格納していますか?Are you storing frequently used metadata about blobs in their metadata?
  BLOBBlobs 迅速なアップロードUploading Fast 1 つの BLOB を迅速にアップロードするときに、ブロックを並列アップロードしていますか?When trying to upload one blob quickly, are you uploading blocks in parallel?
  BLOBBlobs 迅速なアップロードUploading Fast 多数の BLOB を迅速にアップロードするときに、ブロックを並列アップロードしていますか?When trying to upload many blobs quickly, are you uploading blobs in parallel?
  BLOBBlobs 正しい BLOB の種類Correct Blob Type 適宜、ページ BLOB やブロック BLOB を使用していますか?Are you using page blobs or block blobs when appropriate?
  テーブルTables スケーラビリティ ターゲットScalability Targets 1 秒あたりのエンティティに対するスケーラビリティ ターゲットに近づいていませんか?Are you approaching the scalability targets for entities per second?
  テーブルTables 構成Configuration テーブル要求に JSON を使用していますか?Are you using JSON for your table requests?
  テーブルTables 構成Configuration 小さな要求のパフォーマンスを上げるために、Nagle をオフにしていますか?Have you turned Nagle off to improve the performance of small requests?
  テーブルTables テーブルとパーティションTables and Partitions 適切にデータのパーティション分割を実行していますか?Have you properly partitioned your data?
  テーブルTables ホット パーティションHot Partitions 末尾または先頭にのみ追加されるパターンを回避していますか?Are you avoiding append-only and prepend-only patterns?
  テーブルTables ホット パーティションHot Partitions 多くのパーティションにまたがる挿入や更新を実行しますか?Are your inserts/updates spread across many partitions?
  テーブルTables クエリ スコープQuery Scope ほとんどの場合にポイント クエリの使用を許可し、テーブル クエリは控え目に使用するようスキーマを設計していますか?Have you designed your schema to allow for point queries to be used in most cases, and table queries to be used sparingly?
  テーブルTables クエリ密度Query Density 通常のクエリでは、アプリケーションが今後使用する行のみをスキャンして結果を取得していますか?Do your queries typically only scan and return rows that your application will use?
  テーブルTables 返されるデータの限定Limiting Returned Data 不要なエンティティが返されないように、フィルターを使用していますか?Are you using filtering to avoid returning entities that are not needed?
  テーブルTables 返されるデータの限定Limiting Returned Data 不要なプロパティが返されないように、プロジェクションを使用していますか?Are you using projection to avoid returning properties that are not needed?
  テーブルTables 非正規化Denormalization データを取得するときに非効率なクエリや複数の読み取り要求が回避されるように、データを非正規化していますか?Have you denormalized your data such that you avoid inefficient queries or multiple read requests when trying to get data?
  テーブルTables 挿入/更新/削除Insert/Update/Delete トランザクションとする必要がある要求やラウンド トリップを削減するために同時に実行できる要求は、バッチ操作で実行していますか?Are you batching requests that need to be transactional or can be done at the same time to reduce round-trips?
  テーブルTables 挿入/更新/削除Insert/Update/Delete 挿入または更新のどちらを実行するかを判断するためだけにエンティティを取得しないようにしていますか?Are you avoiding retrieving an entity just to determine whether to call insert or update?
  テーブルTables 挿入/更新/削除Insert/Update/Delete まとめて取得されることが多い一連のデータは、複数のエンティティではなく、1 つのエンティティにプロパティとして格納することを検討しましたか?Have you considered storing series of data that will frequently be retrieved together in a single entity as properties instead of multiple entities?
  テーブルTables 挿入/更新/削除Insert/Update/Delete 常にまとめて取得され、バッチ操作で書き込むことができるエンティティ (時系列データなど) には、テーブルではなく BLOB を使用することを検討しましたか?For entities that will always be retrieved together and can be written in batches (for example, time series data), have you considered using blobs instead of tables?
  キューQueues スケーラビリティ ターゲットScalability Targets 1 秒あたりのメッセージに対するスケーラビリティ ターゲットに近づいていませんか?Are you approaching the scalability targets for messages per second?
  キューQueues 構成Configuration 小さな要求のパフォーマンスを上げるために、Nagle をオフにしていますか?Have you turned Nagle off to improve the performance of small requests?
  キューQueues メッセージ サイズMessage Size キューのパフォーマンスが向上するようにメッセージをコンパクトにしていますか?Are your messages compact to improve the performance of the queue?
  キューQueues 一括取得Bulk Retrieve 1 回の "Get" 操作で複数のメッセージを取得していますか?Are you retrieving multiple messages in a single "Get" operation?
  キューQueues ポーリング頻度Polling Frequency アプリケーションの知覚可能な遅延を減らすために、ポーリング頻度は十分ですか?Are you polling frequently enough to reduce the perceived latency of your application?
  キューQueues 更新メッセージUpdate Message エラー発生時にメッセージ全体の再処理が必要になる事態を回避するために、UpdateMessage を使用してメッセージ処理中の進捗を格納していますか?Are you using UpdateMessage to store progress in processing messages, avoiding having to reprocess the entire message if an error occurs?
  キューQueues アーキテクチャArchitecture キューを使用して、クリティカル パスから長期間のワークロードを外し、アプリケーション全体の拡張性を高めて、その後、個別に規模を設定していますか?Are you using queues to make your entire application more scalable by keeping long-running workloads out of the critical path and scale then independently?

すべてのサービスAll Services

このセクションでは、任意の Azure Storage サービス (BLOB、テーブル、キュー、ファイル) を使用する場合に適用できる実証済みプラクティスを列挙します。This section lists proven practices that are applicable to the use of any of the Azure Storage services (blobs, tables, queues, or files).

スケーラビリティ ターゲットScalability Targets

Azure Storage 自体では、サブスクリプションおよびリージョンあたりのストレージ アカウント数が 250 に制限されています。Azure Storage itself has a limit of 250 storage accounts per region per subscription. この制限に達した場合、そのサブスクリプションとリージョンの組み合わせでさらにストレージ アカウントを作成することはできません。If you reach that limit, you will be unable to create any more storage accounts in that subscription/region combination.

各 Azure Storage サービスには、容量 (GB)、トランザクション レート、帯域幅についてのスケーラビリティ ターゲットが設定されています。Each of the Azure Storage services has scalability targets for capacity (GB), transaction rate, and bandwidth. 運用中のアプリケーションがいずれかのスケーラビリティ ターゲットに近づいたり超過したりすると、トランザクション待機時間や調整が増加することがあります。If your application approaches or exceeds any of the scalability targets, it may encounter increased transaction latencies or throttling. Storage サービスは、アプリケーションの調整時に、まず一部のストレージ トランザクションに関して、エラー コード "503 サーバーはビジー状態" または "500 操作タイムアウト" を返します。When a Storage service throttles your application, the service begins to return "503 Server busy" or "500 Operation timeout" error codes for some storage transactions. このセクションでは、スケーラビリティ ターゲット、特に帯域幅のスケーラビリティ ターゲットに対応する一般的な方法を示します。This section discusses both the general approach to dealing with scalability targets and bandwidth scalability targets in particular. また、後のセクションでは個々のストレージ サービスを取り上げ、特定のサービスを使用する状況でのスケーラビリティ ターゲットについて説明します。Later sections that deal with individual storage services discuss scalability targets in the context of that specific service:

すべてのサービスに対する帯域幅のスケーラビリティ ターゲットBandwidth Scalability Target for All Services

この記事の執筆時点で、米国での地理冗長ストレージ (GRS) アカウントに対する帯域幅ターゲットは、受信 (ストレージ アカウントに送信されるデータ) の場合に 10 Gbps、送信 (ストレージ アカウントから送信されるデータ) の場合に 20 Gbps です。At the time of writing, the bandwidth targets in the US for a geo-redundant storage (GRS) account are 10 gigabits per second (Gbps) for ingress (data sent to the storage account) and 20 Gbps for egress (data sent from the storage account). ローカル冗長ストレージ (LRS) アカウントでは、この上限がより高く、受信で 20 Gbps、送信で 30 Gbps です。For a locally redundant storage (LRS) account, the limits are higher – 20 Gbps for ingress and 30 Gbps for egress. 国際的な帯域幅制限はこれよりも低い場合があるため、 スケーラビリティ ターゲットに関するページを参照してください。International bandwidth limits may be lower and can be found on our scalability targets page. ストレージの冗長オプションの詳細については、後の「有用な情報」のリンク先を参照してください。For more information on the storage redundancy options, see the links in Useful Resources below.

スケーラビリティ ターゲットに近づいている場合の対処法What to do when approaching a scalability target

特定のサブスクリプションとリージョンの組み合わせで利用できるストレージ アカウント数の制限に近づいている場合は、アプリケーションとストレージ アカウントの使用状況を評価して、以下のいずれかの状況に該当するかどうかを判断します。If you're approaching the limit of storage accounts you can have in a particular subscription/region combination, evaluate your application and usage of storage accounts and determine if any of these conditions apply.

  • ストレージ アカウントをアンマネージド ディスクとして使用し、これらのディスクを仮想マシンに追加している。Using storage accounts as unmanaged disks and adding those disks to your virtual machines. このシナリオでは、マネージド ディスクの使用をお勧めします。個々のストレージ アカウントを自分で作成して管理することなく、ストレージ ディスクのスケーラビリティが自動的に処理されるからです。In this scenario, we recommend using managed disks, as they handle storage disk scalability for you without you having to create and manage individual storage accounts.
  • データを分離するために、顧客ごとに 1 つのストレージ アカウントを使用している。Using one storage account on a per customer basis, for the purpose of data isolation. このシナリオでは、ストレージ アカウント全体ではなく、顧客ごとにストレージ コンテナーを使用することをお勧めします。In this scenario, we recommend using storage containers for each customer rather than an entire storage account. Azure Storage では、コンテナーごとにロールベースのアクセス制御を指定できるようになりました。Azure Storage now allows you to specify role-based access control on a per container basis.
  • イングレス/エグレス/IOPS/容量のスケーラビリティ向上のため、複数のストレージ アカウントを使用してシャード化している。Using multiple storage accounts to shard for greater scalability of ingress/egress/iops/capacity. このシナリオでは、ワークロードに必要なストレージ アカウントの数を減らすために、可能であれば標準のストレージ アカウントの制限を引き上げることをお勧めします。In this scenario, if possible, we recommend you take advantage of the increased limits of standard storage accounts to reduce the number of storage accounts required for your workload.

アプリケーションが 1 つのストレージ アカウントに対するスケーラビリティ ターゲットに接近している場合は、次の方法のいずれかを検討し、適用します。If your application is approaching the scalability targets for a single storage account, consider adopting one of the following approaches:

  • 対象のアプリケーションでスケーラビリティ ターゲットに対する接近や超過を引き起こしたワークロードを見直します。Reconsider the workload that causes your application to approach or exceed the scalability target. 設計を変更して、必要な帯域幅や処理能力を抑えたり、トランザクションを減らしたりすることができないでしょうか?Can you design it differently to use less bandwidth or capacity, or fewer transactions?
  • アプリケーションが確実にいずれかのスケーラビリティ ターゲットを超過する場合は、複数のストレージ アカウントを作成し、それらのアカウントにアプリケーション データを分けて配置します。If an application must exceed one of the scalability targets, you should create multiple storage accounts and partition your application data across those multiple storage accounts. このパターンを使用する場合は、後で負荷分散用のストレージ アカウントを追加できるようにアプリケーションを設計してください。If you use this pattern, then be sure to design your application so that you can add more storage accounts in the future for load balancing. この記事の執筆時点で、Azure サブスクリプションごとに最大 100 個のストレージ アカウントを作成できます。At time of writing, each Azure subscription can have up to 100 storage accounts. また、ストレージ アカウントでは、データ保存、トランザクション実行、データ転送以外の使用に料金が発生することはありません。Storage accounts also have no cost other than your usage in terms of data stored, transactions made, or data transferred.
  • アプリケーションが帯域幅ターゲットに達する場合は、クライアント側でデータを圧縮し、ストレージ サービスへのデータ送信に必要な帯域幅を削減する方法を検討します。If your application hits the bandwidth targets, consider compressing data in the client to reduce the bandwidth required to send the data to the storage service. これにより帯域幅の節約とネットワーク パフォーマンスの改善が期待できますが、マイナスの影響が及ぶ場合もあります。While this may save bandwidth and improve network performance, it can also have some negative impacts. この方法を適用すると、クライアント側でデータの圧縮と展開の処理要件が増加するため、それがパフォーマンスにどのような影響を及ぼすかを評価する必要があります。You should evaluate the performance impact of this due to the additional processing requirements for compressing and decompressing data in the client. さらに、圧縮データを保存すると、標準のツールでそれらのデータを表示しにくくなるため、問題のトラブルシューティングがより困難になります。In addition, storing compressed data can make it more difficult to troubleshoot issues since it could be more difficult to view stored data using standard tools.
  • アプリケーションがスケーラビリティ ターゲットに達する場合は、再試行に指数関数的バックオフを使用していることを確認してください (「 再試行」を参照)。If your application hits the scalability targets, then ensure that you are using an exponential backoff for retries (see Retries). 望ましいのは、前の方法のいずれかを使用して、スケーラビリティ ターゲットに近づけないことですが、そうするとアプリケーションを迅速に再試行できなくなり、調整の質が低下します。It's better to make sure you never approach the scalability targets (by using one of the above methods), but this will ensure your application won't just keep retrying rapidly, making the throttling worse.

有用な情報Useful Resources

以下のリンクから、スケーラビリティ ターゲットに関する詳細を確認できます。The following links provide additional detail on scalability targets:

パーティションの命名規則Partition Naming Convention

Azure Storage では、範囲を基にしたパーティション構成を使用して、システムを拡大縮小および負荷分散します。Azure Storage uses a range-based partitioning scheme to scale and load balance the system. データを範囲にパーティション分割するには、パーティション キーが使用されます。これらの範囲はシステム全体にわたって負荷分散されます。The partition key is used to partition data into ranges and these ranges are load-balanced across the system. これは、構文の順序 (例: msftpayroll、msftperformance、msftemployees など) やタイムスタンプの使用 (log20160101、log20160102、log20160102 など) のような命名規則が、負荷分散の操作でより小さな範囲にパーティションを分割されるまで、同じパーティション サーバー上に併置される可能性のあるパーティションに適合されることを意味します。This means naming conventions such as lexical ordering (for example, msftpayroll, msftperformance, msftemployees, etc.) or using time-stamps (log20160101, log20160102, log20160102, etc.) will lend itself to the partitions being potentially colocated on the same partition server, until a load-balancing operation splits them out into smaller ranges. たとえば、コンテナー内のすべての BLOB は、これらの BLOB の負荷がさらにパーティション範囲の再調整を必要とするまで、1 台のサーバーで提供されます。For example, all blobs within a container can be served by a single server until the load on these blobs requires further rebalancing of the partition ranges. 同様に、名前が構文の順序で配置された負荷の軽いアカウントのグループは、これらの 1 つまたはすべてのアカウントの負荷が複数のパーティション サーバーに分割される必要があるときまで、1 台のサーバーで提供できます。Similarly, a group of lightly loaded accounts with their names arranged in lexical order may be served by a single server until the load on one or all of these accounts require them to be split across multiple partitions servers. 負荷分散の各操作は、操作中のストレージの呼び出しの待機時間に影響を与える可能性があります。Each load-balancing operation may impact the latency of storage calls during the operation. パーティションに対して急激に増加したトラフィックを処理するシステムの機能は、負荷分散の操作が開始され、パーティション キーの範囲に再調整されるまで、1 台のパーティション サーバーのスケーラビリティによって制限されます。The system's ability to handle a sudden burst of traffic to a partition is limited by the scalability of a single partition server until the load-balancing operation kicks-in and rebalances the partition key range.

このような操作の頻度を減らすために、ベスト プラクティスに従うことができます。You can follow some best practices to reduce the frequency of such operations.

  • アカウント、コンテナー、BLOB、テーブルおよびキューに対して使用する命名規則を精査します。Examine the naming convention you use for accounts, containers, blobs, tables, and queues, closely. お客様のニーズに最も適したハッシュ関数を使用して、アカウント名に 3 桁のハッシュでプレフィックスを付けることを検討します。Consider prefixing account names with a 3-digit hash using a hashing function that best suits your needs.
  • タイムスタンプまたは数値識別子を使用してデータを整理する場合は、末尾にのみ (または先頭にのみ) 追加されるトラフィック パターンを使用していないことを確認する必要があります。If you organize your data using timestamps or numerical identifiers, you have to ensure you are not using an append-only (or prepend-only) traffic patterns. これらのパターンは、範囲ベースのパーティション分割システムには適していません。すべてのトラフィックを 1 つのパーティションに向けたり、システムを効果的な負荷分散から制限したりする場合があります。These patterns are not suitable for a range -based partitioning system, and could lead to all the traffic going to a single partition and limiting the system from effectively load balancing. たとえば、yyyymmdd などのタイムスタンプを持つ BLOB オブジェクトを使用する毎日の操作がある場合、毎日の操作に対するすべてのトラフィックが、1 台のパーティション サーバーで提供される 1 つのオブジェクトに直接送信されます。For instance, if you have daily operations that use a blob object with a timestamp such as yyyymmdd, then all the traffic for that daily operation is directed to a single object, which is served by a single partition server. BLOB の制限およびパーティションの制限ごとにお客様のニーズを満たすかどうかを確認して、必要に応じて、この操作を複数の BLOB に分割することを検討します。Look at whether the per blob limits and per partition limits meet your needs, and consider breaking this operation into multiple blobs if needed. 同様に、時系列データをテーブルに保存する場合、すべてのトラフィックをキーの名前空間の最後の部分に直接送信することができます。Similarly, if you store time series data in your tables, all the traffic could be directed to the last part of the key namespace. タイムスタンプまたは数値 ID を使用する必要がある場合は、3 桁のハッシュを使用して ID にプレフィックスを付けます。また、タイムスタンプの場合は、ssyyyymmdd のように時刻の秒の部分を使用したプレフィックスを付けます。If you must use timestamps or numerical IDs, prefix the ID with a 3-digit hash, or in the case of timestamps prefix the seconds part of the time such as ssyyyymmdd. 操作の一覧およびクエリを繰り返し実行する場合は、クエリの数を制限するハッシュ関数を選択します。If listing and querying operations are routinely performed, choose a hashing function that will limit your number of queries. その他の場合は、ランダムなプレフィックスが望ましい場合があります。In other cases, a random prefix may be sufficient.
  • Azure Storage で使用されるパーティション構成の詳細については、 こちらの SOSP ペーパーを参照してください。For additional information on the partitioning scheme used in Azure Storage, read the SOSP paper here.

ネットワークNetworking

API 呼び出しは重要ですが、一方で、アプリケーションの物理的ネットワークに存在する制約がパフォーマンスに大きな影響を及ぼすことも少なくありません。While the API calls matter, often the physical network constraints of the application have a significant impact on performance. 以下では、ユーザーが遭遇するいくつかの制限について説明します。The following describe some of limitations users may encounter.

クライアントのネットワーク機能Client Network Capability

スループットThroughput

帯域幅については、多くの場合にクライアントの処理能力が問題になります。For bandwidth, the problem is often the capabilities of the client. たとえば、単一のストレージ アカウントで 10 Gbps 以上の受信データを処理できる (「すべてのサービスに対する帯域幅のスケーラビリティ ターゲット」を参照) 一方で、"小さい" Azure worker ロール インスタンスのネットワーク速度が 100 Mbps 程度であるなどの場合です。For example, while a single storage account can handle 10 Gbps or more of ingress (see bandwidth scalability targets), the network speed in a "Small" Azure Worker Role instance is only capable of approximately 100 Mbps. 大きい Azure インスタンスは、処理能力の高い NIC を使用します。そのため、1 台のコンピューターのネットワーク制限を引き上げる必要がある場合は、大きなインスタンスを使用するか VM の数を増やすことを検討してください。Larger Azure instances have NICs with greater capacity, so you should consider using a larger instance or more VMs if you need higher network limits from a single machine. オンプレミスのアプリケーションからストレージ サービスにアクセスし、同じ規則を適用する場合は、クライアント デバイスのネットワーク性能と、Azure Storage の場所へのネットワーク接続について把握し、それらを必要に応じて増強するか、それぞれの性能の範囲内でアプリケーションが稼働するように設計します。If you are accessing a Storage service from an on premises application, then the same rule applies: understand the network capabilities of the client device and the network connectivity to the Azure Storage location and either improve them as needed or design your application to work within their capabilities.

接続品質Link Quality

他のネットワーク運用と同様に、エラーやパケット損失が生じるネットワーク状態では、遅延が生じて有効なスループットが損なわれます。As with any network usage, be aware that network conditions resulting in errors and packet loss will slow effective throughput. WireShark または NetMon は、この問題の診断に有用です。Using WireShark or NetMon may help in diagnosing this issue.

有用な情報Useful Resources

仮想マシンのサイズと割り当てられている帯域幅の詳細については、「Windows VM のサイズ」または「Linux VM のサイズ」をご覧ください。For more information about virtual machine sizes and allocated bandwidth, see Windows VM sizes or Linux VM sizes.

場所Location

分散型環境では、サーバーの近くにクライアントを配置すると、パフォーマンスが最大になります。In any distributed environment, placing the client near to the server delivers in the best performance. 最小限の遅延で Azure Storage にアクセスするには、同じ Azure リージョン内にクライアントを配置するのが最適です。For accessing Azure Storage with the lowest latency, the best location for your client is within the same Azure region. たとえば、Azure Storage で Azure Web Sites のサイトを 1 つ保有している場合は、Azure Storage とサイトの両方を単一のリージョン内に配置します (たとえば、米国西部や東南アジア)。For example, if you have an Azure Web Site that uses Azure Storage, you should locate them both within a single region (for example, US West or Asia Southeast). これにより遅延とコストは低下します。執筆時点では、1 つのリージョン内での帯域幅使用は無料です。This reduces the latency and the cost — at the time of writing, bandwidth usage within a single region is free.

クライアント アプリケーションが Azure 内にホストされていない場合 (モバイル デバイス アプリケーションやオンプレミスのエンタープライズ サービス) も、アクセス元のデバイスに近いリージョンにストレージ アカウントを配置すると、一般的に遅延は少なくなります。If your client applications are not hosted within Azure (such as mobile device apps or on premises enterprise services), then again placing the storage account in a region near to the devices that will access it, will generally reduce latency. クライアントが広範囲に分散されている場合 (一部が北米に、一部がヨーロッパに存在する場合など) は、複数のストレージ アカウントを使用することを検討します。たとえば、アカウントを北米リージョンに配置し、別のアカウントをヨーロッパ リージョンに配置します。If your clients are broadly distributed (for example, some in North America, and some in Europe), then you should consider using multiple storage accounts: one located in a North American region and one in a European region. こうすることで、両方のリージョンのユーザーにとって遅延が減少します。This will help to reduce latency for users in both regions. アプリケーションが保存するデータが個々のユーザーに固有であり、ストレージ アカウント間でデータをレプリケーションする必要がなければ、導入しやすい方法です。This approach is easier to implement if the data the application stores is specific to individual users, and does not require replicating data between storage accounts. 広範なコンテンツ配信には、CDN をお勧めします。詳細については、次のセクションを参照してください。For broad content distribution, a CDN is recommended – see the next section for more details.

コンテンツ配信Content Distribution

Web サイトのホーム ページに表示される製品デモ ビデオのように、1 つのアプリケーションで、同じリージョンまたは複数リージョン内の多数のユーザーに共通のコンテンツを提示する場合があります。Sometimes, an application needs to serve the same content to many users (for example, a product demo video used in the home page of a website), located in either the same or multiple regions. こうしたシナリオでは、Azure CDN などの Content Delivery Network (CDN) を使用し、Azure Storage を CDN のデータ配信元とします。In this scenario, you should use a Content Delivery Network (CDN) such as Azure CDN, and the CDN would use Azure storage as the origin of the data. Azure Storage アカウントは 1 つのリージョンに存在して、他のリージョンに低遅延でコンテンツを配信できないのに対し、Azure CDN は世界中の異なるデータ センターに存在するサーバーを使用します。Unlike an Azure Storage account that exists in a single region and that cannot deliver content with low latency to other regions, Azure CDN uses servers in multiple data centers around the world. また、通常、CDN は単一のストレージ アカウントよりもはるかに高い送信上限をサポートします。Additionally, a CDN can typically support much higher egress limits than a single storage account.

Azure CDN の詳細については、「 Azure CDN」を参照してください。For more information about Azure CDN, see Azure CDN.

SAS と CORS の使用Using SAS and CORS

ユーザーの Web ブラウザーやモバイル アプリケーションで Azure Storage のデータにアクセスする JavaScript などのコードを承認する必要がある場合は、アプリケーションを Web ロールでプロキシとして使用する方法があります。ユーザーのデバイスは Web ロールで認証を実行し、次にストレージ リソースへのアクセスを承認します。When you need to authorize code such as JavaScript in a user's web browser or a mobile phone app to access data in Azure Storage, one approach is to use an application in web role as a proxy: the user's device authenticates with the web role, which in turn authorizes access to storage resources. この方法では、安全でないデバイスにストレージ アカウント キーを知らせずに済みます。In this way, you can avoid exposing your storage account keys on insecure devices. しかし、ユーザーのデバイスとストレージ サービス間で転送されるデータがすべて、Web ロールを通過するため、Web ロールに大きなオーバーヘッドが生じます。However, this places a significant overhead on the web role because all the data transferred between the user's device and the storage service must pass through the web role. Shared Access Signature (SAS) を使用すると、Web ロールをストレージ サービスのプロキシとして用いることを回避できます。場合によっては、SAS とクロス オリジン リソース共有 (CORS) ヘッダーと組み合わせて使用します。You can avoid using a web role as a proxy for the storage service by using Shared Access Signatures (SAS), sometimes in conjunction with Cross-Origin Resource Sharing headers (CORS). SAS を使用すると、ユーザーのデバイスは限られたアクセス トークンでストレージ サービスに直接、要求を実行できるようになります。Using SAS, you can allow your user's device to make requests directly to a storage service by means of a limited access token. たとえば、ユーザーがアプリケーションに写真をアップロードする場合は、Web ロールが特定の BLOB またはコンテナーに対する書き込みアクセスを 30 分間だけ許可する SAS トークンを生成し、ユーザーのデバイスに送信します (30 分が経過すると、SAS トークンは期限切れになります)。For example, if a user wants to upload a photo to your application, your web role can generate and send to the user's device a SAS token that grants permission to write to a specific blob or container for the next 30 minutes (after which the SAS token expires).

通常は、あるドメイン上の Web サイトにホストされているページで、他のドメインに対する "PUT" などの特別な操作を実行する JavaScript は許可されません。Normally, a browser will not allow JavaScript in a page hosted by a website on one domain to perform specific operations such as a "PUT" to another domain. たとえば、"contosomarketing.cloudapp.net" で Web ロールをホストしている場合に、クライアント側の JavaScript で BLOB を "contosoproducts.blob.core.windows.net" のストレージ アカウントにアップロードしようとすると、ブラウザーの "Same Origin Policy" によって操作が禁止されます。For example, if you host a web role at "contosomarketing.cloudapp.net," and want to use client-side JavaScript to upload a blob to your storage account at "contosoproducts.blob.core.windows.net," the browsers "same origin policy" will forbid this operation. CORS は、ソース ドメイン (この例では Web ロール) で生成された要求を信頼するようブラウザーに通知することを、ターゲット ドメイン (この例ではストレージ アカウント) に許可するブラウザー機能です。CORS is a browser feature that allows the target domain (in this case the storage account) to communicate to the browser that it trusts requests originating in the source domain (in this case the web role).

どちらのテクノロジも、Web アプリケーションに不要な負荷 (およびボトルネック) をかけずに運用するために役立ちます。Both of these technologies can help you avoid unnecessary load (and bottlenecks) on your web application.

有用な情報Useful Resources

SAS の詳細については、Shared Access Signature に関する記事のパート 1 の SAS モデルに関するページを参照してください。For more information about SAS, see Shared Access Signatures, Part 1: Understanding the SAS Model.

CORS の詳細については、「 Azure ストレージ サービスでのクロス オリジン リソース共有 (CORS) のサポート」を参照してください。For more information about CORS, see Cross-Origin Resource Sharing (CORS) Support for the Azure Storage Services.

キャッシュCaching

データの取得Getting Data

一般に、1 つのサービスから 1 回でデータを取得する方が、2 回に分けて取得するよりも適切です。In general, getting data from a service once is better than getting it twice. Web ロールで実行している MVC Web アプリケーションが、ユーザー向けコンテンツとして、ストレージ サービスから 50 MB の BLOB を取得した例を考えてみます。Consider the example of an MVC web application running in a web role that has already retrieved a 50-MB blob from the storage service to serve as content to a user. アプリケーションは、この後もユーザーから要求があるたびに同じ BLOB を取得するか、BLOB をローカル ディスクにキャッシュして、以降のユーザー要求に対し、繰り返し再使用することができます。The application could then retrieve that same blob every time a user requests it, or it could cache it locally to disk and reuse the cached version for subsequent user requests. さらにユーザーがデータを要求すると、アプリケーションは更新時刻を記した条件付きヘッダーで GET を発行します。これによって、更新がない場合に BLOB 全体を取得しないように制御します。Furthermore, whenever a user requests the data, the application could issue GET with a conditional header for modification time, which would avoid getting the entire blob if it hasn't been modified. これと同じパターンをテーブル エンティティの操作に適用できます。You can apply this same pattern to working with table entities.

場合によっては、アプリケーションが BLOB を取得した後、短い間だけその BLOB を有効と見なし、期間中は BLOB の更新を確認しないように設定してもかまいません。In some cases, you may decide that your application can assume that the blob remains valid for a short period after retrieving it, and that during this period the application does not need to check if the blob was modified.

アプリケーションが常に使用する構成や検索などのデータは、頻繁にキャッシュの対象とされます。Configuration, lookup, and other data that are always used by the application are great candidates for caching.

.NET を使用して BLOB のプロパティを取得し、最終更新日を確認する方法の例については、「プロパティおよびメタデータの設定と取得」をご覧ください。For an example of how to get a blob's properties to discover the last modified date using .NET, see Set and Retrieve Properties and Metadata. 条件付きダウンロードの詳細については、MSDN の「 BLOB サービス操作の条件ヘッダーの指定」を参照してください。For more information about conditional downloads, see Conditionally Refresh a Local Copy of a Blob.

データの一括アップロードUploading Data in Batches

一部のアプリケーション シナリオでは、データをローカルで集計し、それらをすぐ個別にアップロードするのではなく、定期的に一括でアップロードすることができます。In some application scenarios, you can aggregate data locally, and then periodically upload it in a batch instead of uploading each piece of data immediately. たとえば、Web アプリケーションがアクティビティのログ ファイルを保持する場合があります。つまり、アプリケーションはアクティビティが発生するたびに、それぞれの詳細をテーブル エンティティとしてアップロードできますが (多くのストレージ操作が必要)、ほかに、アクティビティの詳細をローカルのログ ファイルに保存し、それらの全詳細を区切り記号で区切って記録したファイルを定期的に BLOB にアップロードすることもできます。For example, a web application might keep a log file of activities: the application could either upload details of every activity as it happens as a table entity (which requires many storage operations), or it could save activity details to a local log file, and then periodically upload all activity details as a delimited file to a blob. 各ログ エントリが 1 KB であれば、1 回の "Put Blob" トランザクションで何千個もアップロードできます (1 回のトランザクションで最大 64 MB の BLOB をアップロード可能)。If each log entry is 1 KB in size, you can upload thousands in a single "Put Blob" transaction (you can upload a blob of up to 64 MB in size in a single transaction). アップロードする前にローカル マシンがクラッシュした場合は、ログ データが失われる可能性があります。アプリケーション開発者は、クライアント デバイスに障害が起きたり、アップロードに失敗したりする可能性を設計に組み込む必要があります。If the local machine crashes prior to the upload, you will potentially lose some log data: the application developer must design for the possibility of client device or upload failures. 単発のアクティビティではなく、複数の期間にわたってアクティビティ データをダウンロードする必要がある場合は、テーブルよりも BLOB をお勧めします。If the activity data needs to be downloaded for timespans (not just single activity), then blobs are recommended over tables.

.NET 構成.NET Configuration

このセクションでは、.NET Framework を使用してパフォーマンスの大幅な向上を図る場合に利用できる簡単な構成を示します。If using the .NET Framework, this section lists several quick configuration settings that you can use to make significant performance improvements. 他の言語を使用する場合は、その言語に類似の概念がないか確認してください。If using other languages, check to see if similar concepts apply in your chosen language.

既定の接続数の上限を増加するIncrease default connection limit

.NET の次のコードは、既定の接続数の上限 (通常、クライアント環境では 2、サーバー環境では 10) を 100 に増やします。In .NET, the following code increases the default connection limit (which is usually 2 in a client environment or 10 in a server environment) to 100. 一般的に、この値はアプリケーションが使用するおおよそのスレッド数に設定します。Typically, you should set the value to approximately the number of threads used by your application.

ServicePointManager.DefaultConnectionLimit = 100; //(Or More)  

接続数の上限は、接続を開始する前に設定する必要があります。You must set the connection limit before opening any connections.

他のプログラミング言語については、対象の言語のドキュメントで接続数の上限の設定方法を確認してください。For other programming languages, see that language's documentation to determine how to set the connection limit.

詳細については、ブログ記事「Web Services:Concurrent Connections (Web サービス: コンカレント接続数)」を参照してください。For more information, see the blog post Web Services: Concurrent Connections.

非同期タスクを伴う同期コードを使用する場合は、スレッド プールの最小スレッド数 (ThreadPool Min Threads) を増やすIncrease ThreadPool Min Threads if using synchronous code with Async Tasks

このコードはスレッド プールの最小スレッド数を増やします:This code will increase the thread pool min threads:

ThreadPool.SetMinThreads(100,100); //(Determine the right number for your application)  

詳細については、「 ThreadPool.SetMinThreads メソッド」を参照してください。For more information, see ThreadPool.SetMinThreads Method.

.NET 4.5 のガベージ コレクションを活用するTake advantage of .NET 4.5 Garbage Collection

クライアント アプリケーション用に .NET 4.5 以降を使用すると、サーバー ガベージ コレクションによるパフォーマンス向上が期待できます。Use .NET 4.5 or later for the client application to take advantage of performance improvements in server garbage collection.

詳細については、記事「 .NET 4.5 におけるパフォーマンス向上の概要」を参照してください。For more information, see the article An Overview of Performance Improvements in .NET 4.5.

無制限の並列処理Unbounded Parallelism

並列処理はパフォーマンスにとって非常に有用ですが、複数のワーカーを使用して同じストレージ アカウント内の複数のパーティション (コンテナー、キュー、テーブル パーティション) にアクセスする状況や、同じパーティション内の複数の項目にアクセスする状況で、データのアップロードとダウンロードに無制限の並列処理 (スレッドや並列要求の数の上限なし) を使用する場合には、注意が必要です。While parallelism can be great for performance, be careful about using unbounded parallelism (no limit on the number of threads and/or parallel requests) to upload or download data, using multiple workers to access multiple partitions (containers, queues, or table partitions) in the same storage account or to access multiple items in the same partition. 並列処理が無制限の場合、アプリケーションはクライアント デバイスの処理能力やストレージ アカウントのスケーラビリティ ターゲットを超過することがあり、その結果、遅延や調整時間が長くなります。If the parallelism is unbounded, your application can exceed the client device's capabilities or the storage account's scalability targets resulting in longer latencies and throttling.

ストレージ クライアント ライブラリとツールStorage Client Libraries and Tools

常に、Microsoft が提供する最新のクライアント ライブラリとツールを使用してください。Always use the latest Microsoft provided client libraries and tools. この記事の執筆時点では、.NET、Windows Phone、Windows Runtime、Java、および C++ 用のクライアント ライブラリを利用できます。他の言語のプレビュー版ライブラリも利用できます。At the time of writing, there are client libraries available for .NET, Windows Phone, Windows Runtime, Java, and C++, as well as preview libraries for other languages. さらに、Microsoft は Azure Storage の操作用に、PowerShell コマンドレットと Azure CLI コマンドをリリースしています。In addition, Microsoft has released PowerShell cmdlets and Azure CLI commands for working with Azure Storage. Microsoft はパフォーマンスに留意してこれらのツールを積極的に開発し、最新のサービス バージョンに遅れることなく対応して、数多くのパフォーマンスの実証済みプラクティスを内部で確実に処理できるように取り組んでいます。Microsoft actively develops these tools with performance in mind, keeps them up-to-date with the latest service versions, and ensures they handle many of the proven performance practices internally.

再試行Retries

調整とサーバー ビジーThrottling/ServerBusy

ストレージ サービスは、アプリケーションを調整しているときや、なんらかの一時的な状態のために要求を処理できない場合に、"503 サーバーはビジー状態" や "500 操作タイムアウト" メッセージを返すことがあります。In some cases, the storage service may throttle your application or may simply be unable to serve the request due to some transient condition and return a "503 Server busy" message or "500 Timeout". こうしたメッセージは、アプリケーションがスケーラビリティ ターゲットに接近している場合や、システムがパーティション分割されたデータを再調整し、スループットの向上を試みている場合に表示されます。This can happen if your application is approaching any of the scalability targets, or if the system is rebalancing your partitioned data to allow for higher throughput. 通常、クライアント アプリケーションはエラーを引き起こしている操作を再試行します。後で同じ要求を送信すると、正常に処理されることもあります。The client application should typically retry the operation that causes such an error: attempting the same request later can succeed. しかし、スケーラビリティ ターゲットを超過したアプリケーションをストレージ サービスが調整している場合や、他の理由でサービスが要求を処理できない場合に、積極的な再試行を実行すると、多くの場合は問題が悪化します。However, if the storage service is throttling your application because it is exceeding scalability targets, or even if the service was unable to serve the request for some other reason, aggressive retries usually make the problem worse. したがって、再試行には指数関数的バックオフを使用してください (クライアント ライブラリはこの動作が既定)。For this reason, you should use an exponential back off (the client libraries default to this behavior). この動作では、たとえば、アプリケーションが再試行する間隔を、2 秒後、4 秒後、10 秒後、30 秒後と延ばしていき、最終的に再試行を取りやめます。For example, your application may retry after 2 seconds, then 4 seconds, then 10 seconds, then 30 seconds, and then give up completely. これにより、アプリケーションは問題を悪化させずに、サービスに対する負荷を大幅に軽減できます。This behavior results in your application significantly reducing its load on the service rather than exacerbating any problems.

接続エラーは、調整の結果ではなく、一時的な問題と予想されるので、直後に再試行を実行してかまいません。Connectivity errors can be retried immediately, because they are not the result of throttling and are expected to be transient.

再試行できないエラーNon-Retryable Errors

クライアント ライブラリは、再試行できるエラーとできないエラーを区別します。The client libraries are aware of which errors are retry-able and which are not. しかし、ストレージ REST API に対して独自のコードを記述する場合は、一部のエラーでは再試行を実施しないでください。たとえば、400 (正しくない要求) 応答は、クライアント アプリケーションが想定されていない形式で要求を送信したため、処理できなかったという事態を示します。However, if you are writing your own code against the storage REST API, remember there are some errors that you should not retry: for example, a 400 (Bad Request) response indicates that the client application sent a request that could not be processed because it was not in an expected form. この要求を再送信しても、毎回同じ応答が返されることになるので、再試行は無意味です。Resending this request will result the same response every time, so there is no point in retrying it. ストレージ REST API に対して独自のコードを記述する場合は、エラー コードの示す内容と各エラーに対する適切な再試行の方法 (または可否) を理解する必要があります。If you are writing your own code against the storage REST API, be aware of what the error codes mean and the proper way to retry (or not) for each of them.

有用な情報Useful Resources

ストレージのエラー コードの詳細については、Microsoft Azure Web サイトの「 ステータス コードとエラー コード 」を参照してください。For more information about storage error codes, see Status and Error Codes on the Microsoft Azure web site.

BLOBBlobs

既に説明した すべてのサービス 向けの実証済みプラクティスに加えて、ここでは、BLOB サービスに適用する実証済みプラクティスについて説明します。In addition to the proven practices for All Services described previously, the following proven practices apply specifically to the blob service.

BLOB 固有のスケーラビリティ ターゲットBlob-Specific Scalability Targets

1 つのオブジェクトに同時にアクセスする複数のクライアントMultiple clients accessing a single object concurrently

1 つのオブジェクトに多数のクライアントが同時にアクセスする場合は、オブジェクトごとおよびストレージ アカウントごとにスケーラビリティ ターゲットを考慮する必要があります。If you have a large number of clients accessing a single object concurrently, you will need to consider per object and storage account scalability targets. 1 つのオブジェクトにアクセスできるクライアントの正確な数は、オブジェクトを同時に要求するクライアントの数、オブジェクトのサイズ、ネットワークの状態などの要因によって異なります。The exact number of clients that can access a single object will vary depending on factors such as the number of clients requesting the object simultaneously, the size of the object, network conditions etc.

Web サイトから提供されるイメージやビデオなどのように CDN によってオブジェクトを配信できる場合は、CDN を使用する必要があります。If the object can be distributed through a CDN such as images or videos served from a website, then you should use a CDN. こちらを参照してください。See here.

データが機密である科学シミュレーションなどの他のシナリオでは、2 つのオプションがあります。In other scenarios such as scientific simulations where the data is confidential you have two options. 第 1 のオプションは、同時にアクセスするのではなく、オブジェクトに一定の時間アクセスするようにワークロードのアクセスを調整します。The first is to stagger your workload's access such that the object is accessed over a period of time vs being accessed simultaneously. または、複数のストレージ アカウントにオブジェクトを一時的にコピーし、オブジェクトごとおよびストレージ アカウント全体の合計 IOPS を高くします。Alternatively, you can temporarily copy the object to multiple storage accounts thus increasing the total IOPS per object and across storage accounts. 限定的なテストでは、約 25 個の VM が同時に 100 GB の BLOB を並列でダウンロードできました (各 VM は 32 個のスレッドを使ってダウンロードを並列化しました)。In limited testing, we found that around 25 VMs could simultaneously download a 100-GB blob in parallel (each VM was parallelizing the download using 32 threads). 100 個のクライアントがオブジェクトにアクセスする必要がある場合は、最初にオブジェクトを第 2 のストレージ アカウントにコピーした後、最初の 50 個の VM は第 1 の BLOB にアクセスし、残りの 50 個の VM は第 2 の BLOB にアクセスします。If you had 100 clients needing to access the object, first copy it to a second storage account and then have the first 50 VMs access the first blob and the second 50 VMs access the second blob. 結果はアプリケーションの動作によって大きく異なるので、設計時にテストする必要があります。Results will vary depending on your applications behavior so you should test this during design.

BLOB ごとの帯域幅と操作Bandwidth and operations per Blob

1 つの BLOB に対して、最大で 60 MB/秒の読み取りまたは書き込みを実行できます (これは約 480 Mbps に相当し、クライアント デバイスの物理 NIC をはじめ、多くのクライアント側ネットワークの処理能力を超えています)。You can read or write to a single blob at up to a maximum of 60 MB/second (this is approximately 480 Mbps, which exceeds the capabilities of many client-side networks (including the physical NIC on the client device). さらに、1 つの BLOB は 1 秒あたり最大 500 要求をサポートします。In addition, a single blob supports up to 500 requests per second. 複数のクライアントが同じ BLOB を読み取る必要があり、これらの制限を超過する場合は、CDN を使用した BLOB 配信を検討してください。If you have multiple clients that need to read the same blob and you might exceed these limits, you should consider using a CDN for distributing the blob.

BLOB のターゲット スループットの詳細については、「 Azure Storage のスケーラビリティおよびパフォーマンスのターゲット」を参照してください。For more information about target throughput for blobs, see Azure Storage Scalability and Performance Targets.

BLOB のコピーと移動Copying and Moving Blobs

BLOB のコピーCopy Blob

ストレージ REST API Version 2012-02-12 は、複数のアカウント間で BLOB のコピーを実行する有用な機能を実装しました。クライアント アプリケーションはストレージ サービスに対して、他のソース (別のストレージ アカウントも可能) から BLOB をコピーするよう指示を出し、そのサービスに非同期でコピーを実行させることができます。The storage REST API version 2012-02-12 introduced the useful ability to copy blobs across accounts: a client application can instruct the storage service to copy a blob from another source (possibly in a different storage account), and then let the service perform the copy asynchronously. これによってデータのダウンロードとアップロードが不要になるため、他のストレージ アカウントからデータを移行するときにアプリケーションが必要とする帯域幅を大幅に削減できます。This can significantly reduce the bandwidth needed for the application when you are migrating data from other storage accounts because you do not need to download and upload the data.

ただし、ストレージ アカウント間でコピーを実行する場合は、コピーの完了時間に関する保証は得られません。One consideration, however, is that, when copying between storage accounts, there is no time guarantee on when the copy will complete. アプリケーションで BLOB のコピーを適宜、迅速に完了する必要がある場合は、VM に BLOB をダウンロードしてから、目的の場所にアップロードする方法でコピーを実行してください。If your application needs to complete a blob copy quickly under your control, it may be better to copy the blob by downloading it to a VM and then uploading it to the destination. この状況で確実な予測を行うには、同一の Azure リージョンで実行している VM でコピーを実行します。そうしない場合は、ネットワークの状態により、コピーのパフォーマンスに (高い確率で) 影響が生じます。For full predictability in that situation, ensure that the copy is performed by a VM running in the same Azure region, or else network conditions may (and probably will) affect your copy performance. 加えて、プログラムにより非同期コピーの進捗を監視できます。In addition, you can monitor the progress of an asynchronous copy programmatically.

通常、同一のストレージ アカウント内でのコピーは、すばやく完了します。Copies within the same storage account itself are generally completed quickly.

詳細については、「 Copy Blob」を参照してください。For more information, see Copy Blob.

AzCopy の使用Use AzCopy

Azure Storage チームは、ストレージ アカウントとの間やストレージ アカウント間で多数の BLOB を一括転送できる、"AzCopy" コマンド ライン ツールをリリースしました。The Azure Storage team has released a command-line tool "AzCopy" that is meant to help with bulk transferring many blobs to, from, and across storage accounts. このツールは、そうしたシナリオに最適であり、高い転送速度を実現できます。This tool is optimized for this scenario, and can achieve high transfer rates. アップロードやダウンロード、コピーを一括で実行するシナリオに使用してください。Its use is encouraged for bulk upload, download, and copy scenarios. 詳細情報とダウンロード方法については、「 AzCopy コマンドライン ユーティリティを使用してデータを転送する」を参照してください。To learn more about it and download it, see Transfer data with the AzCopy Command-Line Utility.

Azure のインポート/エクスポート サービスAzure Import/Export Service

大量のデータ (1 TB 超) を対象に、Azure Storage はインポート/エクスポート サービスを提供しています。このサービスでは、ハード ドライブを発送して、BLOB ストレージへのアップロードや BLOB ストレージからのダウンロードを実施できます。For large volumes of data (more than 1 TB), the Azure Storage offers the Import/Export service, which allows for uploading and downloading from blob storage by shipping hard drives. アップロードの場合は、ハード ドライブにデータを格納して Microsoft に発送し、ダウンロードの場合は、空のハード ドライブを Microsoft に発送します。You can put your data on a hard drive and send it to Microsoft for upload, or send a blank hard drive to Microsoft to download data. 詳しくは、「Microsoft Azure Import/Export サービスを使用した BLOB ストレージへのデータの転送」をご覧ください。For more information, see Use the Microsoft Azure Import/Export Service to Transfer Data to Blob Storage. 非常に大量のデータのアップロードやダウンロードは、ネットワークを介して実施するよりも、このサービスの方がはるかに効率的です。This can be much more efficient than uploading/downloading this volume of data over the network.

メタデータの使用Use metadata

BLOB サービスは HEAD 要求をサポートしており、BLOB に関するメタデータを含めることができます。The blob service supports head requests, which can include metadata about the blob. たとえば、アプリケーションは写真の EXIF データを必要とする場合に、写真を取得してデータを抽出できます。For example, if your application needed the EXIF data out of a photo, it could retrieve the photo and extract it. 帯域幅の節約とパフォーマンスの向上を目的として、アプリケーションは写真をアップロードする際に、BLOB のメタデータに EXIF データを保存できます。これ以降は HEAD 要求だけを使用してメタデータの EXIF データを取得できるため、BLOB を読み取るたびに EXIF データを抽出するのに必要な、帯域幅と処理時間の大幅な削減につながります。To save bandwidth and improve performance, your application could store the EXIF data in the blob's metadata when the application uploaded the photo: you can then retrieve the EXIF data in metadata using only a HEAD request, saving significant bandwidth, and the processing time needed to extract the EXIF data each time the blob is read. この方法は、BLOB のコンテンツ全体ではなくメタデータだけが必要な場合に役立ちます。This would be useful in scenarios where you only need the metadata, and not the full content of a blob. 1 つの BLOB に格納できるメタデータはわずか 8 KB であり、これを超えるメタデータを格納する要求はサービスに拒否されるため、データのサイズが適合しない場合は、この方法は使用できません。Only 8 KB of metadata can be stored per blob (the service will not accept a request to store more than that), so if the data does not fit in that size, you may not be able to use this approach.

.NET を使用して BLOB のメタデータを取得する方法の例については、「プロパティおよびメタデータの設定と取得」をご覧ください。For an example of how to get a blob's metadata using .NET, see Set and Retrieve Properties and Metadata.

迅速なアップロードUploading Fast

BLOB を迅速にアップロードするには、まず、アップロードする BLOB は 1 つか、それとも複数かということを考えます。To upload blobs fast, the first question to answer is: are you uploading one blob or many? 以下のガイダンスを参考に、状況に応じて、適切な方法を見つけてください。Use the below guidance to determine the correct method to use depending on your scenario.

1 つの大きな BLOB を迅速にアップロードするUploading one large blob quickly

1 つの大きな BLOB を迅速にアップロードするには、クライアント アプリケーションがブロックやページを並列アップロードする必要があります (個々の BLOB とストレージ アカウント全体に関するスケーラビリティ ターゲットに注意してください)。To upload a single large blob quickly, your client application should upload its blocks or pages in parallel (being mindful of the scalability targets for individual blobs and the storage account as a whole). Microsoft が提供する公式の RTM ストレージ クライアント ライブラリ (.NET、Java) で、これを実行できます。The official Microsoft-provided RTM Storage Client libraries (.NET, Java) have the ability to do this. ライブラリごとに指定されている以下のオブジェクトまたはプロパティを使用して、コンカレンシーのレベルを設定します。For each of the libraries, use the below specified object/property to set the level of concurrency:

  • .NET:使用する BlobRequestOptions オブジェクトで ParallelOperationThreadCount を設定します。.NET: Set ParallelOperationThreadCount on a BlobRequestOptions object to be used.
  • Java/Android: BlobRequestOptions.setConcurrentRequestCount() を使用しますJava/Android: Use BlobRequestOptions.setConcurrentRequestCount()
  • Node.js:要求オプションまたは BLOB サービスのいずれかで、parallelOperationThreadCount を使用します。Node.js: Use parallelOperationThreadCount on either the request options or on the blob service.
  • C++: blob_request_options::set_parallelism_factor メソッドを使用します。C++: Use the blob_request_options::set_parallelism_factor method.

多数の BLOB をすばやくアップロードするUploading many blobs quickly

多数の BLOB をすばやくアップロードするには、複数の BLOB を並列アップロードします。To upload many blobs quickly, upload blobs in parallel. この方法は、ストレージ サービスの複数のパーティションにわたってアップロードを展開するため、ブロックの並列アップロードで一度に 1 つの BLOB をアップロードする方法よりも高速です。This is faster than uploading single blobs at a time with parallel block uploads because it spreads the upload across multiple partitions of the storage service. 1 つの BLOB は 60 MB/秒のスループット (約 480 Mbps) のみをサポートします。A single blob only supports a throughput of 60 MB/second (approximately 480 Mbps). この記事の執筆時点で、米国ベースの LRS アカウントは、個々の BLOB が対応しているスループットを大きく上回る最大 20 Gbps のイングレスをサポートしています。At the time of writing, a US-based LRS account supports up to 20-Gbps ingress, which is far more than the throughput supported by an individual blob. AzCopy は既定で並列アップロードを実行するため、このシナリオ用にお勧めします。AzCopy performs uploads in parallel by default, and is recommended for this scenario.

正しい種類の BLOB の選択Choosing the correct type of blob

Azure Storage がサポートしている BLOB には、ページ BLOB とブロック BLOB の 2 種類があります。Azure Storage supports two types of blob: page blobs and block blobs. 特定の使用シナリオでは、BLOB の種類の選択がソリューションのパフォーマンスとスケーラビリティに影響を及ぼします。For a given usage scenario, your choice of blob type will affect the performance and scalability of your solution. ブロック blob は大量のデータを効率的にアップロードする場合に適しています。たとえば、クライアント アプリケーションが BLOB ストレージに写真やビデオをアップロードする必要がある場合です。Block blobs are appropriate when you want to upload large amounts of data efficiently: for example, a client application may need to upload photos or video to blob storage. ページ blob はアプリケーションがランダム書き込みを実行する必要がある場合に適しています。たとえば、Azure VHD がページ blob として格納されている場合です。Page blobs are appropriate if the application needs to perform random writes on the data: for example, Azure VHDs are stored as page blobs.

詳細については、「 ブロック BLOB、追加 BLOB、ページ BLOB について」を参照してください。For more information, see Understanding Block Blobs, Append Blobs, and Page Blobs.

テーブルTables

既に説明した すべてのサービス 向けの実証済みプラクティスに加えて、ここでは、テーブル サービスに適用する実証済みプラクティスについて説明します。In addition to the proven practices for All Services described previously, the following proven practices apply specifically to the table service.

テーブル固有のスケーラビリティ ターゲットTable-Specific Scalability Targets

ストレージ アカウント全体の帯域幅制限に加えて、テーブルにも以下のような固有のスケーラビリティ限界が存在します。In addition to the bandwidth limitations of an entire storage account, tables have the following specific scalability limit. トラフィックが増大するとシステムが負荷分散を実行しますが、トラフィックの急増直後には、対象ボリュームのスループットが得られない場合もあります。The system will load balance as your traffic increases, but if your traffic has sudden bursts, you may not be able to get this volume of throughput immediately. 使用しているパターンで急増が起きた場合は、ストレージ サービスが自動でテーブルの負荷分散を実行するため、その間に調整やタイムアウトが発生することを想定しておく必要があります。If your pattern has bursts, you should expect to see throttling and/or timeouts during the burst as the storage service automatically load balances out your table. 負荷が緩やかに増加した場合は、システムが適切に負荷分散を実行する時間が確保できるため、一般的によい結果が得られます。Ramping up slowly generally has better results as it gives the system time to load balance appropriately.

1 秒あたりのエンティティ (アカウント)Entities per Second (Account)

テーブルに対するアクセスのスケーラビリティ限界は、1 アカウントにつき 1 秒あたり最大 20,000 エンティティ (各 1 KB) です。The scalability limit for accessing tables is up to 20,000 entities (1 KB each) per second for an account. 一般に、挿入、更新、削除、スキャンされたエンティティがそれぞれ、このターゲットに対してカウントされます。In general, each entity that is inserted, updated, deleted, or scanned counts toward this target. したがって、100 エンティティを含むバッチ挿入は 100 エンティティとカウントされます。So a batch insert that contains 100 entities would count as 100 entities. 1 回のクエリで 1,000 エンティティをスキャンし、5 つが返された場合のカウントは、1,000 エンティティです。A query that scans 1000 entities and returns 5 would count as 1000 entities.

1 秒あたりのエンティティ (パーティション)Entities per Second (Partition)

単一パーティション内のテーブルに対するアクセスのスケーラビリティ ターゲットは、1 秒あたり 2,000 エンティティ (各 1 KB) です。カウント方法は前のセクションと同じです。Within a single partition, the scalability target for accessing tables is 2,000 entities (1 KB each) per second, using the same counting as described in the previous section.

構成Configuration

このセクションでは、テーブル サービスのパフォーマンスを大幅に向上させるための簡単な構成を示します。This section lists several quick configuration settings that you can use to make significant performance improvements in the table service:

JSON の使用Use JSON

ストレージ サービス Version 2013-08-15 より、テーブル サービスでは、テーブル データの転送用に、XML ベースの AtomPub 形式に代えて JSON を使用できるようになりました。Beginning with storage service version 2013-08-15, the table service supports using JSON instead of the XML-based AtomPub format for transferring table data. これにより、ペイロード サイズが 75% 程度に抑えられ、アプリケーションのパフォーマンスを大幅に引き上げることができます。This can reduce payload sizes by as much as 75% and can significantly improve the performance of your application.

詳しくは、投稿「Microsoft Azure Tables: Introducing JSON (Microsoft Azure テーブル: JSON の紹介)」と、「Payload Format for Table Service Operations (Table サービス操作のペイロード形式)」を参照してください。For more information, see the post Microsoft Azure Tables: Introducing JSON and Payload Format for Table Service Operations.

Nagle のオフNagle Off

Nagle のアルゴリズムは、ネットワーク パフォーマンスを向上させる方法として、TCP/IP ネットワークで広く使用されています。Nagle's algorithm is widely implemented across TCP/IP networks as a means to improve network performance. しかし、すべての状況に適しているわけではありません (高度な対話形式の環境などには不向き)。However, it is not optimal in all circumstances (such as highly interactive environments). Azure Storage では、Nagle のアルゴリズムがテーブル サービスやキュー サービスに対する要求のパフォーマンスにマイナスの影響を及ぼすため、可能な場合は無効にしてください。For Azure Storage, Nagle's algorithm has a negative impact on the performance of requests to the table and queue services, and you should disable it if possible.

スキーマSchema

データの表現とクエリの方法は、テーブル サービスのパフォーマンスに影響を及ぼす単一要因として最大のものです。How you represent and query your data is the biggest single factor that affects the performance of the table service. アプリケーションごとに違いはありますが、このセクションでは、以下に関連する一般的な実証済みプラクティスの概略を示します。While every application is different, this section outlines some general proven practices that relate to:

  • テーブル設計Table design
  • 効率的なクエリEfficient queries
  • 効率的なデータ更新Efficient data updates

テーブルとパーティションTables and partitions

テーブルはパーティションに分割されます。Tables are divided into partitions. 同じパーティションに格納されるエンティティは、いずれも同じパーティション キーを共有し、一意の行キーによってパーティション内で識別されます。Every entity stored in a partition shares the same partition key and has a unique row key to identify it within that partition. パーティションには利点もありますが、スケーラビリティ限界ももたらします。Partitions provide benefits but also introduce scalability limits.

  • メリット:最大 100 個のストレージ操作 (総サイズの上限は 4 MB) を含む単一のアトミック バッチ トランザクションで、同じパーティション内のエンティティを更新できます。Benefits: You can update entities in the same partition in a single, atomic, batch transaction that contains up to 100 separate storage operations (limit of 4 MB total size). また、取得するエンティティが同数であれば、複数のパーティションにまたがるデータのクエリよりも、単一パーティションに含まれるデータのクエリの方が効率的に実行できます (ただし、テーブル データのクエリに関する推奨事項を参照してください)。Assuming the same number of entities to be retrieved, you can also query data within a single partition more efficiently than data that spans partitions (though read on for further recommendations on querying table data).
  • スケーラビリティ限界: パーティションはアトミック バッチ トランザクションをサポートしているため、単一パーティションに格納されているエンティティへのアクセスは、負荷分散の対象になりません。Scalability limit: Access to entities stored in a single partition cannot be load-balanced because partitions support atomic batch transactions. したがって、個々のテーブル パーティションのスケーラビリティ ターゲットは、テーブル サービス全体のターゲットよりも低くなります。For this reason, the scalability target for an individual table partition is lower than for the table service as a whole.

テーブルとパーティションにはこうした特徴があるため、以下の設計原理を適用します。Because of these characteristics of tables and partitions, you should adopt the following design principles:

  • クライアント アプリケーションが作業の同一論理単位内で頻繁に更新やクエリを実行するデータは、同じパーティションに配置します。Data that your client application frequently updated or queried in the same logical unit of work should be located in the same partition. この配置をとる理由は、アプリケーションによって書き込みが集約されることであり、また、アトミック バッチ操作の利点を活かすためでもあります。This may be because your application is aggregating writes, or because you want to take advantage of atomic batch operations. さらに、単一パーティションに含まれるデータは、複数のパーティションにまたがるデータよりも 1 回で効率的にクエリを実行できます。Also, data in a single partition can be more efficiently queried in a single query than data across partitions.
  • クライアント アプリケーションが作業 (単一クエリまたはバッチ更新) の同一論理単位内で挿入や更新、クエリを実行しないデータは、別のパーティションに配置します。Data that your client application does not insert/update or query in the same logical unit of work (single query or batch update) should be located in separate partitions. ここで重要なのは、単一テーブル内のパーティション キーの数には上限がないということです。そのため、パーティション キーが数百万個あっても問題にはならず、パフォーマンスは影響を受けません。One important note is that there is no limit to the number of partition keys in a single table, so having millions of partition keys is not a problem and will not impact performance. たとえばアプリケーションが、ユーザー ログインが必要でアクセス数の多い Web サイトである場合、パーティション キーとして User ID を使用することは適切です。For example, if your application is a popular website with user login, using the User ID as the partition key could be a good choice.

ホット パーティションHot Partitions

"ホット パーティション" とは、1 つのアカウントに対するトラフィックのうち、突出して大きな割合の通信が行われていながら、それが単一のパーティションであるために負荷分散を実行できないパーティションです。A hot partition is one that is receiving a disproportionate percentage of the traffic to an account, and cannot be load balanced because it is a single partition. 一般的にホット パーティションは、次の 2 つのうち、いずれかの状況で発生します。In general, hot partitions are created one of two ways:

末尾または先頭にのみ追加されるパターンAppend Only and Prepend Only patterns

"追加のみ" パターンでは、特定の PK に対するすべての (または、ほとんどすべての) トラフィックが現在時刻によって増減します。The "Append Only" pattern is one where all (or nearly all) of the traffic to a given PK increases and decreases according to the current time. たとえば、アプリケーションがログ データのパーティション キーとして現在日時を使用するケースです。An example is if your application used the current date as a partition key for log data. この場合は、すべての挿入がテーブルの最後のパーティションに対して実行され、あらゆる書き込みはテーブルの末尾に追加されることになるため、システムは負荷分散を実行できません。This results in all of the inserts going to the last partition in your table, and the system cannot load balance because all of the writes are going to the end of your table. 対象のパーティションに対するトラフィックの量がパーティション レベルのスケーラビリティ ターゲットを超えると、システムは調整を開始します。If the volume of traffic to that partition exceeds the partition-level scalability target, then it will result in throttling. トラフィックを複数のパーティションに送り、要求の負荷をテーブル全体に分散することが必要です。It's better to ensure that traffic is sent to multiple partitions, to enable load balance the requests across your table.

大量のトラフィック データHigh-Traffic Data

採用したパーティショニング スキームにより、あるパーティションのデータが別のパーティションよりもはるかに多く使用される事態が生じると、その単一パーティションのトラフィックがスケーラビリティ ターゲットに接近し、調整が実行されることがあります。If your partitioning scheme results in a single partition that just has data that is far more used than other partitions, you may also see throttling as that partition approaches the scalability target for a single partition. いずれのパーティションもスケーラビリティ ターゲットに達しないように、パーティション スキームを確認してください。It's better to make sure that your partition scheme results in no single partition approaching the scalability targets.

クエリ実行Querying

このセクションでは、テーブル サービスのクエリに関する実証済みプラクティスについて説明します。This section describes proven practices for querying the table service.

クエリ スコープQuery Scope

複数の方法で、クエリで照会するエンティティの範囲を指定できます。There are several ways to specify the range of entities to query. 以下では、各方法の使用について説明します。The following is a discussion of the uses of each.

通常はスキャン (単一のエンティティを超える大きさのクエリ) を実行しないようにしますが、避けられない場合は、必要のない大量のエンティティをスキャンしたり返したりせずに目的のデータを取得できるようデータを編成してみてください。In general, avoid scans (queries larger than a single entity), but if you must scan, try to organize your data so that your scans retrieve the data you need without scanning or returning significant amounts of entities you don't need.

ポイント クエリPoint Queries

ポイント クエリは 1 つのエンティティを正確に取得します。A point query retrieves exactly one entity. 取得するエンティティのパーティション キーと行キーの両方を指定して実行します。It does this by specifying both the partition key and row key of the entity to retrieve. このクエリは効率的であるため、可能であれば常にこれを使用してください。These queries are efficient, and you should use them wherever possible.

パーティション クエリPartition Queries

パーティション クエリは、共通のパーティション キーを持つデータのセットを取得するクエリです。A partition query is a query that retrieves a set of data that shares a common partition key. 通常このクエリでは、パーティション キーに加えて、行キー値の範囲かいくつかのエンティティ プロパティ値の範囲を指定します。Typically, the query specifies a range of row key values or a range of values for some entity property in addition to a partition key. これらは、ポイント クエリより低効率であるため、多用しないでください。These are less efficient than point queries, and should be used sparingly.

テーブル クエリTable Queries

テーブル クエリは、共通のパーティション キーを持たないエンティティのセットを取得するクエリです。A table query is a query that retrieves a set of entities that does not share a common partition key. このクエリは効率的でないため、可能であれば使用を控えてください。These queries are not efficient and you should avoid them if possible.

クエリ密度Query Density

クエリ効率に関する他の主要な要因は、結果のセットを特定するためのスキャンが行われたエンティティの数に対する、返されたエンティティの数です。Another key factor in query efficiency is the number of entities returned as compared to the number of entities scanned to find the returned set. 1% のデータだけに共通するプロパティ値に適合するフィルターと共にテーブル クエリを実行すると、このクエリは 1 つのエンティティを返すごとに 100 エンティティをスキャンすることになります。If your application performs a table query with a filter for a property value that only 1% of the data shares, the query will scan 100 entities for every one entity it returns. 前に説明したテーブルのスケーラビリティ ターゲットはいずれも、返されるエンティティ数ではなく、スキャンを実行するエンティティ数に関係しています。つまり、クエリ密度が低いと、目的のエンティティを取得するために非常に多くのエンティティをスキャンしなければならないため、テーブル サービスによるアプリケーションの調整が発生しやすくなります。The table scalability targets discussed previously all relate to the number of entities scanned, and not the number of entities returned: a low query density can easily cause the table service to throttle your application because it must scan so many entities to retrieve the entity you are looking for. これを回避する方法の詳細については、後の「非正規化」セクションをご覧ください。See the section below on denormalization for more information on how to avoid this.

必要なデータ量の制限Limiting the Amount of Data Returned
フィルター処理Filtering

クエリによって、クライアント アプリケーションにとって不要なエンティティが返される場合は、フィルターを使用して結果のサイズを減らすことを検討してください。Where you know that a query will return entities that you don't need in the client application, consider using a filter to reduce the size of the returned set. クライアントに返されないエンティティもスケーラビリティ限界に対してカウントされますが、ネットワーク ペイロードのサイズが小さくなり、クライアント アプリケーションが処理しなければならないエンティティの数も少なくなるため、アプリケーションのパフォーマンスは向上します。While the entities not returned to the client still count toward the scalability limits, your application performance will improve because of the reduced network payload size and the reduced number of entities that your client application must process. 前の「クエリ密度」の説明をご覧ください。ただし、スケーラビリティ ターゲットはスキャンされるエンティティ数に関連するため、多くのエンティティを除外するクエリは、ほとんどエンティティを返さない場合でも、調整を引き起こすことがあります。See above note on Query Density, however – the scalability targets relate to the number of entities scanned, so a query that filters out many entities may still result in throttling, even if few entities are returned.

プロジェクションProjection

クライアント アプリケーションが、テーブルに含まれるエンティティのプロパティのごく一部しか必要としない場合は、プロジェクションを使用して、返されるデータ セットのサイズを制限できます。If your client application needs only a limited set of properties from the entities in your table, you can use projection to limit the size of the returned data set. フィルター処理と同じく、この方法はネットワークの負荷とクライアントによる処理の削減に役立ちます。As with filtering, this helps to reduce network load and client processing.

非正規化Denormalization

リレーショナル データベースを運用する場合とは異なり、テーブル データに対する効率的なクエリの実証済みプラクティスは、データを非正規化することにつながります。Unlike working with relational databases, the proven practices for efficiently querying table data lead to denormalizing your data. つまり、多数のエンティティをスキャンしてアプリケーションに必要なデータを見つけるのではなく、複数のエンティティで同じデータを (データの検索に使用するキーごとに 1 つ) 複製し、クライアントに必要なデータを探すためにクエリでスキャンしなければならないエンティティ数を最小にします。That is, duplicating the same data in multiple entities (one for each key you may use to find the data) to minimize the number of entities that a query must scan to find the data the client needs, rather than having to scan large numbers of entities to find the data your application needs. たとえば電子商取引を行う Web サイトでは、ある注文を見つけるために、カスタマー ID (特定の顧客の注文を探す) と日付 (特定の日の注文を探す) の両方での検索が必要になることがあります。For example, in an e-commerce website, you may want to find an order both by the customer ID (give me this customer's orders) and by the date (give me orders on a date). テーブル ストレージでの最適な方法は、エンティティ (またはエンティティに対する参照) を 2 回格納することです。1 回はカスタマー ID で検索しやすくするためにテーブル名、PK、RK と共に格納し、もう 1 回は日付で検索しやすくするために行います。In Table Storage, it is best to store the entity (or a reference to it) twice – once with Table Name, PK, and RK to facilitate finding by customer ID, once to facilitate finding it by the date.

挿入/更新/削除Insert/Update/Delete

このセクションでは、テーブル サービスに格納されているエンティティの変更に関する実証済みプラクティスについて説明します。This section describes proven practices for modifying entities stored in the table service.

バッチ処理Batching

Azure Storage では、バッチ トランザクションはエンティティ グループ トランザクション (ETG) と呼ばれています。ETG に含まれるすべての操作は、単一テーブル内の 1 つのパーティションで実行されます。Batch transactions are known as Entity Group Transactions (ETG) in Azure Storage; all the operations within an ETG must be on a single partition in a single table. 可能な場合は、ETG を使用して一括での挿入、更新、削除を実行してください。Where possible, use ETGs to perform inserts, updates, and deletes in batches. これにより、クライアント アプリケーションとサーバー間のラウンド トリップ数が減少し、課金対象のトランザクション数も少なくなります (1 つの ETG は課金対象の 1 回のトランザクションとしてカウントされ、最大 100 回のストレージ操作が含まれます)。さらに、アトミックな更新 (1 回の ETG ですべての操作が成功するか、すべて失敗するかのいずれか) も可能になります。This reduces the number of round trips from your client application to the server, reduces the number of billable transactions (an ETG counts as a single transaction for billing purposes and can contain up to 100 storage operations), and enables atomic updates (all operations succeed or all fail within an ETG). モバイル デバイスなどの待機時間が長い環境では、ETG を使用することで大きなメリットが得られます。Environments with high latencies such as mobile devices will benefit greatly from using ETGs.

アップサート (Upsert)Upsert

可能な場合は、常にテーブルの アップサート 操作を使用します。Use table Upsert operations wherever possible. アップサートには 2 種類あり、いずれも従来の挿入操作と更新操作に比べて効率的です。There are two types of Upsert, both of which can be more efficient than a traditional Insert and Update operations:

  • InsertOrMerge: エンティティ プロパティのサブセットをアップロードする必要があるものの、エンティティが既に存在するかどうかが明らかでない場合に使います。InsertOrMerge: Use this when you want to upload a subset of the entity's properties, but aren't sure whether the entity already exists. エンティティが存在する場合、この呼び出しはアップサート操作に含まれるプロパティを更新し、既存のプロパティはすべてそのまま残します。エンティティが存在しない場合は、新しいエンティティを挿入します。If the entity exists, this call updates the properties included in the Upsert operation, and leaves all existing properties as they are, if the entity does not exist, it inserts the new entity. 変更するプロパティのアップロードだけが必要とされる点が、クエリにおけるプロジェクションの使用に類似しています。This is similar to using projection in a query, in that you only need to upload the properties that are changing.
  • InsertOrReplace: 新しいエンティティをアップロードする必要があるものの、エンティティが既に存在するかどうかが明らかでない場合に使用します。InsertOrReplace: Use this when you want to upload an entirely new entity, but you aren't sure whether it already exists. この方法は、以前のエンティティを全面的に上書きするため、新たにアップロードするエンティティに誤りが無いことが確実な場合にのみ使用してください。You should only use this when you know that the newly uploaded entity is entirely correct because it completely overwrites the old entity. たとえば、アプリケーションが以前にユーザーの場所データを保存しているかどうかにかかわらず、ユーザーの現在の場所を格納しているエンティティを更新する必要があり、その新しい場所エンティティに問題がなく、かつ以前のすべてのエンティティが持つあらゆる情報を必要としない場合などです。For example, you want to update the entity that stores a user's current location regardless of whether or not the application has previously stored location data for the user; the new location entity is complete, and you do not need any information from any previous entity.
単一エンティティでのデータ シリーズの格納Storing Data Series in a Single Entity

アプリケーションが、頻繁にすべてを一括で取得しなければならない一連のデータを保存する場合があります。たとえば、アプリケーションが直近 24 時間のデータを反映するチャートをプロットするために、時間の経過に伴う CPU 使用率を追跡している場合です。Sometimes, an application stores a series of data that it frequently needs to retrieve all at once: for example, an application might track CPU usage over time in order to plot a rolling chart of the data from the last 24 hours. このとき、正時ごとに対応するテーブル エンティティを 1 つずつ作成し、各エンティティに特定の時刻の CPU 使用率を格納する方法をとることができます。One approach is to have one table entity per hour, with each entity representing a specific hour and storing the CPU usage for that hour. このデータをプロットするには、アプリケーションが直近 24 時間のデータを保持しているエンティティを取得する必要があります。To plot this data, the application needs to retrieve the entities holding the data from the 24 most recent hours.

また、別の方法として、アプリケーションが各時刻の CPU 使用率を単一エンティティの個々のプロパティとして格納することもできます。アプリケーションは InsertOrMerge Upsert の呼び出しを実行するたびに直近の時刻の値を更新でき、その値を毎時間の更新に使うことができます。Alternatively, your application could store the CPU usage for each hour as a separate property of a single entity: to update each hour, your application can use a single InsertOrMerge Upsert call to update the value for the most recent hour. データをプロットするためにアプリケーションが取得するエンティティは、24 個ではなく 1 つだけであるため、効率的なクエリを実行できます (前の「クエリ スコープ」の説明を参照)。To plot the data, the application only needs to retrieve a single entity instead of 24, making for an efficient query (see above discussion on query scope).

BLOB での構造化データの格納Storing structured data in blobs

構造化データはテーブルに格納するデータのように考えられる場合もありますが、常にいくつかのエンティティ範囲がまとめて取得され、それらをバッチ挿入することができます。Sometimes structured data feels like it should go in tables, but ranges of entities are always retrieved together and can be batch inserted. 典型的な例はログ ファイルです。A good example of this is a log file. この例では、数分間のログを一括で処理して挿入を実行することができ、そのときに、ユーザーは必ず数分間のログを一度に取得します。In this case, you can batch several minutes of logs, insert them, and then you are always retrieving several minutes of logs at a time as well. この場合は、テーブルではなく BLOB を使用した方が、書き込まれるオブジェクトと返されるオブジェクトの数を大幅に削減でき、さらに通常は必要な要求数も減らすことができるため、パフォーマンスの面で優れています。In this case, for performance, it's better to use blobs instead of tables, since you can significantly reduce the number of objects written/returned, as well as usually the number of requests that need made.

キューQueues

既に説明したすべてのサービス向けの実証済みプラクティスに加えて、ここでは、キュー サービスに適用する実証済みプラクティスについて説明します。In addition to the proven practices for All Services described previously, the following proven practices apply specifically to the queue service.

スケーラビリティ限界Scalability Limits

1 つのキューは、1 秒あたり約 2,000 メッセージ (各 1 KB) を処理できます (ここでは各 AddMessage、GetMessage、DeleteMessage を 1 つのメッセージとカウントします)。A single queue can process approximately 2,000 messages (1 KB each) per second (each AddMessage, GetMessage, and DeleteMessage count as a message here). これがアプリケーションにとって十分でない場合は、複数のキューを使用してメッセージを分散する必要があります。If this is insufficient for your application, you should use multiple queues and spread the messages across them.

Azure Storage のスケーラビリティおよびパフォーマンスのターゲット」で、現在のスケーラビリティ ターゲットを確認してください。View current scalability targets at Azure Storage Scalability and Performance Targets.

Nagle のオフNagle Off

Nagle アルゴリズムについて論じているテーブル構成のセクションを参照してください。Nagle アルゴリズムは、一般的にキュー要求のパフォーマンスに適していないため、無効にする必要があります。See the section on table configuration that discusses the Nagle algorithm — the Nagle algorithm is generally bad for the performance of queue requests, and you should disable it.

メッセージ サイズMessage Size

メッセージ サイズが増加すると、キューのパフォーマンスとスケーラビリティが低下します。Queue performance and scalability decrease as message size increases. メッセージには、受信者が必要な情報のみを含める必要があります。You should place only the information the receiver needs in a message.

一括取得Batch Retrieval

1 回の操作でキューから最大 32 個のメッセージを取得できます。You can retrieve up to 32 messages from a queue in a single operation. これにより、クライアント アプリケーションの取得回数を減らすことができ、モバイル デバイスなどの待機時間が長い環境では特に役立ちます。This can reduce the number of roundtrips from the client application, which is especially useful for environments, such as mobile devices, with high latency.

キューのポーリング間隔Queue Polling Interval

多くのアプリケーションはキューからメッセージをポーリングします。キューは、そのアプリケーションにとって最大のトランザクション ソースの 1 つです。Most applications poll for messages from a queue, which can be one of the largest sources of transactions for that application. ポーリング間隔を適切に選択します。ポーリング頻度が高すぎると、アプリケーションはキューのスケーラビリティ ターゲットに近づく可能性があります。Select your polling interval wisely: polling too frequently could cause your application to approach the scalability targets for the queue. ただし、200,000 トランザクションあたり 0.01 ドル (記事の執筆時点) で、1 つのプロセッサが 1 か月間 1 秒に 1 回ポーリングする場合、そのコストは 15 セントにも満たないため、通常、コストはポーリング間隔の選択に影響を与える要因ではありません。However, at 200,000 transactions for $0.01 (at the time of writing), a single processor polling once every second for a month would cost less than 15 cents so cost is not typically a factor that affects your choice of polling interval.

最新のコストの情報については、「 Azure Storage 料金」をご覧ください。For up-to-date cost information, see Azure Storage Pricing.

UpdateMessageUpdateMessage

UpdateMessage を使用すると、非常時タイムアウトを長くしたり、メッセージの状態情報を更新したりすることができます。You can use UpdateMessage to increase the invisibility timeout or to update state information of a message. この機能は効果的ですが、各 UpdateMessage 操作はスケーラビリティ ターゲットにカウントされることに留意してください。While this is powerful, remember that each UpdateMessage operation counts towards the scalability target. しかし、それでもジョブの手順が完了するごとに、次のキューにジョブを渡すワークフローに比べると、はるかに効率的な方法です。However, this can be a much more efficient approach than having a workflow that passes a job from one queue to the next, as each step of the job is completed. UpdateMessage 操作を使用すると、アプリケーションは、ジョブの各手順が完了するたびに次の手順のメッセージを再キューイングするのではなく、ジョブ状態をメッセージに保存して、処理を継続できるようになります。Using the UpdateMessage operation allows your application to save the job state to the message and then continue working, instead of requeuing the message for the next step of the job every time a step completes.

詳細については、キューに配置されたメッセージの内容を変更する方法に関する記事を参照してください。For more information, see the article How to: Change the contents of a queued message.

アプリケーションのアーキテクチャApplication architecture

アプリケーション アーキテクチャの拡張性を確保するには、キューを使用します。You should use queues to make your application architecture scalable. 以下のリストは、キューを使用して、アプリケーションの拡張性を高めるための方法を示しています。The following lists some ways you can use queues to make your application more scalable:

  • キューを使用して、処理に関する作業のバックログを作成し、アプリケーションのワークロードを平滑化するために利用できます。You can use queues to create backlogs of work for processing and smooth out workloads in your application. たとえば、アップロード済み画像のサイズ変更など、プロセッサの負荷が高い作業の要求をキューに残しておくことができます。For example, you could queue up requests from users to perform processor intensive work such as resizing uploaded images.
  • キューを使用して、アプリケーションの一部を切り離し、個別に拡張することができます。You can use queues to decouple parts of your application so that you can scale them independently. たとえば、Web フロントエンドがユーザーから得られた調査結果をキューに配置し、将来の解析とストレージに活用できます。For example, a web front end could place survey results from users into a queue for later analysis and storage. 必要に応じて、キュー データを処理する worker ロール インスタンスを追加できます。You could add more worker role instances to process the queue data as required.

まとめConclusion

この記事では、Azure Storage 使用時のパフォーマンスを最適化する実証済みプラクティスのうち、よく用いられるものをいくつか取り上げました。This article discussed some of the most common, proven practices for optimizing performance when using Azure Storage. すべてのアプリケーション開発者に対して、この記事で示した個々のプラクティスに照らしてアプリケーションを評価し、推奨事項に基づく動作によって、Azure Storage を使用するアプリケーションが優れたパフォーマンスを発揮できるように検討することをお勧めします。We encourage every application developer to assess their application against each of the above practices and consider acting on the recommendations to get great performance for their applications that use Azure Storage.