[关闭]
@maorongrong 2017-12-10T08:50:43.000000Z 字数 13398 阅读 1040

关于毕设研究内容的说明

毕设


背景

当公有云引入docker技术进入微服务时代,由于VM、Docker两类虚拟化技术的特性不同,差别,那么Docker所提供的服务级别隔离和VM提供的租户间完全隔离,必将使得云中心以docker-vm-hm的架构提供服务;与以往传统的vm-hm架构相比,docker技术的引入意味着云中心部署算法、调度算法的粒度可进一步缩小为容器级别,为解决云中心高能耗、负载不均、调度迁移VM的时间代价长等问题提供了新思路

确定研究框架

当部署架构由2层的v-h转变为3层d-v-h将存在的问题 解决思路 解决方法
针对容器新增时希望达到降能耗or均衡负载目标的问题现有研究仅在docker容器层提出简单的binpack、spread、random部署策略;实际上从整个物理集群的角度去衡量,这些策略仅以directly hosted VMs作为衡量标准,而忽视整个集群running HMs/VMs实际资源分布,对能耗及负载的解决能力不会特别好 面向降能耗or均衡负载的目标,使容器放置策略对集群中所有running HMs和VMs均进行能耗or负载的打分,打分模块首先选取所有满足资源约束的selected-VMS,逐个对selected-VM及其hosted HM进行能耗or负载代价计算,打分最终值为,分别为控制VM、HM打分占比的非零权重值; 2. 考虑到docker微服务orchestrator scheduler 必须具有的容错能力,因此需要增加动态检测模块实时检测所有容器及其replicas在上一步部署策略安排好的place能否满足independence条件,即同一service的多个replicas不可位于同一Node(此处应为VM),该模块采用BFD微调策略在hosted HM多个VMs间进行选择性换出与纳新。 考虑到计算出新增容器放置位置的及时性,选用此类装箱问题最简单有效的启发式算法;针对降能耗目标采用FFD-Based Heuristics类型的FFDSum、FFDProd算法, 针对均衡负载采用Dimensions-aware类型的Dot-Product及Norm-based L2算法;除了算法的各个打分策略按照解决思路编写之外,为了均衡效果更优将Dot-Product算法改进为MaxCosine方式去解决。
针对在云中心增加聚合阶段进行降能耗or均衡负载的问题现有研究均集中在仅以VM作为聚合粒度进行聚合算法的研究,实际上在3层架构下充分考虑到容器易部署、迁移代价为零的特性后,同时将docker、VM作为聚合粒度能够大大提升仅以VM作为聚合粒度时的很多无法再进一步聚合的情况,因此总体上提升降能耗的效果 提出新的解决思路,即同时以docker、VM作为聚合粒度。1. 考虑到容器无代价迁移的特性,先在整个容器层进行容器粒度的聚合,再对聚合后实际host容器的VM(一般会节省出一部分running VMs)进行聚合,会进一步节省一批running HMs;2. 增加动态检测模块实时检测所有容器及其replicas在上一步部署策略后的place能否满足independence条件,对不符的容器采用BFD微调策略在hosted HM多个VMs间进行选择性换出与纳新。 采用学术界针对VM聚合常采用的heuristics、GA以及BBO算法,按照解决思路的方式进行问题映射和算法调整;分别1. 以降能耗为主的单目标聚合问题进行上述3种算法调整 2. 以降能耗、均衡负载、减少迁移时间为主的多目标问题,采用多目标进化算法(MBBO、GA)进行问题映射和算法调整。

可能遇到的问题及解决方式(还未完成,后期更新):

架构 考虑角度 采用方法A 存在问题
2层 仅将vm作为容器放置影响因素 binpack/spread/random 没有发掘出提升优化程度可能性
3层 以VM、hosted HM作为放置影响因素 FFDSum、FFDProd、Dot-Product、L2 降能耗、均衡负载会提升,但需要考虑docker service independence,引入独立检测模块进行dependence调整
2层 仅以VM作为聚合粒度 多目标、单目标优化算法 没有发掘出提升优化程度可能
3层 docker&VM为聚合粒度 学术界常用优化算法先进行docker聚合再进行VM聚合 优化程度提高很多,需要加入独立性检测模块进行dependence调整

面向d-v-h部署架构下的容器动态部署模型

注意: 需要完美解释为何在新增阶段考虑新增容器与HM产生的实际之间的关系??

以降能耗为目标

能耗计算模型

能耗预测模型沿用李睿在论文中提出的服务器能耗与其CPU利用率成正相关的立方多项式预测模型:

那么,HM的cpu利用率应该以所有运行于其上的VMs实际资源量计算(即运行于各个VM内的容器尺寸之和),还是按照VMs配置的资源量计算???

云中心运行维护海量服务器,每台服务器的资源耗费不尽相同,具体的取决于其上部署的VM配置及其数量。而VM在各个时刻对资源的需求变化很难预测,取决于其上运行的容器所承载的具体服务及其特征。数据中心通常按照用户申请并分配给VM的可使用资源计费,而非以VM实际使用中消耗的资源量计费。因此,本文以分配给VM的资源量作为VM资源量,直接用于能耗预测模型。

