日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > 互聯(lián)網(wǎng) > Docker:分布式系統(tǒng)的軟件工程革命(上)

Docker:分布式系統(tǒng)的軟件工程革命(上)

來(lái)源:程序員人生   發(fā)布時(shí)間:2014-09-06 17:37:07 閱讀次數(shù):2424次

【編者按】為了使用Docker,需要了解不少工具及其設(shè)計(jì)思路;而這些工具的文檔分布在不同的網(wǎng)站。為了方便大家學(xué)習(xí),本文以開發(fā)一個(gè)極簡(jiǎn)的搜索引擎為例,展示Docker帶來(lái)的革新。本文以技術(shù)教程為主線,穿插了一些關(guān)于Hadoop和Mesos等“模仿”項(xiàng)目的介紹,簡(jiǎn)要追溯它們勇敢而艱難的“邯鄲學(xué)步”的歷程。本文來(lái)自王益的個(gè)人博客。


免費(fèi)訂閱“CSDN大數(shù)據(jù)”微信公眾號(hào),實(shí)時(shí)了解最新的大數(shù)據(jù)進(jìn)展!

CSDN大數(shù)據(jù),專注大數(shù)據(jù)資訊、技術(shù)和經(jīng)驗(yàn)的分享和討論,提供Hadoop、Spark、Imapala、Storm、HBase、MongoDB、Solr、機(jī)器學(xué)習(xí)、智能算法等相關(guān)大數(shù)據(jù)觀點(diǎn),大數(shù)據(jù)技術(shù),大數(shù)據(jù)平臺(tái),大數(shù)據(jù)實(shí)踐,大數(shù)據(jù)產(chǎn)業(yè)資訊等服務(wù)。


以下為原文:

Docker最近很火。Docker實(shí)現(xiàn)了“集裝箱”――一種介于“軟件包”和“虛擬機(jī)”之間的概念――并被寄予厚望,以期革新Internet服務(wù)以及其他大數(shù)據(jù)處理系統(tǒng)的開發(fā)、測(cè)試、和部署流程。

為了使用Docker,需要了解不少工具及其設(shè)計(jì)思路;而這些工具的文檔分布在不同的網(wǎng)站。為了方便大家學(xué)習(xí),本文以開發(fā)一個(gè)極簡(jiǎn)的搜索引擎為例,展示Docker帶來(lái)的革新。

說(shuō)是革新,其實(shí)是Google已經(jīng)用了很多年的方式,只是最近才因?yàn)镈ocker開源項(xiàng)目而廣為人知。最近這將近十年的時(shí)間里,各互聯(lián)網(wǎng)公司和高校都在奮力模仿Google的計(jì)算技術(shù)。了解這一模仿的過(guò)程,可以幫助我們深入理解分布式系統(tǒng)(包括現(xiàn)在常說(shuō)的“大數(shù)據(jù)系統(tǒng)”)中若干重要問(wèn)題。為此,本文以技術(shù)教程為主線,穿插了一些關(guān)于Hadoop和Mesos等“模仿”項(xiàng)目的介紹,簡(jiǎn)要追溯它們勇敢而艱難的“邯鄲學(xué)步”的歷程。最后,本文會(huì)介紹Google最近公布的“正確答案”――Hubernetes――Google核心技術(shù)Borg的開源版本。

Docker

Docker是一個(gè)軟件系統(tǒng),實(shí)現(xiàn)了一種稱為“集裝箱”的概念。集裝箱類似Google機(jī)群管理系統(tǒng)Borg中的包(package)。

通常我們說(shuō)的“包”是軟件包――比如Ubuntu/Debian Linux里常見的.deb文件――安裝的時(shí)候,安裝程序會(huì)把被依賴的包也裝上。可是執(zhí)行的時(shí)候呢?得根據(jù)具體情況配置,然后依次啟動(dòng)互相依賴的多個(gè)程序。比如,啟動(dòng)一個(gè)Web服務(wù)之前,要啟動(dòng)Apache和MySQL;而且他們仨都得有合理的配置,確保它們能一起工作,來(lái)實(shí)現(xiàn)這個(gè)Web服務(wù)。

但是Docker集裝箱以及Borg中的包更像虛擬機(jī)。虛擬機(jī)里包括程序和配置,所以可以被執(zhí)行――也就是執(zhí)行其中的程序。因?yàn)槌绦蚴桥渲煤玫模蕴摂M機(jī)可以被扔到各種環(huán)境上去執(zhí)行――包括開發(fā)機(jī)、做演示用的筆記本電腦、用VirtualBox虛擬的機(jī)群、測(cè)試機(jī)群、預(yù)發(fā)布環(huán)境和產(chǎn)品環(huán)境。近幾年隨著“云計(jì)算”概念的普及,虛擬機(jī)被廣泛使用,作為分布式計(jì)算的基礎(chǔ)調(diào)度單元。

