刘钱超,吴 利,郑礼辉
(江南计算技术研究所,江苏 无锡 214083)
随着大数据、云计算等软件技术的飞速发展,基于虚拟机集群的分布式软件运行环境构建方式资源开销大、耗时长、可伸缩性差等缺点逐渐显露,降低了软件运行效率,增加了运维成本,而具有高可伸缩性和高资源使用率等优势的容器云环境为上述问题提供了优化方案[1-2]。
容器云是以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管理者提供用于构建、发布和运行分布式应用的平台[3]。基于容器云构建软件运行环境,与基于虚拟机集群方式相比,具有简化软件部署方式、优化管理运维模式和降低运维成本等优势。然而,容器云作为一种全新的云环境解决方案,在集群动态伸缩策略方面仍存在不足。集群的动态伸缩[4-6]是指集群能够根据工作负载的变化动态地调整自身规模,从而调整其对外服务的能力。目前,容器云采用的是基于阈值的响应式伸缩策略,该策略只会对系统资源的实时情况进行响应,因而系统的伸缩调整往往会晚于工作负载的变化,导致服务质量不佳,用户体验较差。
目前,已有很多关于云环境下集群动态伸缩策略的改进研究。文献[7]提出一种基于工作流模型的虚拟机动态分配和回收策略,能够较大程度地提高系统资源利用率,但该策略不能对集群未来工作负载进行预测。文献[8]针对基于虚拟机的资源管理难以实现细粒度的资源动态调整与混合云中跨平台服务快速迁移的问题,提出一种基于容器技术的云计算资源自适应管理方法,能够提高集群自适应响应速度和集群整体性能,但该方法也不能对集群未来工作负载进行预测。文献[9]提出一种基于集群负载预测的虚拟机资源管理框架,能够实现对未来工作负载预测并及时做出伸缩响应,保证服务质量,但该框架底层是基于虚拟机资源实现,由于虚拟机启停耗时长,集群伸缩响应速度仍然较慢。
针对文献[7-8]不能对未来工作负载进行预测和文献[9]中基于虚拟机资源响应速度慢的不足,提出一种基于二次移动平均法的预测式容器云伸缩方法。该方法可以对未来工作负载进行预测并依托容器轻量特点快速做出伸缩响应,从而降低服务响应时间的波动幅度,提高服务的质量和稳定性。
集群动态伸缩技术包括响应式伸缩[10]和预测式伸缩[11]两种。
(1)响应式伸缩。
基于阈值的响应式伸缩策略因算法实现简单,对集群突发式负载具有较好效果,目前被广泛应用于云平台伸缩决策中。响应式伸缩策略需要对响应规则和阈值进行设定。算法运行时,会对系统内资源(CPU、网络、存储、内存等)进行监控,一旦监测到某些指标超过既定阈值,集群会发出相应的扩展或收缩命令。具体来说,如图1(a)所示,t1时刻通过对系统资源进行持续监控,当t2时刻监测到系统资源有较大变化且超过阈值(包括上下限阈值)时,开始进行集群伸缩,t5时刻完成伸缩。基于阈值的响应式伸缩策略存在的不足是无法对未来负载进行预测,只能对系统资源的实时情况进行响应,因而系统的伸缩调整往往会晚于工作负载的变化,导致服务质量不佳,用户体验变差。
(2)预测式伸缩。
预测式伸缩策略是对过去一段时间内系统资源使用情况进行分析,然后利用数学方法进行建模并完成对未来时刻的预测。它能够较好克服响应式伸缩策略存在时间滞后性的缺点。具体来说,如图1(b)所示,当t1时刻根据历史数据特点预测到t6时刻系统资源使用发生较大改变且超过所设置的阈值时,系统会在t2时刻发出伸缩命令,因而系统能在t6时刻负载发生大幅变化之前有充足时间完成伸缩操作,从而能够及时响应系统资源变化。
图1 两种伸缩方式
根据上述对两种伸缩策略的分析,文中结合使用预测式伸缩策略与响应式伸缩策略,在对集群突发式负载具有良好响应效果的同时,也可以实现对未来时刻负载值的预测,克服响应式伸缩策略存在时间滞后性的不足,从而提高集群资源响应速度,更好地保障应用服务的质量和稳定性。
预测式伸缩策略常采用的分析方法主要有时间序列分析和机器学习[12],但机器学习需要较长模型训练时间,适用性不强。
二次移动平均法(又名二重移动平均法)是一种时间序列分析方法,它是在预测目标时间序列上的一次移动平均值的基础上再进行一次移动平均,并将结果代入到相关公式中得到预测值,目的是解决一次移动平均法存在滞后偏差,使得预测值总是落后于实际观测值的问题。它适用于数据随某个变量呈现自相关特性的场景,考虑到容器云中应用的资源使用情况可能随时间呈现一定规律,因此文中选取二次移动平均法对未来时刻负载值进行预测。其数学计算公式如下:
假设xt,xt-1,…,xt-n+1为系统在时刻t的历史数据序列,因此t时刻数据序列的一次移动平均值为:
(1)
t时刻的二次移动平均值为:
(2)
(3)
(4)
(5)
因此基于二次移动平均法,对t时刻历史数据序列进行分析,可以计算出t+T时刻的预测值:
(6)
图2为文中提出的容器云伸缩算法的决策过程。在算法运行过程中,系统内会维护一张容器服务最近L次响应时间记录表H,通过对系统内容器服务(Service_ID)的响应时间tres进行持续监控并用获取到的数据不断更新记录表H。决策模块会对表H中最近L次响应时间进行处理、建模、预测,得到未来时刻的预测值tpre,根据实时响应时间数据以及预测值,利用基于阈值的响应式伸缩策略进行系统伸缩决策,并将伸缩命令传递给伸缩执行模块执行。执行完毕后,判断伸缩算法是否继续运行,根据判断结果来决定继续循环或终止该算法。
图2 容器云伸缩决策过程
如图3所示,伸缩算法包含Monitor、Processor、Commander和Scheduler四个模块。
图3 伸缩算法模块
(1)Monitor模块。
Monitor模块负责对应用服务响应时间tres持续监控,并用获取到的响应时间序列不断更新表H,使表H始终保持存储最近L次应用服务响应时间。设定更新表H的策略为每次获取服务响应时间tres后,将其加入到链表尾部,同时将链表首元素删除。在Monitor获取到服务响应时间后,同时也将采集到的数据传递给Commander模块。
(2)Processor模块。
Processor模块主要对表H中最近L次服务响应时间数据进行分析、建模和对未来时刻值的预测。在具体算法实现时,假设表H中存储的最近L次服务响应时间序列为:xt-L+1,xt-L+2,…,xt-1,xt,设置好二次移动平均法参数n和预测间隔T后,基于二次移动平均法,根据表H中L条数据使用式6预测t+T时刻的服务响应时间值xt+T,并将预测值传递给Commander模块。
(3)Commander模块。
Commander模块会对Monitor模块采集到的实时服务响应时间tres和Processor模块利用二次移动平均法计算出的响应时间预测值tpre依据基于阈值的响应式伸缩策略进行判断,如果tres>Tu‖tpre>Tu(Tu为响应时间阈值上限)关系成立,说明系统内服务响应时间过长,质量较差,因此Commander模块会向Sch-eduler模块发出扩展命令,由Scheduler模块完成容器服务扩展(算法1中4~6行))。如果tres
算法1:伸缩决策算法。
Input:tres,H,Tu,Td,Service_ID
Output:Scale_Dec
1 Begin
2 While(algorithm is running)
3 Monitor and Collecttres,Maintain the tableH,calculate the valuetpre
4 iftres>Tu||tpre>Tu
5 send(Extension,E,Service_ID) command to Scheduler
6 end if
7 iftres
8 send(Contraction,E,Service_ID) command to Scheduler
9 end if
10 end While
11 End
(4)Scheduler模块。
Scheduler模块保存了一份对所有主机的评分表。集群中所有备选主机的CPU使用率、内存占用率以及网络带宽占用率每隔一段时间就会被Scheduler模块收集,并依据式7进行评分和记录到评分表中,通过评分高低来决定在哪台主机上进行容器服务的伸缩。
Scorei=(3-CPU_use-Mem_use-Net_use),Scorei∈(0,3)
(7)
其中,CPU_use为CPU使用率;Mem_use为内存占用率;Net_use为网络带宽占用率。
同时,扩展时需要计算扩展容器服务个数N。假设需要扩展的资源为E,单个容器持有资源为E0,因此可得N=E/E0。当需要进行收缩资源时,为防止因系统突然减少大量资源造成系统运行异常,设定收缩资源时,每次释放1个容器服务。
Scheduler模块在运行过程中,需要接收由Commander模块发出的命令,如果收到的是扩展命令,选择当前打分表中分数最高的主机,根据服务ID及新建容器命令,在指定主机上部署N个指定ID的容器,对外提供服务并将其记录到Service记录表S中,扩展工作结束。此时为了避免因频繁伸缩导致系统剧烈“抖动”,伸缩算法进入一小段时间的休眠期(算法2中3~8行);如果收到的是收缩命令,选择当前打分表中分数最低且其上运行着相关服务的主机。分数低意味着其上负载较重,因此在释放资源时,为了维持负载均衡,首先移除负载较重主机上的服务,减轻其上负载压力。主机选定后,根据容器服务的ID,使用相关命令移除1个容器服务,回收资源并更新Service记录表S的内容,收缩工作结束。同样,为了避免因频繁伸缩导致系统剧烈“抖动”,伸缩算法进入一小段时间的休眠期(算法2中9~14行)。
算法2:伸缩执行算法。
Input:(COMMAND,E,Service_ID)
Output:UpdatedS
1Begin
2 While(algorithm is running)
3 if “COMMAND” equals “Extension”
4 calculateN=E/E0;
5 Select the highest Score of the physical machine and deployN
6 Service_ID container service,updateS;
7 Sleep(a period of time);
8 end if
9 if “COMMAND” equals “Contraction”
10N=1;
11 Select the lowestScoreof the physical machine and removeN
12 Service_ID container service,updateS;
13 Sleep(a period of time);
14 end if
15 end While
16 End
实验搭建了两个四节点的Docker swarm[13]集群,分别为集群1和集群2。集群1为无任何修改的Docker swarm集群,即原生集群,采用的是响应式伸缩策略。集群2为依据文中提出的伸缩策略改进后的Docker swarm集群。实验需要使用的工具包括并发测试执行工具Jmeter以及反向代理器Nginx。实验硬件包含6台PC机,各节点配置及安装环境如表1所示。
表1 集群信息
续表1
图4为实验过程中主机之间的访问顺序。测试机通过其上安装的Jmeter测试软件以并发方式访问swarm集群中容器Web认证服务(实验条件下只生成一类服务),并记录服务响应时间的变化情况。同时为了更好地验证提出的伸缩方法,在访问链路中加入了Nginx服务器来进行消息转发。
图4 实验过程中主机之间的访问顺序
文中提出的伸缩策略在具体算法实现时,L值设置为10,容器扩展和收缩个数N设置为1,响应时间阈值上限设置为0.9 s,阈值下限设置为0.2 s。二次移动平均法中n设置为2,预测时刻间隔T设置为1,也即根据t时刻的3个响应时间值,使用二次移动平均法可以预测t+1时刻的响应时间值。
表2为实验负载数据。实验负载数据分为两类:周期性负载数据和突发式负载数据。
表2 实验负载数据
续表2
图5为施加周期性负载的实验结果。
图5 周期性负载实验结果
当请求数为50、120时,文中提出的算法和纯响应式伸缩算法效果一致,两条曲线在图中完全重合。原因是此时服务的实时响应时间和响应时间的预测值均未超过响应时间的阈值上限,没有触发容器云集群的伸缩机制。当请求数增长至230时,文中算法下个时刻的服务响应时间预测值已经超出了阈值上限,因此会选择一台分数最高的主机新建一个对应容器并提供服务。当请求数继续增长至320时,由于文中算法已提前扩展了容器服务,服务的响应时间减至约为纯响应式伸缩算法的一半,而此时纯响应式伸缩算法才判定响应时间超过阈值上限并开始扩展。直到请求数为410时,纯响应式算法扩展效果开始显现,与文中算法效果一致。收缩过程与上述扩展过程类似。
从图5可以看出,对纯响应式伸缩策略,容器服务响应时间波峰为0.9 s,波谷为0.2 s,波动幅度为0.7;而文中提出的优化算法服务响应时间波峰为0.7 s,波谷为0.3 s,波动幅度为0.4。与纯响应式伸缩策略相比,文中算法的服务响应时间的波动幅度降低了约42.9%,有效减弱了由负载变化引起的服务响应时间波动。
图6为施加突发式负载的实验结果。
图6 突发式负载实验结果
从图中可以看出,文中算法与纯响应式伸缩算法结果始终保持一致,两条曲线完全重合。原因为对改进伸缩策略后的Docker swarm集群施加突发式负载时,二次移动平均法无法对未来时刻值进行准确预测,导致预测效果丧失,集群伸缩决策只由服务的实时响应时间和响应时间阈值之间大小关系决定。因此,对于突发式负载,文中算法与纯响应式伸缩算法表现一致。
文中提出的基于二次移动平均法的预测式容器云伸缩策略,在保留基于阈值的响应式伸缩策略对突发式负载具有良好响应效果的同时,在周期性负载条件下还能对未来负载值进行准确预测,提高了容器云对应用资源请求的响应能力,降低了服务响应时间波动幅度,保证了服务响应时间的稳定性。
针对容器云目前基于阈值的响应式伸缩策略存在时间滞后性、难以及时响应服务资源请求的问题,提出一种基于二次移动平均法的预测式容器云伸缩方法。该方法可以对未来工作负载进行预测并依托容器轻量特点快速做出伸缩响应。通过设计两种不同的工作负载场景对改进后容器集群伸缩方法进行了测试,验证了该方法的可行性和有效性。但该方法也存在不足,即对周期性工作负载具有较好的预测效果,而对其他类型工作负载的预测效果并不理想。后续研究可以考虑结合机器学习方法来建立预测模型,提高预测模型在各种工作负载场景下的预测准确性。