但是!!!对于新增容器不造成新增加active VM和HM的情况下,容器放于任何一个VM中都不会改变能耗的预测值,那么为什么还要考虑HM层的资源分布?

针对上述问题那么,可以说以集群中所有 active VMs的cpu资源量作为预测能耗的数据时即为当前集群拓扑的能耗最大值,那么以节省能耗为优化目标的容器新增算法,在进行VM选择时,除了提升最大化VM资源利用率外,应同时考虑当前HM实际能耗对预测能耗的占比最大化,即该HM上所有容器对HM cpu的实际使用率上所有容器对HM的实际占比(相同最大预测能耗下,所有容器当其hosted HM资源使用占比越大说明资源利用越充分)。
综上,若集群能耗计算是以VM需求量作为预测数据时,可以间接认为active HM数量越少,实际物理能耗才会越少,部署策略才会越好(2017-12-6更新)。

分别代表VM的下标和HM的下标;
即位于第个HM的第个VM。

那么新增时,每次都以满足资源约束的VM所在的HM,其上实际的cpu使用率作为能耗数据,取集群能耗最小的放置位置。

最后分别对比仅考虑VM资源分布的docker能耗等代价,和考虑HM资源分布的能耗代价。

以均衡负载为目标

服务器间负载均衡度子模型

服务器内部负载均衡度子模型

该指数大小仅能放映该HM再增加新VM的可能性,值越大能够再容纳新VM可能性越小,当用于说明集群中服务器间负载均衡度时,比说指明服务器load index的均值。实际上并不直观。

故下面提出的负载模型pass

此处输入图片的描述$$)

PPT宗旨

能上图绝不要是文字说明

2017-12-7完整想法

背景

传统云计算环境以VM作为降能耗、均衡负载的部署、调度单元,VM的‘庞大’还会牵扯到热迁移的代价问题。而如今促进‘微服务’发展的docker技术引入到云中心,其易构建、分发、部署和无代价迁移的特性也为解决云中心能耗问题提供新的思路。
提供容器云服务的公有云环境,几乎都以docker-vm-hm的3层结构提供服务,主要考虑到VM提供的租户间完全隔离和容器间服务隔离。
该架构下的docker集群调度器,基本以主动(docker swarm+machine)或被动(mesos、openstack magnum)方式感知集群VM层资源分布情况及简单的binpack、spread、random调度策略进行容器的调度。这种局部资源感知力和简单调度策略对于整个集群的能耗节省提供的作用甚微;
而以云中心最有效节省能耗的手段著名的VM聚合策略,在微服务时代很多情况下会出现不可聚合情况,若改变思路提供docker、VM俩种聚合粒度,则能显著降低能耗。

研究内容

综上,提出面向云中心3层部署架构下的,以降低能耗、均衡负载为目标,同时考虑docker-vm与vm-hm 3个层次及满足微服务独立性的容器动态部署策略。

研究内容一

提出面向降能耗or均衡负载场景的动态新增部署策略

研究内容二

提出面向降能耗为目标的双粒度聚合部署策略

研究内容三

提出以容器作为集群真正负载的双粒度均衡放置部署策略

负载均衡分为纵向和横向均衡两种。
纵向是指HM or VM内部各个维度资源的均衡使用,避免因为某一维资源过载导致无法再容纳新VM/docker而造成的其他维度资源的浪费,即避免某一维资源成为容纳新服务的瓶颈。
横向是指集群中所有HMs间每一维资源使用率相对均衡,尽量减少空载和过载的极端情况,避免集群负载检测模块在监测到HM使用率超过过载阈值时开启更多HM提供服务,而造成能耗进一步攀升的情况,因此集群资源横向均衡能够间接稳定能耗。

对于d-v-h部署架构,VM作为完全隔离的提供者必不可少,但实际上容器服务才是真正的集群负载,进行集群负载的均衡时,实际应该以容器作为真正负载均衡的考虑对象。保证容器对HM造成的实际横向、纵向负载均衡,以及容器对VM造成的纵向负载均衡。

附加-在Markdown中使用MathJax引擎

在Markdown中添加MathJax引擎也很简单,

  1. <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=default"></script>

然后,再使用Tex写公式。$$公式$$表示行间公式,本来Tex中使用\ (公式\ ) 表示行内公式,但因为Markdown中\是转义字符,所以在Markdown中输入行内公式使用 \ \(公式\ \ ),如下代码:

  1. $$x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}$$
  2. \\(x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}\\)

swarm strategy源码