Docker作為一個(gè)軟件系統(tǒng),可以用來(lái)創(chuàng)建“集裝箱鏡像”(container image)和執(zhí)行這些鏡像。就像VirtualBox是一個(gè)軟件系統(tǒng),可以用來(lái)創(chuàng)建和執(zhí)行虛擬機(jī)。但是集裝箱比虛擬機(jī)“輕”――一個(gè)虛擬機(jī)包括一組虛擬硬件、操作系統(tǒng),用來(lái)執(zhí)行用戶程序;而集裝箱里沒有虛擬的硬件,也沒有操作系統(tǒng),它用主機(jī)(host)的硬件和操作系統(tǒng)來(lái)執(zhí)行程序。

那么在集裝箱里跑程序和直接在主機(jī)上跑有什么區(qū)別呢?一個(gè)區(qū)別是,集裝箱有一套網(wǎng)絡(luò)端口空間(port space)。一個(gè)集裝箱里的進(jìn)程可以各自開端口,也可以連接對(duì)方的端口進(jìn)行通信。但是這些端口是集裝箱之外的進(jìn)程看不到的。我們也可以讓集裝箱把某些內(nèi)部端口號(hào)展示給外部,比如把集裝箱內(nèi)的端口5000映射到外部的8080。這樣,當(dāng)我們用主機(jī)上的程序(比如瀏覽器)訪問(wèn)本機(jī)(主機(jī))的8080端口時(shí),實(shí)際上訪問(wèn)的是集裝箱里的5000端口。這項(xiàng)對(duì)外公開集裝箱內(nèi)部端口的技術(shù),稱為端口轉(zhuǎn)發(fā)(port forwarding),和虛擬機(jī)的端口轉(zhuǎn)發(fā)概念一樣。另一個(gè)區(qū)別在于,集裝箱里有虛擬的文件系統(tǒng)。這樣我們可以把要執(zhí)行的程序拷貝進(jìn)集裝箱。也可以把主機(jī)上的某些目錄映射成集裝箱虛擬文件系統(tǒng)的某些目錄。

集裝箱這個(gè)想法已經(jīng)在深刻地改變傳統(tǒng)分布式系統(tǒng)的開發(fā)、測(cè)試和部署的流程了。傳統(tǒng)的做法是,開發(fā)者寫一個(gè)Makefile(或者其他描述,比如CMakeList、POM等)來(lái)說(shuō)明如何把源碼編譯成二進(jìn)制文件。隨后,開發(fā)人員會(huì)在開發(fā)機(jī)上配置并且執(zhí)行二進(jìn)制文件,來(lái)作測(cè)試。測(cè)試人員會(huì)在測(cè)試機(jī)群上配置和執(zhí)行,來(lái)作驗(yàn)證。而運(yùn)維人員會(huì)在數(shù)據(jù)中心里的預(yù)發(fā)布環(huán)境和產(chǎn)品環(huán)境上配置和執(zhí)行,這就是部署。因?yàn)殚_發(fā)機(jī)、測(cè)試機(jī)群、和產(chǎn)品環(huán)境里機(jī)器的數(shù)量和質(zhì)量都不同,所以配置往往很不同。加上每個(gè)新版本的軟件系統(tǒng),配置方式難免有所差異,所以經(jīng)常造成意外錯(cuò)誤。以至于絕大部分團(tuán)隊(duì)都選擇趁夜深人靜、用戶不活躍的時(shí)候,上線新版本,苦不堪言。

而利用集裝箱概念的開發(fā)流程里,開發(fā)者除了寫Makefile,還要寫一個(gè)Dockerfile,來(lái)描述如何把二進(jìn)制文件安裝進(jìn)一個(gè)集裝箱鏡像(container image),并且做好配置。而一個(gè)鏡像就像一臺(tái)配置好的虛擬機(jī),可以在機(jī)群上啟動(dòng)多個(gè)實(shí)例(instance),而每個(gè)實(shí)例通常稱為一個(gè)集裝箱(container)。在自測(cè)的時(shí)候,開發(fā)者在開發(fā)機(jī)上執(zhí)行一個(gè)或者多個(gè)集裝箱;在驗(yàn)證時(shí),測(cè)試人員在測(cè)試機(jī)群上執(zhí)行集裝箱;在部署時(shí),運(yùn)維人員在產(chǎn)品環(huán)境執(zhí)行集裝箱。因?yàn)閳?zhí)行的都是同樣地集裝箱,所以不容易出錯(cuò)。

這種流程更合理的劃分了開發(fā)者和其他角色的工作邊界,也大大簡(jiǎn)化了測(cè)試和部署工作。

