0

Windows Azure 用に開発中の ASP.NET アプリがあります。アプリは書き込み負荷が非常に高いが、データは簡単に分離されるため、DB にシャーディングを使用して書き込み時間を改善する必要があると考えられています。ただし、すべてのインスタンスでいくつかの中心的な変数を追跡する必要があり、その情報を保存する最適な場所がわかりません。私のオプションは何ですか?

要件:

  • 耐久性が必要で、インスタンスの再起動に耐えることができます
  • 同期する必要があります。値を上書きしたり黙って失敗したりするのではなく、競合する更新を回避するか、少なくともそのような場合に例外をスローすることが非常に重要です。
  • 適度に高速である必要があります (毎秒 2000 回以上の読み取り/書き込み)

単純にメモリ内の値を読み書きし、頻繁にディスクにフラッシュするワーカー ロールで実行する別のコンポーネントを作成することを考えましたが、その目的のために Windows で適切に使用できるものを既に作成しておく必要があると思います。アズール。

私が探しているのは Apache ZooKeeper のようなシステムだと思いますが、worker ロールの起動中に JRE をインストールする必要はありません。

編集: 以下の提案に基づいて、次のコードを使用して Azure Table Storage を使用しようとしています:

var context = table.ServiceClient.GetTableServiceContext();
var item = context.CreateQuery<OfferDataItemTableEntity>(table.Name)
    .Where(x => x.PartitionKey == Name).FirstOrDefault();

if (item == null)
{
    item = new OfferDataItemTableEntity(Name);
    context.AddObject(table.Name, item);
}                    

if (item.Allocated < Quantity)
{
    allocated = ++item.Allocated;
    context.UpdateObject(item);
    context.SaveChanges();
    return true;
}

ただし、アイテムのコンテキストを最初に照会してコンテキスト追跡メカニズムに追加しないで、context.UpdateObject(item)呼び出しは失敗しThe context is not currently tracking the entity.ますか?

4

3 に答える 3

0

最終的に、ハイブリッド キャッシュ/テーブル ストレージ ソリューションにたどり着きました。すべてのインスタンスは Azure キャッシュを介して変数を追跡しますが、最初のインスタンスは 1 秒に 1 回値をテーブル ストレージに保存するタイマーを起動します。起動時に、キャッシュ変数はテーブル ストレージに保存された値で初期化されます (使用可能な場合)。

于 2012-11-09T15:43:30.317 に答える
0

必要なのは、すべての要件に一致するTable Storageです。

  • 耐久性: はい。Table Storage はストレージ アカウントの一部であり、特定のクラウド サービスやインスタンスとは関係ありません。
  • 同期済み: はい。Table Storage はストレージ アカウントの一部であり、特定のクラウド サービスまたはインスタンスとは関係ありません。
    • 競合する更新を避けることは非常に重要です: はい、これはETagを使用することで可能です
  • 適度に速い?非常に高速で、毎秒最大 20,000 のエンティティ/メッセージ/ブロブ

アップデート:

新しいストレージ SDK (2.0) を使用するサンプル コードを次に示します。

var storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
var table = storageAccount.CreateCloudTableClient()
                            .GetTableReference("Records");
table.CreateIfNotExists();

// Add item.
table.Execute(TableOperation.Insert(new MyEntity() { PartitionKey = "", RowKey ="123456", Customer = "Sandrino" }));

var user1record = table.Execute(TableOperation.Retrieve<MyEntity>("", "123456")).Result as MyEntity;
var user2record = table.Execute(TableOperation.Retrieve<MyEntity>("", "123456")).Result as MyEntity;

user1record.Customer = "Steve";
table.Execute(TableOperation.Replace(user1record));

user2record.Customer = "John";
table.Execute(TableOperation.Replace(user2record));
  1. まず、アイテム 123456 を追加します。
  2. 次に、2 人のユーザーが同じレコードを取得することをシミュレートしています (両方ともレコードを表示するページを開いたとします)。
  3. ユーザー 1 は速く、アイテムを更新します。これは機能します。
  4. ユーザー 2 はまだウィンドウを開いたままにしました。これは、彼がアイテムの古いバージョンに取り組んでいることを意味します。彼は古いアイテムを更新し、保存しようとします。これにより、次の例外が発生します (これは、SDK が ETag と一致するために発生する可能性があります)。

リモート サーバーがエラーを返しました: (412) 前提条件が失敗しました。

于 2012-11-08T07:17:03.743 に答える
0

SQL Azure フェデレーションについて調べましたか? まさにあなたが探しているもののように思えます: SQL Azure のシャーディングです。

ここに読むべきいくつかのリンクがあります:

http://msdn.microsoft.com/en-us/library/windowsazure/hh597452.aspx

http://convective.wordpress.com/2012/03/05/introduction-to-sql-azure-federations/

http://searchcloudapplications.techtarget.com/tip/Tips-for-deploying-SQL-Azure-Federations

于 2012-11-08T04:36:09.457 に答える