Share via


关于Azure Auto Scale的高级属性配置

Auto Scale是一种自动化管理云服务负载的功能,系统可以根据预先制定的规则,在满足条件的情况下对计算实例的数量进行增减从而可以用来优化使用Azure的计算资源,可以适用于Cloud Service、VM、WebSite以及Mobile Service。

Auto Scale有3种主要时间类型的配置,固定时间、周期性时间及无时间配置。每个配置需要指定最小、最大和默认实例数。

  • 固定时间配置多用于一些可预知的固定事件,例如春节、世界杯决赛等负载可预知的情况。
  • 周期性时间配置主要用于负载具有比较明显的时间特征,例如一些业务应用在工作时间负载较高,而在非工作时间上负载非常低。
  • 无时间配置主要用于对系统的负载无法通过时间进行预测,需要根据其他的度量值来进行调整。

除了时间配置之外,还需要定制时间配置下的规则。规则是由度量值触发器及扩展操作组成。

度量值触发器主要是用来描述通过如何收集某种度量信息并在满足何种条件下出发扩展操作。在度量值方面VM的CPU,Storage的blob\queue\table, Service Bus的queue\topics\notification hubs等多种度量信息,关于Auto Scale可以支持具体信息可以参考Azure Service Management REST API Reference。

扩展操作主要是用来定义当度量值触发器被触发时系统需要执行的操作,需要定义操作是增加还是减少实例,每次增加或减少的实例数量,以及距离上一次扩展操作之间的冷却时间。

其中需要特别注意的是关于TimeGrain和TimeWindow的设置。TimeGrain主要用于设置数据收集的频率,默认设置是5分钟,最小值可以为1分钟。TimeWindow的主要是用来指定被收集数据的时间范围,默认值为45分钟,最小值可以为5分钟。另外还有一点需要注意在收集到的数据并不是实时数据,通常会有15分钟的延迟,这个与我们在VM上能够看到的度量信息的延迟是一样的。

最近在一些项目中客户反馈Auto Scale的延迟较大,也就是说高负载出现后系统并没有及时的进行扩展,其中主要的问题是并没有对系统的默认值进行修改,如果需要Auto Scale在出现系统压力后尽快的进行扩展并可以将TimeGrain和TimeWindow的值修改的更小一些。但是在设置的时候也需要考虑到增加或减少实例也是需要一定的时间,如果时间设置的过短可能并不能很好的应对负载增加的情况,例如突发在20分钟里出现高峰但是当完成一次增加实例后峰值可能已经过去,这样并不能有效的应对并节约成本。所以在调整TimeGrain和TimeWindow时需要对扩展的实例所需的时间以及应对的场景进行评估。

这些高级配置并不能通过Management Portal进行直接设置,需要通过REST API进行设置或者也可以通过Windows Azure Compute Management Library 进行配置。由于 Windows Azure Compute Management Library目前还是Preview的版本,所以需要通过在Visual Studio中的Nuget Console中通过命令行添加进行引用

PM> Install-Package Microsoft.WindowsAzure.Management.Compute -Version 0.9.0-preview -Pre

下面的方法可以用来显示在指定云服务中相应角色的Auto Scale配置

private static void ShowProfile(string subscriptionId,string base64EncodedCertificate,string cloudServiceName,string roleName)

