精品国产一级在线观看,国产成人综合久久精品亚洲,免费一级欧美大片在线观看

開源IaaS ZStack 的伸縮性秘密之異步架構(gòu)

責任編輯:editor005

2015-08-31 14:09:57

摘自:開源中國

ZStack 核心架構(gòu)設(shè)計使得 99% 的任務(wù)異步執(zhí)行,因此確保了單個的管理節(jié)點能夠管理十萬級的物理服務(wù)器,百萬級的虛擬機,數(shù)萬級的并行任務(wù)。通過這三個異步方式,ZStack 已經(jīng)構(gòu)建了一個分層架構(gòu),保證所有組件能夠?qū)崿F(xiàn)異步操作。

ZStack 核心架構(gòu)設(shè)計使得 99% 的任務(wù)異步執(zhí)行,因此確保了單個的管理節(jié)點能夠管理十萬級的物理服務(wù)器,百萬級的虛擬機,數(shù)萬級的并行任務(wù)。

架構(gòu)的創(chuàng)新動力

對于要管理大量的硬件和虛擬機的公有云,伸縮性是IaaS軟件要解決的主要問題之一。一個中等規(guī)模的數(shù)據(jù)中心,可能會有50.000臺物理服務(wù)器,大約 1,500,000的虛擬機,舉例來說,同時分屬于10000用戶。雖然,用戶不太可能象刷新Facebook頁面一樣開/關(guān)虛擬機,但是IaaS 系統(tǒng)還是會在某個時刻被數(shù)千任務(wù)擁塞,這些任務(wù)有來自API的,還有來自內(nèi)部組件的。在某些更糟糕的情況下,一個用戶可能會等一個小時才能創(chuàng)建虛擬機,就是因為系統(tǒng)線程池只有1000,而等待處理的任務(wù)有5000個。

問題

首先,我們明確反對某些文章中的觀點,針對 IaaS 伸縮性問題歸結(jié)于,其聲稱 “支撐基礎(chǔ),特別是數(shù)據(jù)庫和消息代理是 IaaS 伸縮性的問題的罪魁禍首”。 這完全是錯誤的!首先,就數(shù)據(jù)庫的規(guī)模來講,其頂多算是小型和中型;像 Facebook 和 Twitter 這樣的互聯(lián)網(wǎng)巨頭,還在擁 MySQL 作為其主數(shù)據(jù)庫。IaaS 的數(shù)據(jù)難道超過了 Facebook 或 Twitter 嗎?完全不可能,他們是十億級,IaaS 只有百萬級(超級數(shù)據(jù)中心)。其次,相較與 Apache Kafka 或者 ZeroMQ 此類的消息代理服務(wù)器,ZStack 所應(yīng)用的 RabbitMQ 只能算是一個中等伸縮性的代理。但是,其依然可以保持每秒 50.000 的消息處理量。(參考,RabbitMQ 性能測試 , part 2)。難道這在 IaaS 軟件系統(tǒng)中做通信還不夠嗎?完全足夠。

其實,IaaS 伸縮性問題的根源在于:任務(wù)處理慢。確實是,在 IaaS 軟件系統(tǒng)中任務(wù)處理非常慢,慢到要有幾秒甚至是幾分鐘才能完成。因此,當系統(tǒng)中全是這種慢慢處理的任務(wù)時候,當然就帶來了新任務(wù)的巨大的延遲。而這種慢處理的任務(wù)源于任務(wù)路徑過長。舉例說明,創(chuàng)建虛擬機,一般要經(jīng)過以下路徑 身份服務(wù)(service)-->規(guī)劃器(scheduler)-> 圖象服務(wù)(service)->存儲服務(wù)->網(wǎng)絡(luò)服務(wù)->系統(tǒng)管理(Hypervisor); 每個服務(wù)都會花費幾秒甚至幾分鐘來操作外部硬件,這就導(dǎo)致了超長的任務(wù)處理時長。

同步 vs 異步

