Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating new instances of CloudTableClient and CloudTable per transaction

After doing some research, I am still unsure how best to maintain a 'connection' to Azure Table Storage. Should CloudTableClient or CloudTable instances be reused across requests?

We are using Table Storage behind a public, high-traffic API. We require high read availability and performance. All queries are POINT queries (both partition key and row key are available) and the response payment is small in size (less than 1 kilobyte). Write performance is not a big concern. Each request on the API could read up to 10 point queries across a few partitions.

From my reading, I have understood the following:

  • CloudTableClient is not thread-safe and should be created for every transaction. Apparently this shouldn't hamper performance when being recreated continuously.

  • A CloudTable instance will thus also have to be created for each transaction.

Are these the correct assumptions to make?

I am thus reinitialising CloudTableClient and CloudTable for every request. It feels wasteful.

See implementation:

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;
    }
}
like image 613
Dave New Avatar asked Apr 13 '16 12:04

Dave New


People also ask

Can two entities in same table storage contain different collection of properties of different types?

An entity has a primary key and a set of properties. A property is a name, typed-value pair, similar to a column. The Table service does not enforce any schema for tables, so two entities in the same table may have different sets of properties.

What is the maximum amount of data that can be stored in a Azure table storage database?

An entity in Azure Storage can be up to 1MB in size. An entity in Azure Cosmos DB can be up to 2MB in size. Properties: A property is a name-value pair. Each entity can include up to 252 properties to store data.

What is the difference between Azure table storage and Cosmos DB?

Azure Table Storage supports a single region with an optional read-only secondary region for availability. Cosmos DB supports distribution from 1 to more than 30 regions with automatic failovers worldwide. You can easily manage this from the Azure portal and define the failover behavior.

What is partition key and RowKey in Azure table storage?

A RowKey in Table Storage is a very simple thing: it's your “primary key” within a partition. PartitionKey + RowKey form the composite unique identifier for an entity. Within one PartitionKey, you can only have unique RowKeys. If you use multiple partitions, the same RowKey can be reused in every partition.


1 Answers

Apart from the usual overhead of creating an object, I don't see any issue in creating multiple instances of CloudTableClient and CloudTable objects. So if you're simply doing the following, I don't think you're going to get hit performance wise:

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

However I do see an issue with the way you're creating CloudTable in your code (Table member). Essentially in your code, anytime you get the Table property from EntityStorageComponent, you're trying to create a table in your storage account.

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

This is a problem because table.CreateIfNotExists(requestOptions, context); will make a network call and would slow down your system considerably. You may want to move out table.CreateIfNotExists(requestOptions, context); code and put that in your startup code so that you're always sure (mostly) that the table is present.

like image 183
Gaurav Mantri Avatar answered Oct 28 '22 16:10

Gaurav Mantri