boot2docker

上節(jié)提到,Docker虛擬了網(wǎng)絡(luò)地址空間和文件系統(tǒng)。實(shí)際上,它還虛擬了進(jìn)程ID空間(pid space)等系統(tǒng)數(shù)據(jù)結(jié)構(gòu)。這些功能是一個(gè)叫dockerd的daemon程序借助Linux內(nèi)核中的control groups(又叫cgroups)功能實(shí)現(xiàn)的。

dockerd負(fù)責(zé)執(zhí)行集裝箱;就像VirtualBox負(fù)責(zé)執(zhí)行虛擬機(jī)一樣。而cgroup是Google的兩個(gè)工程師Paul Menage和Rohit Seth貢獻(xiàn)給Linux社區(qū)的。從他們的工作記錄看,主要工作集中在2008和2009年。據(jù)說(shuō),Google開發(fā)它就是為了方便在自己的機(jī)群上部署各種Internet應(yīng)用和離線處理系統(tǒng)。具體一點(diǎn)兒的故事,請(qǐng)看這篇Information Week上的帖子。。

因?yàn)閏groups功能只有Linux內(nèi)核有,所以Docker目前只能運(yùn)行在Linux上。可是,現(xiàn)在很多開發(fā)者都在用Mac。為了能讓這些開發(fā)者方便的測(cè)試自己創(chuàng)作的集裝箱鏡像,Docker的開發(fā)者寫了boot2docker――利用VirtualBox虛擬一個(gè)Linux主機(jī),并且在上面安裝dockerd。而命令行控制程序docker執(zhí)行在Mac主機(jī)上,被配置成和虛擬Linux主機(jī)上的dockerd協(xié)作。

boot2docker的安裝方式很簡(jiǎn)單:照著這個(gè)流程,下載并執(zhí)行一個(gè)安裝包即可。因?yàn)閎oot2docker利用了VirtualBox,所以安裝它之前需要先裝VirtualBox。Homebrew也提供了安裝boot2docker的選項(xiàng),但是可能因?yàn)閎ug導(dǎo)致dockerd和docker版本不同,沒法協(xié)同工作。

在利用boot2docker在Mac上開始工作之前,還有幾個(gè)注意事項(xiàng)。當(dāng)我們?cè)贚inux主機(jī)上啟動(dòng)一個(gè)集裝箱的時(shí)候,我們可以讓Docker把主機(jī)的某些目錄映射成集裝箱內(nèi)的目錄。這樣集裝箱里的程序和主機(jī)上的程序共享數(shù)據(jù),是一種方便的調(diào)試方式。但是在用boot2docker的時(shí)候,“主機(jī)”不是Mac,而是虛擬Linux主機(jī)。此時(shí)如果想把Mac上的目錄映射到集裝箱,先得將其通過(guò)VirtualBox映射到Linux主機(jī)。

另一個(gè)注意事項(xiàng)和端口轉(zhuǎn)發(fā)有關(guān)。當(dāng)我們把集裝箱內(nèi)的某個(gè)端口映射為主機(jī)的某個(gè)端口時(shí),只是映射到了虛擬Linux主機(jī);如果想讓Mac上的程序能訪問(wèn),還得把虛擬機(jī)端口通過(guò)VirtualBox映射成Mac上的端口。這些注意事項(xiàng),在下文中會(huì)有詳細(xì)解釋。

CoreOS

實(shí)際開發(fā)中的測(cè)試機(jī)群和產(chǎn)品環(huán)境通常都是用的Linux服務(wù)器。要在上面執(zhí)行集裝箱,也需要安裝Docker。因?yàn)镈ocker的開發(fā)者提供各種Linux軟件包,所以通常輸入一個(gè)命令,即可安裝Docker。比如在Ubuntu/Debian Linux里,這個(gè)命令是:

sudo apt-get install docker.io

但是目前最常用的用來(lái)執(zhí)行Docker集裝箱的Linux發(fā)行版本既不是Ubuntu、Debian也不是RedHat、Fedora,而是CoreOS。這個(gè)發(fā)行版本根本沒有軟件包管理程序,所以也不能通過(guò)輸入某個(gè)命令來(lái)安裝軟件。但是CoreOS預(yù)裝了Docker,所以可以制作集裝箱鏡像,或者下載別人發(fā)布的集裝箱鏡像來(lái)執(zhí)行。目前,Amazon AWS和Google Compute Engine這兩大云計(jì)算平臺(tái)都提供預(yù)裝了CoreOS的虛擬機(jī)。