傳統(tǒng)的 IaaS 軟件系統(tǒng)同步處理任務(wù);其往往是基于線程池機制。在此機制下,線程分配給每一個任務(wù),只有當前任務(wù)結(jié)束后,下一個任務(wù)才能被處理。因為,任務(wù)處理緩慢,在遇到并行任務(wù)的峰值時, 系統(tǒng)由于超過了線程池的極限所以變的很慢,新來的任務(wù)只能緩存排隊。

解決之道,直觀的認為要增加線程池的容量;不過,現(xiàn)在操作系統(tǒng)雖然可以允許程序啟動數(shù)萬的線程,但是調(diào)度效率很低。因此,人們就開始做橫向擴展,把處理任務(wù)分布在類似軟件程序上,這些程序駐留在不同操作系統(tǒng)上;因為每個程序擁有其獨有的線程池,從而最終增加了整個系統(tǒng)的線程池的容量。但是,以上橫向擴展的方案帶來了成本問題,其加大了管理的難度,并且,從軟件設(shè)計的角度講,集群軟件本身也還是不小的挑戰(zhàn)。最后,雖然其他的包括數(shù)據(jù)庫,消息代理和外部系統(tǒng)(例如,成千的物理服務(wù)器)在內(nèi)的基礎(chǔ)設(shè)施有足夠的能力來服務(wù)于更多的并行任務(wù),但是IaaS軟件系統(tǒng)本身變成了云系統(tǒng)的瓶頸。

ZStack 通過異步架構(gòu)來解決這個問題。如果,我們考慮 IaaS 軟件系統(tǒng)和數(shù)據(jù)中心其他設(shè)施的關(guān)系,IaaS 軟件系統(tǒng)其實是一個中間人的角色。其協(xié)調(diào)外部系統(tǒng)但不做時實的任務(wù);例如,IaaS 不作具體工作,而是存儲系統(tǒng)創(chuàng)建物理卷,鏡像系統(tǒng)下載模板,虛擬機由虛擬管理系統(tǒng)創(chuàng)建。那么,IaaS 實際的工作任務(wù)就是決定如何分發(fā)子任務(wù)(sub-tasks)給外部系統(tǒng)。例如,對 KVM,子任務(wù)就包括了準備邏輯卷,網(wǎng)絡(luò)和創(chuàng)建虛擬機,這些子任務(wù)都是 KVM 主機實施的;這個過程可能花費5秒鐘,其中 IaaS 軟件 0.5s, 其余 4.5s 被 KVMz 主機占用。根本上,ZStack 的異步架構(gòu)確保了不用等這 4.5s,而是僅僅用0.5s 來選擇執(zhí)行的 KVM 主機,然后把任務(wù)分發(fā)出去。一旦,KVM 主機完成了指定的任務(wù),它就會通知 IaaS 管理軟件。以異步架構(gòu)的方式,一個 100 線程的線程池就能輕松處理數(shù)千的并行任務(wù)。

ZStack 的異步方式