{

var autoscaleClient = new AutoscaleClient(GetCredentials(subscriptionId, base64EncodedCertificate), new Uri(ManagementEndpoint));

string resourceId = AutoscaleResourceIdBuilder.BuildCloudServiceResourceId(cloudServiceName, roleName, true);

var autoscaleSettingGetResponse = autoscaleClient.Settings.Get(resourceId);

foreach (var profile in autoscaleSettingGetResponse.Setting.Profiles)

{

Console.WriteLine("Profile:{0}", profile.Name);

Console.WriteLine("Capacity: Default-{0},Max-{1},Min-{2}", profile.Capacity.Default, profile.Capacity.Maximum, profile.Capacity.Minimum);

if(profile.FixedDate!=null)

Console.WriteLine("Fixed date: start-{0} End-{1} timezone-{2}", profile.FixedDate.Start, profile.FixedDate.End, profile.FixedDate.TimeZone);

if (profile.Recurrence != null)

{

Console.WriteLine("Frequency:{0}", profile.Recurrence.Frequency);

if(profile.Recurrence.Schedule!=null)

{

Console.WriteLine("TimeZone:{0}",profile.Recurrence.Schedule.TimeZone);

Console.WriteLine("Days");

foreach (var day in profile.Recurrence.Schedule.Days)

{

Console.Write(day+" ");

}

Console.WriteLine();

Console.WriteLine("Hours");

foreach(var hour in profile.Recurrence.Schedule.Hours)

{

Console.Write(hour + " ");

}

Console.WriteLine();

Console.WriteLine("Minutes");

foreach (var min in profile.Recurrence.Schedule.Minutes)

{

Console.Write(min + " ");

}

Console.WriteLine();

}

}

if (profile.Rules != null || profile.Rules.Count > 0)

{

foreach (var rule in profile.Rules)

{

ConsoleColor c = Console.ForegroundColor;

Console.ForegroundColor = ConsoleColor.Green;

Console.WriteLine("MetricTrigger");

Console.ForegroundColor = c;

Console.WriteLine("MetricName:{0}",rule.MetricTrigger.MetricName);

Console.WriteLine("MetricNamespace:{0}",rule.MetricTrigger.MetricNamespace);

Console.WriteLine("MetricSource:{0}",rule.MetricTrigger.MetricSource);

Console.WriteLine("Operator:{0}",rule.MetricTrigger.Operator);

Console.WriteLine("Statistic:{0}",rule.MetricTrigger.Statistic);

Console.WriteLine("Threshold:{0}", rule.MetricTrigger.Threshold);

Console.WriteLine("TimeAggregation:{0}",rule.MetricTrigger.TimeAggregation);

Console.WriteLine("TimeGrain:{0}",rule.MetricTrigger.TimeGrain);

Console.WriteLine("TimeWindow:{0}",rule.MetricTrigger.TimeWindow);

Console.ForegroundColor = ConsoleColor.Green;

Console.WriteLine("ScaleAction");

Console.ForegroundColor = c;

Console.WriteLine("ScaleActionType:{0}",rule.ScaleAction.Type);

Console.WriteLine("Direction:{0}",rule.ScaleAction.Direction);

Console.WriteLine("Cooldown:{0}",rule.ScaleAction.Cooldown);

Console.WriteLine("Value:{0}",rule.ScaleAction.Value);

}

}

}

}

下面的方法用于更新指定云服务中相应角色的Auto Scale的配置

private static void UpldateAutoScaleWindow(string subscriptionId,string base64EncodeCertificate, string cloudServiceName,string roleName,int timeGrain,int timeWindow,int cooldown)

{

var autoscaleClient = new AutoscaleClient(GetCredentials(SubscriptionId,Base64EnCodedCertificate), new Uri(ManagementEndpoint));

string resourceId = AutoscaleResourceIdBuilder.BuildCloudServiceResourceId(cloudServiceName, roleName, true);

var setting = autoscaleClient.Settings.Get(resourceId).Setting;

foreach (var profile in setting.Profiles)

{

foreach(var rule in profile.Rules)

{

rule.MetricTrigger.TimeGrain = TimeSpan.FromMinutes(timeGrain);

rule.MetricTrigger.TimeWindow = TimeSpan.FromMinutes(timeWindow);

rule.ScaleAction.Cooldown = TimeSpan.FromMinutes(cooldown);

}

}

var parameter = new AutoscaleSettingCreateOrUpdateParameters();

parameter.Setting = setting;

autoscaleClient.Settings.CreateOrUpdate(resourceId, parameter);

}

Auto Scale并不是银弹也会有一定的使用场景和限制,如果对系统的性能有很高要求时,需要通过严格的性能测试来评估系统的容量及性能并合理设置相关的度量数据收集时间间隔以及相关的阀值,另外还需要结合对于系统负载产生的过程建立合理的时间计划,这样才能更好的发挥Auto Scale的功能。