實(shí)際上,Google數(shù)據(jù)中心里運(yùn)行的Linux系統(tǒng)和CoreOS有很多相似之處。我記得2010年我剛離開Google加入騰訊的時(shí)候,一位騰訊的同事好奇地問(wèn):“Google的機(jī)群里用的Linux用什么軟件包管理程序?是apt-get嗎?還是yum?”我回答:“其實(shí)服務(wù)器上運(yùn)行的Linux是不需要包管理的,只有桌面Linux系統(tǒng)才需要”。這位同事很難相信。其實(shí),要不是因?yàn)椤耙娏艘换刎i跑”,我也想不到會(huì)是這樣。

CoreOS和其他Linux發(fā)行版本相比,執(zhí)行效率高、內(nèi)存耗費(fèi)省;此外,利用雙磁盤分區(qū)技術(shù),即便是更新Linux內(nèi)核也不需要重啟。CoreOS還有很多獨(dú)特之處,使得它在問(wèn)世后很短的時(shí)間里就被Amazon和Google采用。如果想進(jìn)一步了解這些特性,請(qǐng)看這個(gè)對(duì)Docker作者的訪談。

Go語(yǔ)言

接下來(lái),我們看看如何在Mac上用Go語(yǔ)言寫一個(gè)極簡(jiǎn)化的搜索引擎,并且封裝成集裝箱鏡像。

我們選擇Go語(yǔ)言為例,而不是更常見的Java、Python、Perl、Ruby、Scala等,有很現(xiàn)實(shí)的原因――后面這些語(yǔ)言寫的程序,在執(zhí)行時(shí)都需要某些運(yùn)行環(huán)境的支持。比如,Java程序依賴Java虛擬機(jī),Python程序需要Python解釋器,這些加上預(yù)裝的程序庫(kù)需要占用幾百M(fèi)B的集裝箱空間。而用Go寫的程序默認(rèn)是全靜態(tài)編譯的,執(zhí)行時(shí)不需要任何環(huán)境支持,不需要預(yù)裝庫(kù),甚至連Linux系統(tǒng)動(dòng)態(tài)庫(kù)都不依賴。鑒于一家公司的系統(tǒng)往往由成千上萬(wàn)的集裝箱構(gòu)成;每個(gè)集裝箱少幾百M(fèi)B,能為公司省出很大一筆開銷。那些每月要向Amazon或者Goolgle付賬的公司,對(duì)此必然印象深刻。這是Go語(yǔ)言在很多創(chuàng)業(yè)公司拓展迅猛的一個(gè)原因。

如果我們用C或者C++開發(fā),也可以生成全靜態(tài)鏈接的二進(jìn)制程序文件。但是在Web時(shí)代,C/C++的開發(fā)效率不如Go。Google里倒是普遍使用C++,但是Google里有一套精心設(shè)計(jì)、積攢多年的C++庫(kù),這是外界沒有的。外界普遍得使用第三方庫(kù),并往往因此撓頭。比如,不同的第三方庫(kù)(Thrift和boost)各有各的線程池機(jī)制,很難統(tǒng)一管理多線程。C++11倒是有了標(biāo)準(zhǔn)線程管理,但是把很多庫(kù)統(tǒng)一到C++11是一項(xiàng)開銷極大的工作。Go語(yǔ)言是專門為分布式系統(tǒng)開發(fā)設(shè)計(jì)的,根本就沒有線程的概念,在語(yǔ)法上用goroutine代替了,線程池實(shí)現(xiàn)在Go runtime里,被編譯進(jìn)每個(gè)二進(jìn)制程序。

交叉編譯

因?yàn)榧b箱用主機(jī)的操作系統(tǒng)和硬件來(lái)執(zhí)行程序,而Docker只支持Linux,所以Go程序必須被編譯成Linux二進(jìn)制文件,才能通過(guò)Docker運(yùn)行。而我們?cè)贛ac上開發(fā),需要利用交叉編譯技術(shù)來(lái)生成Linux二進(jìn)制文件。

為了得到一個(gè)支持交叉編譯的Go語(yǔ)言編譯器,我們需要從源碼安裝Go,并且需要做一些額外的安裝工作。具體過(guò)程如下:

1. 安裝Xcode,從而獲得C編譯器。

2. 下載Go編譯器的源碼包。比如Go 1.3在這里。

3. 解壓和編譯

 tar xzvf go1.3.src.tar.gz
 cd go/src
 ./all.bash

4. 編譯各種平臺(tái)下的Go標(biāo)準(zhǔn)庫(kù)

 git clone git://github.com/davecheney/golang-crosscompile.git
 source golang-crosscompile/crosscompile.bash
 go-crosscompile-build-all

這里,我們用到了Dave Cheney寫的一個(gè)Bash腳本程序。這個(gè)程序支持生成以下平臺(tái)上的Go語(yǔ)言標(biāo)準(zhǔn)庫(kù):

  1. darwin/386
  2. darwin/amd64
  3. freebsd/386
  4. freebsd/amd64
  5. freebsd/arm
  6. linux/386
  7. linux/amd64
  8. linux/arm
  9. windows/386
  10. windows/amd64
  11. nacl/amd64
  12. nacl/386