可参考文章——【原创】swarm源码分析(4)---Scheduler和Api

  1. // PlacementStrategy is the interface for a container placement strategy.
  2. type PlacementStrategy interface {
  3. // Name of the strategy
  4. Name() string
  5. // Initialize performs any initial configuration required by the strategy and returns
  6. // an error if one is encountered.
  7. // If no initial configuration is needed, this may be a no-op and return a nil error.
  8. Initialize() error
  9. // RankAndSort applies the strategy to a list of nodes and ranks them based
  10. // on the best fit given the container configuration. It returns a sorted
  11. // list of nodes (based on their ranks) or an error if there is no
  12. // available node on which to schedule the container.
  13. RankAndSort(config *cluster.ContainerConfig, nodes []*node.Node) ([]*node.Node, error)
  14. }
  15. var (
  16. strategies []PlacementStrategy
  17. // ErrNotSupported is the error returned when a strategy name does not match
  18. // any supported placement strategy.
  19. ErrNotSupported = errors.New("strategy not supported")
  20. // ErrNoResourcesAvailable is the error returned when there are no resources
  21. // available to schedule a container. This can occur if there are no nodes in
  22. // the cluster or if no node contains sufficient resources for the container.
  23. ErrNoResourcesAvailable = errors.New("no resources available to schedule container")
  24. )
  25. func init() {
  26. strategies = []PlacementStrategy{
  27. &SpreadPlacementStrategy{},
  28. &BinpackPlacementStrategy{},
  29. &RandomPlacementStrategy{},
  30. }
  31. }
  1. // RankAndSort sorts nodes based on the binpack strategy applied to the container config.
  2. func (p *BinpackPlacementStrategy) RankAndSort(config *cluster.ContainerConfig, nodes []*node.Node) ([]*node.Node, error) {
  3. // for binpack, a healthy node should increase its weight to increase its chance of being selected
  4. // set healthFactor to 10 to make health degree [0, 100] overpower cpu + memory (each in range [0, 100])
  5. const healthFactor int64 = 10
  6. weightedNodes, err := weighNodes(config, nodes, healthFactor)
  7. if err != nil {
  8. return nil, err
  9. }
  10. sort.Sort(sort.Reverse(weightedNodes))
  11. output := make([]*node.Node, len(weightedNodes))
  12. for i, n := range weightedNodes {
  13. output[i] = n.Node
  14. }
  15. return output, nil
  16. }

weighted_node.go :

  1. func weighNodes(config *cluster.ContainerConfig, nodes []*node.Node, healthinessFactor int64) (weightedNodeList, error) {
  2. weightedNodes := weightedNodeList{}
  3. for _, node := range nodes {
  4. nodeMemory := node.TotalMemory
  5. nodeCpus := node.TotalCpus
  6. // Skip nodes that are smaller than the requested resources.
  7. if nodeMemory < int64(config.HostConfig.Memory) || nodeCpus < config.HostConfig.CPUShares {
  8. continue
  9. }
  10. var (
  11. cpuScore int64 = 100
  12. memoryScore int64 = 100
  13. )
  14. if config.HostConfig.CPUShares > 0 {
  15. cpuScore = (node.UsedCpus + config.HostConfig.CPUShares) * 100 / nodeCpus
  16. }
  17. if config.HostConfig.Memory > 0 {
  18. memoryScore = (node.UsedMemory + config.HostConfig.Memory) * 100 / nodeMemory
  19. }
  20. if cpuScore <= 100 && memoryScore <= 100 {
  21. weightedNodes = append(weightedNodes, &weightedNode{Node: node, Weight: cpuScore + memoryScore + healthinessFactor*node.HealthIndicator})
  22. }
  23. }
  24. if len(weightedNodes) == 0 {
  25. return nil, ErrNoResourcesAvailable
  26. }
  27. return weightedNodes, nil
  28. }

swarm/scheduler/strategy/spread.go

  1. // RankAndSort sorts nodes based on the spread strategy applied to the container config.
  2. func (p *SpreadPlacementStrategy) RankAndSort(config *cluster.ContainerConfig, nodes []*node.Node) ([]*node.Node, error) {
  3. // for spread, a healthy node should decrease its weight to increase its chance of being selected
  4. // set healthFactor to -10 to make health degree [0, 100] overpower cpu + memory (each in range [0, 100])
  5. const healthFactor int64 = -10
  6. weightedNodes, err := weighNodes(config, nodes, healthFactor)
  7. if err != nil {
  8. return nil, err
  9. }
  10. sort.Sort(weightedNodes)
  11. output := make([]*node.Node, len(weightedNodes))
  12. for i, n := range weightedNodes {
  13. output[i] = n.Node
  14. }
  15. return output, nil
  16. }

swarm/scheduler/strategy/binpack_test.go:

  1. func createNode(ID string, memory int64, cpus int64) *node.Node {
  2. oc := 0.05
  3. memory = int64(float64(memory) + float64(memory)*oc)
  4. return &node.Node{
  5. ID: ID,
  6. IP: ID,
  7. Addr: ID,
  8. TotalMemory: memory * 1024 * 1024 * 1024,
  9. TotalCpus: cpus,
  10. HealthIndicator: 100,
  11. }
  12. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注