加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 如何减少Azure表存储延迟?

发布时间:2020-12-16 03:16:57 所属栏目:asp.Net 来源:网络整理
导读:我有一个相当庞大的(30毫升行,每个最多5-100Kb)表在Azure上. 每个RowKey都是一个Guid,而PartitionKey是第一个Guid部分,例如: PartitionKey = "1bbe3d4b"RowKey = "1bbe3d4b-2230-4b4f-8f5f-fe5fe1d4d006" 表每秒有600次读取和600次写入(更新),平均延迟为60m
我有一个相当庞大的(30毫升行,每个最多5-100Kb)表在Azure上.
每个RowKey都是一个Guid,而PartitionKey是第一个Guid部分,例如:

PartitionKey = "1bbe3d4b"
RowKey = "1bbe3d4b-2230-4b4f-8f5f-fe5fe1d4d006"

表每秒有600次读取和600次写入(更新),平均延迟为60ms.所有查询都使用PartitionKey和RowKey.
但是,有些读取需要3000毫秒(!).平均而言,所有读取中的> 1%花费超过500ms并且与实体大小没有相关性(在25ms中可以返回100Kb行,在1500ms中可以返回10Kb).

我的应用程序是在4-5个大型实例上运行的ASP.Net MVC 4网站.

我已阅读有关Azure表存储性能目标的所有MSDN文章,并已执行以下操作:

> UseNagle已关闭
> Expect100Continue也被禁用
>表客户端的MaxConnections设置为250(设置1000-5000没有任何意义)

我也检查过:

>存储帐户监控计数器没有限制错误
>性能中存在某种“波浪”,但它们并不依赖于负载

这种性能问题可能是什么原因以及如何改进?

解决方法

如果我不打算很快更新实体,我会使用 DataServiceContext.MergeOption属性上的 MergeOption.NoTracking设置获得额外的性能.这是一个例子:

var account = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString"));
var tableStorageServiceContext = new AzureTableStorageServiceContext(account.TableEndpoint.ToString(),account.Credentials);
tableStorageServiceContext.RetryPolicy = RetryPolicies.Retry(3,TimeSpan.FromSeconds(1));
tableStorageServiceContext.MergeOption = MergeOption.NoTracking;
tableStorageServiceContext.AddObject(AzureTableStorageServiceContext.CloudLogEntityName,newItem);
tableStorageServiceContext.SaveChangesWithRetries();

另一个问题可能是你正在检索整个enity及其所有属性,即使你只想使用一个或两个属性 – 这当然是浪费但不能轻易避免.但是,如果您使用Slazure,那么您可以使用查询投影仅从表存储中检索您感兴趣的实体属性,仅此而已,这将为您提供更好的查询性能.这是一个例子:

using SysSurge.Slazure;
using SysSurge.Slazure.Linq;
using SysSurge.Slazure.Linq.QueryParser;

namespace TableOperations
{
    public class MemberInfo
    {
        public string GetRichMembers()
        {
            // Get a reference to the table storage
            dynamic storage = new QueryableStorage<DynEntity>("UseDevelopmentStorage=true");

            // Build table query and make sure it only return members that earn more than $60k/yr
            // by using a "Where" query filter,and make sure that only the "Name" and 
            // "Salary" entity properties are retrieved from the table storage to make the
            // query quicker.   
            QueryableTable<DynEntity> membersTable = storage.WebsiteMembers;
            var memberQuery = membersTable.Where("Salary > 60000").Select("new(Name,Salary)");

            var result = "";

            // Cast the query result to a dynamic so that we can get access its dynamic properties
            foreach (dynamic member in memberQuery)
            {
                // Show some information about the member
                result += "LINQ query result: Name=" + member.Name + ",Salary=" + member.Salary + "<br>";
            }

            return result;
        }
    }
}

完全披露:我编码了Slazure.

如果要检索大型数据集,也可以考虑分页,例如:

// Retrieve 50 members but also skip the first 50 members
var memberQuery = membersTable.Where("Salary > 60000").Take(50).Skip(50);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读