并行計(jì)算最常用的目標(biāo)平臺(tái)是linux/amd64――64bit的Linux系統(tǒng),也是CoreOS的平臺(tái)格式。下文中我們會(huì)演示如何在Mac下用這個(gè)編譯器生成Linux平臺(tái)的二進(jìn)制代碼文件。

極簡(jiǎn)版搜索引擎

在這篇帖子里,作者Adriaan de Jonge用一個(gè)最簡(jiǎn)單的http server作為例子,說(shuō)明如何在Mac下用Docker運(yùn)行一個(gè)程序。

這篇帖子對(duì)我很有幫助。只是這個(gè)例子程序太過(guò)簡(jiǎn)單了――通常一個(gè)互聯(lián)網(wǎng)產(chǎn)品包含不只一個(gè)程序――現(xiàn)代互聯(lián)網(wǎng)產(chǎn)品幾乎都采用micro service架構(gòu),一個(gè)http server和多個(gè)RPC server協(xié)同工作。之外,還會(huì)有一些daemon程序,不時(shí)向RPC server提供不斷更新的數(shù)據(jù)。比如在搜索引擎里,一個(gè)indexer程序會(huì)不斷將cralwer程序爬下來(lái)的網(wǎng)頁(yè)內(nèi)容加以整理,并且發(fā)送給搜索引擎服務(wù)。

本節(jié)里我們介紹的極簡(jiǎn)版的搜索引擎就包括兩個(gè)程序――search engine server和向它提供索引內(nèi)容的indexer daemon。search engine server首先是一個(gè)http server,可以通過(guò)瀏覽器訪問(wèn)――對(duì)每個(gè)輸入的query,返回相應(yīng)的結(jié)果。同時(shí),它還是一個(gè)RPC server,接受從indexer daemon發(fā)來(lái)的更新后的索引內(nèi)容。這兩個(gè)程序的源碼在這里。

為了下載和構(gòu)建這個(gè)例子程序,請(qǐng)輸入如下命令:

mkdir -p /tmp/learn-docker
cd /tmp/learn-docker
export GOPATH=`pwd`
go get github.com/wangkuiyi/helloworld/indexer
go get github.com/wangkuiyi/helloworld/searchengine

此時(shí),在 /tmp/learn-docker/bin 目錄里應(yīng)該有兩個(gè)二進(jìn)制程序文件 indexer和searchengine。這兩個(gè)文件都是Darwin/AMD64格式的。我們可以在Mac主機(jī)上運(yùn)行它倆:

./bin/searchengine -addr=":10000" &
./bin/indexer -searchengine="localhost:10000"

這樣首先啟動(dòng)了searchengine,并且讓它的http和rpc服務(wù)都監(jiān)聽本機(jī)(Mac主機(jī))的10000端口;隨后啟動(dòng)了indexer,它每秒鐘通過(guò)RPC調(diào)用告訴searchengine更新索引內(nèi)容。

啟動(dòng)成功之后,我們可以在瀏覽器里訪問(wèn)如下網(wǎng)址:http://localhost:10000/?q=news,從而看到searchengine返回的搜索結(jié)果(如下圖):


當(dāng)然,我們也可以用命令行程序,比如wget和curl,來(lái)訪問(wèn)searchengine服務(wù)。這樣我們可以很方便的寫一個(gè)集成測(cè)試(regression test)程序。比如這個(gè)。

創(chuàng)建集裝箱

接下來(lái),我們看看如何把這兩個(gè)程序打包進(jìn)Docker集裝箱鏡像,然后在Mac主機(jī)(實(shí)際上是boot2docker創(chuàng)建的Linux虛擬機(jī))上運(yùn)行集裝箱。接下來(lái)我們會(huì)看到:這些集裝箱不用修改,也就能在Amazon AWS和Google Compute Engine上運(yùn)行,從而完成發(fā)布。

首先,我們需要從源碼生成Linux/AMD64二進(jìn)制程序文件。用上文介紹的方法,得到一個(gè)支持交叉編譯的Go編譯器之后,編譯示范程序很簡(jiǎn)單:

GOOS=linux GOARCH=amd64 go install
github.com/wangkuiyi/helloworld/indexer
github.com/wangkuiyi/helloworld/searchengine

可以看到,我們只是通過(guò)環(huán)境變量設(shè)置了一下目標(biāo)操作系統(tǒng)和架構(gòu)。

