每次交易创建CloudTableClient和CloudTable的新实例

时间:2016-04-13 12:20:38

标签: azure azure-storage azure-table-storage

在做了一些研究之后,我仍然不确定如何最好地维护与Azure Table Storage的“连接”。是否应该在请求之间重复使用CloudTableClientCloudTable个实例?

我们在公共的高流量API背后使用表存储。我们需要高读取可用性和性能。所有查询都是POINT查询(分区键和行键都可用),响应支付的大小很小(小于1千字节)。写性能不是一个大问题。 API上的每个请求都可以在几个分区中读取最多10个点查询。

从我的阅读中,我理解了以下内容:

  • CloudTableClient不是线程安全的,应该为每个事务创建。显然,这不应该在连续重新创建时妨碍性能。

  • 因此,还必须为每笔交易创建CloudTable个实例。

这些是正确的假设吗?

因此,我为每个请求重新初始化CloudTableClientCloudTable。这感觉很浪费。

见实施:

public class EntityStorageComponent : IEntityComponent
{
    private CloudStorageAccount storageAccount;

    public CloudTable Table
    {
        get
        {
            var tableClient = storageAccount.CreateCloudTableClient();

            ServicePoint tableServicePoint = ServicePointManager.FindServicePoint(storageAccount.TableEndpoint);
            tableServicePoint.UseNagleAlgorithm = false;
            tableServicePoint.ConnectionLimit = 100;

            var context = new OperationContext();
            context.Retrying += (sender, args) =>
            {
                Debug.WriteLine("Retry policy activated");
            };

            // Attempt delays: ~200ms, ~200ms, ~200ms
            var requestOptions = new TableRequestOptions
            {
                RetryPolicy = = new LinearRetry(TimeSpan.FromMilliseconds(200), 3),
                MaximumExecutionTime = TimeSpan.FromSeconds(60)
            };

            var table = tableClient.GetTableReference("farematrix");
            table.CreateIfNotExists(requestOptions, context);

            return table;                
        }
    }

    public EntityStorageComponent(IOptions<ConfigurationOptions> options)
    {
        storageAccount = CloudStorageAccount.Parse(options.Value.TableStorageConnectionString);
    }

    public SomeEntity Find(Guid partitionKey, Guid rowKey)
    {
        var retrieveOperation = TableOperation.Retrieve<SomeEntity>(partitionKey, rowKey);

        var retrievedResult = Table.Execute(retrieveOperation);

        return retrievedResult.Result as SomeEntity;
    }
}

1 个答案:

答案 0 :(得分:10)

除了创建对象的通常开销之外,我在创建CloudTableClientCloudTable个对象的多个实例时没有看到任何问题。因此,如果您只是执行以下操作,我认为您不会明智地获得性能:

        var tableClient = storageAccount.CreateCloudTableClient();
        var table = tableClient.GetTableReference("farematrix");

但是,我确实发现您在代码(CloudTable成员)中创建Table的方式存在问题。基本上在您的代码中,只要您从Table获得EntityStorageComponent属性,就会尝试在存储帐户中创建一个表。

        var table = tableClient.GetTableReference("farematrix");
        table.CreateIfNotExists(requestOptions, context);

这是一个问题,因为table.CreateIfNotExists(requestOptions, context);会进行网络通话,并会大大减慢您的系统速度。您可能希望移出table.CreateIfNotExists(requestOptions, context);代码并将其放入启动代码中,以便您(大多数)始终确定该表存在。