異步操作在計算機世界很普遍;異步 I/O, AJAX(Asynchronous Javascript And XML 異步的(Javascript 和 XML)是廣為人知的例子。然而,要構(gòu)建異步的全業(yè)務(wù)邏輯,特別象是 IaaS 這樣的集成軟件,仍然由很多挑戰(zhàn) 。

最大的挑戰(zhàn)在于,不是部分,而是全部的組件都要實現(xiàn)異步;例如,如果只是構(gòu)建一個異步存儲服務(wù),但其他相關(guān)服務(wù)都是同步。那么,整個系統(tǒng)還是沒有多少優(yōu)勢。這是因為,要調(diào)用存儲服務(wù),即使它是異步的,調(diào)用方的服務(wù)還是不得不等待其結(jié)束,那么整個工作流依然是同步的。

圖:線程中,業(yè)務(wù)流程服務(wù)要調(diào)用存儲服務(wù),直到存儲服務(wù)返回了,線程才能結(jié)束。 雖然,存儲服務(wù)通過異步方式和外部存儲系統(tǒng)交互。

ZStack's 異步架構(gòu)包含三部分: 異步消息,異步方法,異步 HTTP 調(diào)用。

1. 異步消息

ZStack 使用 RabbitMQ 作為消息總線以便連接各個服務(wù)。當某個服務(wù)調(diào)用另一個服務(wù)時,源服務(wù)發(fā)消息給目的服務(wù)并注冊一個回調(diào)函數(shù),然后馬上返回;一旦目的服務(wù)完成了任務(wù),它就會通過觸發(fā)回調(diào)函數(shù)來回復(fù)任務(wù)結(jié)果。

AttachNicToVmOnHypervisorMsg amsg = new AttachNicToVmOnHypervisorMsg();

amsg.setVmUuid(self.getUuid());

amsg.setHostUuid(self.getHostUuid());

amsg.setNics(msg.getNics());

bus.makeTargetServiceIdByResourceUuid(amsg, HostConstant.SERVICE_ID, self.getHostUuid());

bus.send(amsg, new CloudBusCallBack(msg) {

@Override

public void run(MessageReply reply) {

AttachNicToVmReply r = new AttachNicToVmReply();

if (!reply.isSuccess()) {

r.setError(errf.instantiateErrorCode(VmErrors.ATTACH_NETWORK_ERROR, r.getError()));

}

bus.reply(msg, r);

}

});

單個服務(wù)也可以發(fā)送一串消息給其他服務(wù) ,并異步的等待回復(fù)。

final ImageInventory inv = ImageInventory.valueOf(ivo);

final List dmsgs = CollectionUtils.transformToList(msg.getBackupStorageUuids(), new Function() {

@Override

public DownloadImageMsg call(String arg) {

DownloadImageMsg dmsg = new DownloadImageMsg(inv);

dmsg.setBackupStorageUuid(arg);

bus.makeTargetServiceIdByResourceUuid(dmsg, BackupStorageConstant.SERVICE_ID, arg);

return dmsg;

}

});

bus.send(dmsgs, new CloudBusListCallBack(msg) {

@Override

public void run(List replies) {

/* do something */

}

}

更進一步,也能發(fā)送具有一定并行性的消息串。 比如,一串十個的消息,能夠兩兩發(fā)送,第三,第四個消息只有第一,第二個消息收到后在一起發(fā)出。

final List msgs = new ArrayList(hostsToLoad.size());

for (String uuid : hostsToLoad) {

ConnectHostMsg connectMsg = new ConnectHostMsg(uuid);

connectMsg.setNewAdd(false);

connectMsg.setServiceId(serviceId);

connectMsg.setStartPingTaskOnFailure(true);

msgs.add(connectMsg);

}

bus.send(msgs, HostGlobalConfig.HOST_LOAD_PARALLELISM_DEGREE.value(Integer.class), new CloudBusSteppingCallback() {

@Override

public void run(NeedReplyMessage msg, MessageReply reply) {

/* do something */

}

});

2. 異步方法

ZStack 服務(wù),就像以上段一所示,它們之間通過異步消息通信; 對于服務(wù)內(nèi)部,一系列的互相關(guān)聯(lián)的組件,插件是通過異步方法調(diào)用來交互的。

protected void startVm(final APIStartVmInstanceMsg msg, final SyncTaskChain taskChain) {

startVm(msg, new Completion(taskChain) {

@Override

public void success() {

VmInstanceInventory inv = VmInstanceInventory.valueOf(self);

APIStartVmInstanceEvent evt = new APIStartVmInstanceEvent(msg.getId());

evt.setInventory(inv);

bus.publish(evt);

taskChain.next();

}

@Override

public void fail(ErrorCode errorCode) {

APIStartVmInstanceEvent evt = new APIStartVmInstanceEvent(msg.getId());

evt.setErrorCode(errf.instantiateErrorCode(VmErrors.START_ERROR, errorCode));

bus.publish(evt);

taskChain.next();

}

});

}

同樣, 回調(diào)也能包含返回值:

public void createApplianceVm(ApplianceVmSpec spec, final ReturnValueCompletion completion) {

CreateApplianceVmJob job = new CreateApplianceVmJob();

job.setSpec(spec);

if (!spec.isSyncCreate()) {

job.run(new ReturnValueCompletion(completion) {

@Override

public void success(Object returnValue) {

completion.success((ApplianceVmInventory) returnValue);

}

@Override

public void fail(ErrorCode errorCode) {

completion.fail(errorCode);

}

});

} else {

jobf.execute(spec.getName(), OWNER, job, completion, ApplianceVmInventory.class);

}

}

3. 異步HTTP調(diào)用

ZStack 使用了很多代理來管理外部系統(tǒng)。 例如: 管理 KVM 主機的代理,管理 Console Proxy 的代理,管理虛擬路由的代理等等。這些代理都是構(gòu)建在 Python CherryPy 上的輕量級的 Web 服務(wù)器。因為,沒有類似 HTML5 中的 Web Sockets 技術(shù)就不能實現(xiàn)雙向通信,ZStack 就為每個請求,放置了一個回調(diào) URL 在 HTTP 的包頭 。這樣,任務(wù)結(jié)束后,代理就能夠發(fā)送應(yīng)答給調(diào)用者的 URL。

RefreshFirewallCmd cmd = new RefreshFirewallCmd();

List tos = new RuleCombiner().merge();

cmd.setRules(tos);

resf.asyncJsonPost(buildUrl(ApplianceVmConstant.REFRESH_FIREWALL_PATH), cmd, new JsonAsyncRESTCallback(msg, completion) {

@Override

public void fail(ErrorCode err) {

/* handle failures */

}

@Override

public void success(RefreshFirewallRsp ret) {

/* do something */

}

@Override

public Class getReturnClass() {

return RefreshFirewallRsp.class;

}

});

通過這三個異步方式,ZStack 已經(jīng)構(gòu)建了一個分層架構(gòu),保證所有組件能夠?qū)崿F(xiàn)異步操作。

總結(jié)

此文,我們闡述了 ZStack 的異步架構(gòu),此架構(gòu)解決了由于并行任務(wù)慢而導(dǎo)致的 IaaS 伸縮性問題。在測試中,使用模擬器,在單 ZStack 管理節(jié)點中,1000 線程就能輕易處理創(chuàng)建 1,000,000 虛擬機的10.000 個并行任務(wù)。除了單節(jié)點具有足夠伸縮性處理大部分云系統(tǒng)負載的優(yōu)點外,想要支持高可用行(High Availability)或者朝大規(guī)模負載(比如,100,000 并行任務(wù)),就必須安裝多個管理節(jié)點。

鏈接已復(fù)制,快去分享吧

企業(yè)網(wǎng)版權(quán)所有?2010-2024 京ICP備09108050號-6京公網(wǎng)安備 11010502049343號

  • <menuitem id="jw4sk"></menuitem>

    1. <form id="jw4sk"><tbody id="jw4sk"><dfn id="jw4sk"></dfn></tbody></form>
      主站蜘蛛池模板: 长子县| 福海县| 株洲市| 锡林浩特市| 咸阳市| 密山市| 平谷区| 扶沟县| 错那县| 大荔县| 西安市| 潮安县| 兴文县| 盐津县| 许昌县| 汤原县| 大宁县| 广饶县| 堆龙德庆县| 托克逊县| 德江县| 天气| 衡东县| 攀枝花市| 油尖旺区| 永定县| 炎陵县| 师宗县| 宁晋县| 米泉市| 阿鲁科尔沁旗| 邹城市| 无极县| 张家港市| 金寨县| 四子王旗| 自治县| 吉隆县| 治多县| 锡林浩特市| 锦屏县|