如何在分片环境中管理集中值

时间:2012-11-08 03:57:36

标签: azure

我有一个为Windows Azure开发的ASP.NET应用程序。我们认为有必要为数据库使用分片来改善写入时间,因为应用程序非常重写,但数据很容易被隔离。但是,我需要跟踪所有实例中的一些中心变量,而且我不确定存储该信息的最佳位置。我有什么选择?

要求:

  • 必须耐用,可以在实例重新启动后继续存在
  • 必须同步。在这种情况下避免冲突更新或至少抛出异常非常重要,而不是覆盖值或静默失败。
  • 必须相当快(每秒读取/写入2000次以上)

我考虑过编写一个单独的组件来运行一个worker角色,它只是在内存中读取/写入值并且每隔一段时间将它们刷回磁盘,但我认为必须已经为此目的编写了一些东西,我可以适用于Windows Azure。

我认为我正在寻找的是像Apache ZooKeeper这样的系统,但我不想在工作角色启动期间和所有那些爵士乐中处理安装JRE。

编辑:根据以下建议,我尝试使用以下代码使用Azure表存储:

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.不查询项目的上下文,最初将其添加到上下文跟踪机制中吗?

3 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

您需要的是Table Storage,因为它符合您的所有要求:

  • 持久:是的,表存储是存储帐户的一部分,它与特定的云服务或实例无关。
  • 已同步:是,表存储是存储帐户的一部分,它与特定的云服务或实例无关。
    • 避免更新冲突非常重要:是的,这可以通过使用 ETags
    • 来实现
  • 合理快?非常快,up to 20,000 entities/messages/blobs per second

<强>更新

以下是一些使用新存储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匹配):
  5.   

    远程服务器返回错误:(412)Precondition Failed。

答案 2 :(得分:0)

我最终得到了混合缓存/表存储解决方案。所有实例都通过Azure缓存跟踪变量,而第一个实例会旋转一个计时器,该值每秒将值保存到表存储一次。启动时,缓存变量将初始化,并保存到表存储的值(如果可用)。