关于 Azure Auto Scale 的高级属性配置
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 的功能。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。