隨后,我們要?jiǎng)?chuàng)建一個(gè)Docker集裝箱鏡像,把編譯好的兩個(gè)程序放進(jìn)去。因?yàn)槿缟衔慕榻B的,Go程序執(zhí)行時(shí)不需要特殊的運(yùn)行環(huán)境,所以這個(gè)集裝箱鏡像里,除了一些metadata和我們的程序之外,什么都不需要。以至于我們可以從Docker Hub網(wǎng)站上下載一個(gè)空的鏡像,在里面安裝我們的程序即可。為此,我們需要寫一個(gè)Dockerfile:

FROM scratch
ADD bin/linux_amd64/searchengine /searchengine
ADD bin/linux_amd64/indexer /indexer

這里的第一行是讓Docker自動(dòng)從Docker Hub上下載名為scratch的鏡像;第二行說(shuō)把本地文件bin/linux_amd64/searchengine裝進(jìn)這個(gè)鏡像的根目錄,成為/searchengine;第三行拷貝indexer。

有了Dockerfile我們就能用docker命令創(chuàng)建一個(gè)鏡像了。下面命令創(chuàng)建一個(gè)鏡像,并命名為wangkuiyi/helloworld:

cp $GOPATH/src/github.com/wangkuiyi/helloworld/Dockerfile $GOPATH/
docker build -t wangkuiyi/helloworld $GOPATH

此時(shí),我們可以用docker images命令看到我們創(chuàng)建的鏡像:

yiwang@yiwang-mn1-> docker images

REPOSITORY             TAG                 IMAGE ID            CREATED             VIRTUAL SIZE

wangkuiyi/helloworld   latest              255460c3d095        3 hours ago         13.86 MB

分布式系統(tǒng)的部署

最簡(jiǎn)單的使用Docker的部署方案是:?jiǎn)?dòng)一個(gè)集裝箱,在其中運(yùn)行一個(gè)searchengine進(jìn)程和一個(gè)indexer進(jìn)程。這和上文中介紹的在Mac主機(jī)上運(yùn)行的方式是一樣的,但這不符合分布式系統(tǒng)的一般部署原則。

通常,為了提高處理速度、提升吞吐量和系統(tǒng)容錯(cuò)能力,每個(gè)程序都會(huì)啟動(dòng)為多個(gè)進(jìn)程,運(yùn)行在不同的機(jī)器上。比如,indexer程序的每個(gè)進(jìn)程處理一部分?jǐn)?shù)據(jù)(比如一個(gè)cralwer進(jìn)程的輸出)。這樣的并行處理提升建立索引的效率。這種情況下,每個(gè)進(jìn)程及其處理的數(shù)據(jù)被稱為一個(gè)shard。(shard應(yīng)該怎么翻譯?我不知道)。

類似地,searchengine進(jìn)程也會(huì)啟動(dòng)為多個(gè)進(jìn)程,每個(gè)進(jìn)程的內(nèi)存空間里都裝著同樣地索引結(jié)構(gòu),所以都能提供同樣地服務(wù),從而提升吞吐量。如果這些進(jìn)程運(yùn)行在不同的機(jī)器上,那么哪怕某些機(jī)器掛了,還有活著的進(jìn)程能不間斷地提供搜索服務(wù)。這樣的每個(gè)進(jìn)程被稱為一個(gè)replication。

其實(shí)每個(gè)indexer shard也可以是一組多個(gè)進(jìn)程,其中每個(gè)進(jìn)程是隸屬本shard的一個(gè)replication。從而同時(shí)提升indexer的處理速度和容錯(cuò)能力。

這么多進(jìn)程應(yīng)該啟動(dòng)在哪些機(jī)器上呢?要靠人來(lái)決定,可就忙不過(guò)來(lái)咯;得靠機(jī)群管理系統(tǒng)。Google Borg就是這樣一套系統(tǒng)。

可是在很多年的時(shí)間里,外界都不知道Borg。有一些項(xiàng)目試圖模仿Google的計(jì)算架構(gòu),比如Hadoop意圖模仿MapReduce。Google MapReduce是一個(gè)構(gòu)建在Borg之上的并行計(jì)算框架。但是Hadoop的開發(fā)者沒有開發(fā)類似Borg的系統(tǒng),而是讓Hadoop(計(jì)算框架)兼任資源管理和調(diào)度的功能,導(dǎo)致系統(tǒng)復(fù)雜,代碼亂作一團(tuán)。

