Azure 为每个事务创建CloudTableClient和CloudTable的新实例
在做了一些研究之后,我仍然不确定如何最好地维护到Azure表存储的“连接”。Azure 为每个事务创建CloudTableClient和CloudTable的新实例,azure,azure-storage,azure-table-storage,Azure,Azure Storage,Azure Table Storage,在做了一些研究之后,我仍然不确定如何最好地维护到Azure表存储的“连接”。CloudTableClient或CloudTable实例是否应跨请求重用 我们在一个公共的、高流量的API后面使用表存储。我们需要高读可用性和高性能。所有查询都是点查询(分区键和行键都可用),响应支付的大小很小(小于1 KB)。写性能不是一个大问题。API上的每个请求可以跨几个分区读取多达10个点的查询 通过阅读,我了解到以下几点: CloudTableClient不是线程安全的,应该为每个事务创建。显然,在连续重新
CloudTableClient
或CloudTable
实例是否应跨请求重用
我们在一个公共的、高流量的API后面使用表存储。我们需要高读可用性和高性能。所有查询都是点查询(分区键和行键都可用),响应支付的大小很小(小于1 KB)。写性能不是一个大问题。API上的每个请求可以跨几个分区读取多达10个点的查询
通过阅读,我了解到以下几点:
不是线程安全的,应该为每个事务创建。显然,在连续重新创建时,这不应该影响性能CloudTableClient
- 因此,还必须为每个事务创建一个
实例。CloudTable
CloudTableClient
和CloudTable
。感觉很浪费
参见实施:
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;
}
}
公共类EntityStorageComponent:EntityComponent
{
私有云存储账户;
公共云表
{
得到
{
var tableClient=storageAccount.CreateCloudTableClient();
ServicePoint tableServicePoint=ServicePointManager.FindServicePoint(storageAccount.TableEndpoint);
tableServicePoint.UseNagleAlgorithm=false;
tableServicePoint.ConnectionLimit=100;
var context=new OperationContext();
context.Retrying+=(发送方,参数)=>
{
Debug.WriteLine(“重试策略已激活”);
};
//尝试延迟:~200ms、~200ms、~200ms
var requestOptions=new TableRequestOptions
{
RetryPolicy==新的线性重试(TimeSpan.From毫秒(200),3),
MaximumExecutionTime=TimeSpan.FromSeconds(60)
};
var table=tableClient.GetTableReference(“farematrix”);
CreateIfNotExists(请求选项、上下文);
返回表;
}
}
公共实体存储组件(IOOptions选项)
{
storageAccount=CloudStorageAccount.Parse(options.Value.TableStorageConnectionString);
}
公共实体查找(Guid分区键、Guid行键)
{
var retrieveOperation=TableOperation.Retrieve(partitionKey,rowKey);
var retrievedResult=Table.Execute(retrieveOperation);
返回retrievedResult.Result作为SomeEntity;
}
}
除了创建对象的常见开销外,我认为创建CloudTableClient
和CloudTable
对象的多个实例没有任何问题。因此,如果您只是执行以下操作,我认为您不会在性能方面受到影响:
var tableClient = storageAccount.CreateCloudTableClient();
var table = tableClient.GetTableReference("farematrix");
但是,我确实看到您在代码(Table
member)中创建CloudTable
的方式存在问题。本质上,在代码中,只要您从EntityStorageComponent
获取Table
属性,您就会尝试在存储帐户中创建一个表
var table = tableClient.GetTableReference("farematrix");
table.CreateIfNotExists(requestOptions, context);
这是一个问题,因为
table.CreateIfNotExists(requestOptions,context)
将进行网络呼叫,并会大大降低系统速度。您可能希望移出table.CreateIfNotExists(requestOptions,context)编码>编码并将其放在启动代码中,以便您始终(大部分)确定表是否存在。您能解释一下的意思吗?我仍然不确定如何最好地维护与Azure表存储的连接。
?@GauravMantri:基本上,CloudTableClient
或CloudTable
实例是否应跨请求重用?我担心的是,每次请求时(可能是每分钟1000次)都必须重新创建这些文件,这会对性能造成损失。答案太棒了。ThanksQuick问题:您是否建议将ServicePoint
修正案也移至启动(Nagles和ConnectionLimit)?是的。这是系统范围的设置,只能定义一次。在单线程非并发代码中使用CreateIfNotExists时要小心。我犯了一个错误,把它放在处理程序风格的代码中——类似于WCF hander或REST APi处理程序。这将导致多个线程同时运行,并且在第一个线程之后的任何线程都将得到如下错误:“远程服务器返回了一个错误:(409)冲突。”