【ZStack】8.级联框架

云中的资源相互都有关系。操作一个资源通常会引发连锁反应;例如,当删除一个集群的时候,是非常合理地去删除属于该集群的所有主机并停止所有在这些主机上运行的虚拟机。传统的IaaS软件要么硬编码连锁反应,要么简单地禁止这些操作,例如,禁止用户删除有虚拟机运行的集群。ZStack提供一个级联框架,用以散布本来只对一个资源的操作到所有相关的资源。资源可以通过实现一个简单的扩展点以加入级联框架,使得资源的业务逻辑与框架解耦。

动机

云中的资源多多少少都彼此依赖;例如,一个主机是一个集群的子资源,一个主存储是一个集群的兄弟资源,L3网络是一个区域的后裔资源。资源之间的关系可以被描述为一个有向图:

上图,我们展示了ZStack的主要资源;不同的IaaS软件可能使用不同的术语,上图主要是想让你有一个粗略的概念。由上图所暗示的,当对资源进行操作时,不仅仅是目标资源,相关资源也将受到影响;例如,当删除一个区域时,比较理想的是属于区域的集群、主机、主存储、L2网络等资源也同时被删除。为了处理这个问题,IaaS软件必须满足级联(cascading)操作的需求。

问题

大多数IaaS软件很少考虑级联操作。它们要么硬编码业务逻辑,例如,你需要显式删除一个将要被删除帐户的所有资源;要么直接不允许这种操作,例如,当你试图删除一个IP地址范围时,抛出一个错误信息“仍有VM使用在这个IP范围中的IP”。这两种方法都会带来很多麻烦。对硬编码而言,它使软件不能灵活的添加新的资源,因为你必须修改现有的代码来添加级联操作,例如,修改删除帐户的代码使得账户删除时,新资源也被删除。对于完全没有责任感的错误信息,用户要么去做无聊的工作,例如,在删除一个IP范围之前,手动删除100个虚拟机;要么摧毁现有的一切,然后从零开始,例如,重新部署整个云。

避免误操作不是借口: 有些人可能会声称不允许级联删除是慎重考虑的结果,因为用户可能会误操作,误操作可能带来灾难性的后果;例如,错误地删除区域会导致损失掉所有虚拟机。然而,这种说法只是一个错误的借口,并且是一种为用户做决定的自作聪明。你能想象吗,当你为了删除一个区域必须手动删除10,000个虚拟机,因为软件认为你可能会做错事,所以迫使你枯燥的重复10,000次任务确认?一个好的软件应该为用户提供选择,并让他们做出决定。在我们的例子中,IaaS软件应该在进行到最后删除之前警告用户,还有10,000台虚拟机在运行;但一旦用户承认他们需要这么做,软件就应该这么做。

级联框架

ZStack通过一个级联框架解决这一问题;顾名思义,级联框架允许一个操作能从一个资源级联到其他资源。为了解耦整个架构,这个级联框架被作为一个单独的组件创造出来,资源可以按意愿加入框架。要加入框架,资源所需要做的全部事情就是实现一个扩展点CascadeExtensionPoint(在我们的例子中AbstractAsyncCascadeExtension是一个实现CascadeExtensionPoint的类):

class VmCascadeExtension extends AbstractAsyncCascadeExtension {
    @Override
    public void asyncCascade(CascadeAction action, Completion completion) {
        if (/* this is from deleting Primary Storage*/) {
            /* delete VMs that have root volumes on the primary storage*/
        } else if (/*this is from deleting L3 Network*/) {
            /* stop VMs that have nics on the L3 network, and remove those nics */
        } else if (/* this is from deleting IP range*/) {
            /* stop VMs that have nics whose IP is in the IP range */
        } else if (/* this is from deleting host*/) {
            /* stop VMs that run on the host */
        }

        completion.success();
    }

    @Override
    public List<String> getEdgeNames() {
        return Arrays.asList(
                PrimaryStorageVO.class.getSimpleName(),
                L3NetworkVO.class.getSimpleName(),
                IpRangeVO.class.getSimpleName(),
                HostVO.class.getSimpleName()
        );
    }