實(shí)際上,在Hadoop開始的若干年里,甚至沒有像Google MapReduce那樣讓每個(gè)job有一個(gè)master進(jìn)程來(lái)管理;而是讓機(jī)群上所有job里的所有進(jìn)程都向一個(gè)叫Job Tracker的進(jìn)程匯報(bào)心跳(heartbeat),以至于一個(gè)Hadoop機(jī)群不能太大,否則Job Tracker會(huì)處理不過(guò)來(lái)。而且Job Tracker作為性能和穩(wěn)定性的雙重瓶頸,一旦累壞了,整個(gè)機(jī)群上所有job就都掛了。Hadoop的開發(fā)者直到2011年左右才意識(shí)到這一點(diǎn),并發(fā)布了一篇文章,開始計(jì)劃開發(fā)“下一代Hadoop”,現(xiàn)在被稱為YARN的系統(tǒng)。

YARN的功能和Google Borg有類似之處,但是真正引發(fā)外界對(duì)Google Borg關(guān)注的,是加州大學(xué)伯克利分校和Twitter的合作項(xiàng)目Mesos。這是一個(gè)試圖復(fù)制Borg的嘗試。當(dāng)Mesos在Twitter運(yùn)行起來(lái)的時(shí)候,很多從Google加入Twitter的工程師都很興奮――終于重新能“高效工作”了!這里的故事,可以參見這篇Wired文章。Mesos系統(tǒng)設(shè)計(jì)思路描述在這篇論文里。其第一作者Ben Hindman曾經(jīng)在Google實(shí)習(xí),后來(lái)在Twitter任職。

實(shí)際上,即便Mesos也沒有能很相似地模仿Google Borg。至少在程序的發(fā)布和部署上。Mesos沒有和Google Borg等效的打包和執(zhí)行包的功能。而這個(gè)功能能為外界所訪問(wèn),正是靠了本文著重介紹的Docker。Docker和Google Borg一樣,使用Google工程師為L(zhǎng)inux內(nèi)核貢獻(xiàn)的cgroups功能來(lái)實(shí)現(xiàn)集裝箱機(jī)制。

借助Docker,Google終于于本月(2014年7月)開源了Borg――但是是用Go語(yǔ)言重寫的Borg,稱為Kubernetes――Google Borg是用C++開發(fā)的。感謝開源社區(qū)不懈的推動(dòng)!

集成測(cè)試

基于上一節(jié)的介紹,我們能想象,如果每個(gè)集裝箱只執(zhí)行一個(gè)進(jìn)程,那么機(jī)群管理系統(tǒng)在部署和調(diào)度應(yīng)用時(shí)受到的限制最少。反過(guò)來(lái)想,如果我們?cè)谝粋€(gè)集裝箱里同時(shí)運(yùn)行一個(gè)indexer進(jìn)程和一個(gè)searchengine進(jìn)程,那么我們實(shí)際上引入了一個(gè)不必要的約束――indexer進(jìn)程和searchengine進(jìn)程一一對(duì)應(yīng)。而且如果機(jī)群中有一臺(tái)機(jī)器,可以承擔(dān)運(yùn)行一個(gè)進(jìn)程的負(fù)載,但是不能承擔(dān)同時(shí)運(yùn)行兩個(gè)進(jìn)程,那么這臺(tái)機(jī)器上就沒法部署上述“大”集裝箱了。

所以,在Google Borg和Google Kubernetes里,都建議每個(gè)集裝箱里只執(zhí)行一個(gè)進(jìn)程。

基于“打包一次,兼顧測(cè)試和發(fā)布”的原則,我們可以想象,對(duì)于一個(gè)應(yīng)用(或者叫做產(chǎn)品,比如上述的極簡(jiǎn)搜索引擎),最常見的打包方式是產(chǎn)生一個(gè)集裝箱鏡像,但是每個(gè)集裝箱里只執(zhí)行一個(gè)程序的一個(gè)進(jìn)程。

上文中,我們已經(jīng)用一個(gè)Dockerfile把兩個(gè)程序:indexer和searchengine都裝進(jìn)一個(gè)鏡像wangkuiyi/hellworld了。接下來(lái),我們嘗試在Mac主機(jī)上啟動(dòng)兩個(gè)集裝箱,分別執(zhí)行一個(gè)indexer和一個(gè)searchengine進(jìn)程:

docker run -d -p 8080:8080 --name searchengine wangkuiyi/helloworld /searchengine
VBoxManage modifyvm "boot2docker-vm" --natpf1 "tcp-port8080,tcp,,8080,,8080"
docker run -d --name indexer --link searchengine:se wangkuiyi/helloworld /indexer -searchengine=se:8080

這里,第一行啟動(dòng)了一個(gè)集裝箱,并且起名叫searchengine,執(zhí)行的鏡像是wangkuiyi/helloworld。-d的意思是在后臺(tái)執(zhí)行,類似一個(gè)shell命令后面跟上一個(gè)&符號(hào)的效果。-p 8080:8080的意思是:“這個(gè)集裝箱里有個(gè)程序會(huì)監(jiān)聽8080端口(如果看看searchengine的源碼,會(huì)發(fā)現(xiàn)8080是其默認(rèn)端口),把這個(gè)端口映射到主機(jī)(boot2docker創(chuàng)建的Linux虛擬機(jī))的8080端口”。

第二個(gè)命令讓VirtualBox把Linux虛擬機(jī)的8080端口映射為Mac主機(jī)的8080端口。這樣就可以在Mac主機(jī)上啟動(dòng)一個(gè)瀏覽器,通過(guò)訪問(wèn)本機(jī)的8080端口,來(lái)訪問(wèn)集裝箱里的searchengine服務(wù)。(如果你在Linux主機(jī)上開發(fā),就不需要boot2docker虛擬一個(gè)Linux主機(jī)了,也就不需要這個(gè)命令了。)

上述第三個(gè)命令啟動(dòng)了一個(gè)名為indexer的集裝箱,執(zhí)行的也是wangkuiyi/helloworld鏡像。在這個(gè)集裝箱里啟動(dòng)了一個(gè)indexer進(jìn)程;這個(gè)進(jìn)程會(huì)去連接se:8080這個(gè)網(wǎng)絡(luò)地址,并通過(guò)RPC調(diào)用,向這個(gè)目標(biāo)地址發(fā)送更新的索引數(shù)據(jù)。se這個(gè)IP地址是怎么來(lái)的呢?這是--link seachengine:se參數(shù)的效果――這個(gè)參數(shù)使得Docker在啟動(dòng)indexer集裝箱之前,修改了其中/etc/hosts文件,在其中增加了一行:

 xxx.xxx.xxx.xxx se

這里 xxx.xxx.xxx.xxx 指代集裝箱searchengine(--link searchengine:se中冒號(hào)左邊的部分)的虛擬IP地址,se(--link searchengine:se中冒號(hào)右邊的部分)也就是其域名了。Docker就是通過(guò)--link這個(gè)參數(shù),讓不同集裝箱內(nèi)的多個(gè)進(jìn)程可以互相通信的。

此時(shí),在本機(jī)打開一個(gè)瀏覽器窗口并訪問(wèn)http://localhost:8080/?q=news,可以看到和上圖完全一樣的結(jié)果。

自動(dòng)部署

到目前為止,我們都是手動(dòng)調(diào)用docker命令來(lái)操作docker的。而得到的效果――在Mac主機(jī)上啟動(dòng)極簡(jiǎn)搜索引擎――和不用Docker是一樣的。大家不禁會(huì)問(wèn),為什么要引入Docker呢?

其實(shí),實(shí)際使用Docker時(shí),我們不會(huì)手動(dòng)敲docker命令,而是會(huì)利用fleet或者Kubernetes來(lái)部署和啟動(dòng)集裝箱。這樣只需要寫一個(gè)非常簡(jiǎn)明的部署配置文件,就可以在開發(fā)機(jī)、集成測(cè)試機(jī)群、預(yù)發(fā)布機(jī)群、和產(chǎn)品環(huán)境中完成部署了。這篇文章為了說(shuō)明Docker的設(shè)計(jì)思路和使用方法已經(jīng)很長(zhǎng)了,所以關(guān)于fleet和Kubernetes的介紹,我準(zhǔn)備放在《Docker:分布式系統(tǒng)的軟件工程革命(下)》中。

原文鏈接:Docker:分布式系統(tǒng)的軟件工程革命(上)(責(zé)編/魏偉)

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 久久久久福利视频 | 国产精品久久久久久久久久久不卡 | 99re最新视频 | 久久精品国产亚洲一区二区三区 | 亚洲免费视频一区 | 国产精品久久久久久久久久浪潮 | 成年人免费网站 | 久久精品日 | 国产精品成人国产乱一区 | 69视频免费看 | 久久久久久国裸歌舞团 | 久久久免费毛片 | 亚洲成人免费观看 | 欧美一区二区三区在线视频 | 中文字幕视频在线观看 | 7799精品视频 | 国产一区二区精品免费 | 日韩精品不卡 | 吞噬星空在线观看 | 国产精品一区二区久久久 | 欧美日韩一区精品 | 国产精品亚洲欧美 | 精品国产一区二区三区在线观看 | 中文字幕日韩欧美一区二区三区 | 久热中文字幕 | 日韩激情图片 | 国产精品一区二区久久久 | 国产麻豆精品 | 99国产超薄肉色丝袜交足的后果 | 天堂√中文最新版在线 | 国产日韩欧美视频 | 91精品国产乱码久久久久久 | 日韩和的一区二在线 | 国产乱妇4p交换乱免费视频 | 亚洲高清免费视频 | 日韩不卡一区二区三区 | 国产日韩一区二区 | 成人久久久精品国产乱码一区二区 | 99久久精品一区二区成人 | 看片91| 久久美|