    @Override
    public String getCascadeResourceName() {
        return VmInstanceVO.class.getSimpleName();
    }

    @Override
    public CascadeAction createActionForChildResource(CascadeAction action) {
        return convertContextToVmRelatedContext(action);
    }
}

getCascadeResourceName()方法返回该资源的名称(VmInstance);getEdgeNames()方法返回一个和资源直接关联的资源名列表,在我们的例子中返回主存储、L3网络、IpRange和主机;所以如果删除操作在这些edge resources或其上游资源(如区域)上发生时,该操作将被级联至在getEdgeNames()方法中声明了这些资源的扩展。级联扩展可以在asyncCascade() 中采取行动,并获取必须的信息比如操作码(如删除),根发起者(如区域,下文将很快给出解释),作为操作来源的父发起者(如主机,将很快给出解释)和操作上下文(例如,哪台主机正在被删除)。由于资源的关系是一个可能有环路的有向图,级联框架将把图压扁成一棵树,并把环路变为分支。例如,删除区域的操作将最终创建以下树(一部分):

注:如你所见,删除区域操作将多次级联到虚拟机的级联扩展;这是刻意的,因为级联扩展通常依赖于父发起者去决定该采取什么行动;在这个例子中,虚拟机的父发起者为主存储、主机、L3网络和IP范围;然而,对于不同的父发起者,扩展可能会采取不同的行动;例如,如果父发起者为主存储并且操作码为delete,该扩展将摧毁所有根云盘在该主存储的虚拟机;但如果父发起者是主机,扩展将会只停止在那台主机上的虚拟机,因为这些虚拟机稍后就可以在其他主机上启动。考虑到ZStack没有产生冲突的级联操作,例如,不会有一个操作导致虚拟机在路径A启动而在路径B停止,所以级联操作从不同路径进行多次延伸是没有问题的。

当级联一个操作时,该框架从该操作被应用的root issuer开始;在上述删除区域的示例中,zone是根发起者;那么框架将从根发起者遍历树,并调用扩展的createActionForChildResource() 方法为每一条路径上的每一个扩展创建上下文;一旦所有上下文创建成功,该框架将再次遍历树,不过是从叶子节点到根,并调用每个扩展的asyncCascade()方法 ;一个扩展可以依靠父发起者去决定应该做哪些操作,父发起者在getEdgeNames() 方法中以资源名的方式声明;例如,如果父发行者是主机,则停止虚拟机;如果父发行者是主存储,则删除虚拟机。

这两个阶段的遍历保证,一个操作(例如删除)将只会被应用到根发起者,在所有下游资源都做完一些合适的操作后。例如,一个区域只在所有子孙资源都被删除后才能被删除。
由于并不是所有的操作都需要级联,一个资源可以在它需要的时候直接调用CascadeFacade.asyncCascade()。

总结

在这篇文章中,我们演示了ZStack的级联框架,这是一个强大的工具,用于扩散操作而不需要硬编码。ZStack用很多方式使用了它,除了我们在文中提到的以外,一些操作,如卸载主存储(这将停止将被卸载的集群中的所有虚拟机),卸载L2网络(这将停止将被卸载的集群中的所有虚拟机)都是以这种方式实现的。有了它的帮助,管理员可以快速尝试不同的云部署而无需担心不方便;你可以只删除你的部署的一部分并重新创建一个新的,而不需要仅因为你在一个设计错误的L2网络上创建了许多虚拟机,就重新部署整个云(举个例子)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,650评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,050评论 25 707
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,235评论 11 349
  • 2.4应用程序启动过程小结 从官方对该函数的描述可以知道,该函数主要做了以下几件事: UIApplicationM...
    刘2傻阅读 219评论 0 0
  • 1 下载 2 启动容器 2.1 制定挂载目录 3测试 4 接下来修改一下该镜像的tag。 5接下来把打了tag的镜...
    曹振华阅读 6,817评论 1 2