成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

通過 Mesos、Docker 和 Go,使用 300 行代碼創(chuàng)建一個分布式系統(tǒng)

douzifly / 1972人閱讀

摘要:在分布式系統(tǒng)用例上,比特幣開采就是一個很好的例子。會和一個比特幣采礦池通信,并給每個分配。這里是相關(guān)的代碼萬事大吉通過努力,這里在上建立一個正常工作的分布式比特幣開采框架,它只用了大約行代碼。

【摘要】雖然 Docker 和 Mesos 已成為不折不扣的 Buzzwords ,但是對于大部分人來說它們?nèi)匀皇悄吧?,下面我們就一起領(lǐng)略 Mesos 、Docker 和 Go 配合帶來的強大破壞力,如何通過 300 行代碼打造一個比特幣開采系統(tǒng)。

時下,對于大部分 IT 玩家來說, Docker 和 Mesos 都是熟悉和陌生的:熟悉在于這兩個詞無疑已成為大家討論的焦點,而陌生在于這兩個技術(shù)并未在生產(chǎn)環(huán)境得到廣泛使用,因此很多人仍然不知道它們究竟有什么優(yōu)勢,或者能干什么。近日, John Walter 在 Dzone 上撰文 Creating a Distributed System in 300 Lines With Mesos, Docker, and Go,講述了 Mesos、Docker 和 Go 配合帶來的強大破壞力,本文由 OneAPM 工程師編譯整理。

誠然,構(gòu)建一個分布式系統(tǒng)是很困難的,它需要可擴展性、容錯性、高可用性、一致性、可伸縮以及高效。為了達(dá)到這些目的,分布式系統(tǒng)需要很多復(fù)雜的組件以一種復(fù)雜的方式協(xié)同工作。例如,Apache Hadoop 在大型集群上并行處理 TB 級別的數(shù)據(jù)集時,需要依賴有著高容錯的文件系統(tǒng)( HDFS )來達(dá)到高吞吐量。

在之前,每一個新的分布式系統(tǒng),例如 Hadoop 和 Cassandra ,都需要構(gòu)建自己的底層架構(gòu),包括消息處理、存儲、網(wǎng)絡(luò)、容錯性和可伸縮性。慶幸的是,像 Apache Mesos 這樣的系統(tǒng),通過給分布式系統(tǒng)的關(guān)鍵構(gòu)建模塊提供類似操作系統(tǒng)的管理服務(wù),簡化了構(gòu)建和管理分布式系統(tǒng)的任務(wù)。Mesos 抽離了 CPU 、存儲和其它計算資源,因此開發(fā)者開發(fā)分布式應(yīng)用程序時能夠?qū)⒄麄€數(shù)據(jù)中心集群當(dāng)做一臺巨型機對待。

構(gòu)建在 Mesos 上的應(yīng)用程序被稱為框架,它們能解決很多問題: Apache Spark,一種流行的集群式數(shù)據(jù)分析工具;Chronos ,一個類似 cron 的具有容錯性的分布式 scheduler ,這是兩個構(gòu)建在 Mesos 上的框架的例子。構(gòu)建框架可以使用多種語言,包括 C++,Go,Python,Java,Haskell 和 Scala。

在分布式系統(tǒng)用例上,比特幣開采就是一個很好的例子。比特幣將為生成 acceptable hash 的挑戰(zhàn)轉(zhuǎn)為驗證一塊事務(wù)的可靠性。可能需要幾十年,單臺筆記本電腦挖一塊可能需要花費超過 150 年。結(jié)果是,有許多的“采礦池”允許采礦者將他們的計算資源聯(lián)合起來以加快挖礦速度。Mesosphere 的一個實習(xí)生, Derek ,寫了一個比特幣開采框架(https://github.com/derekchiang/Mesos-Bitcoin-Miner),利用集群資源的優(yōu)勢來做同樣的事情。在接下來的內(nèi)容中,會以他的代碼為例。

1 個 Mesos 框架有 1 個 scheduler 和 1 個 executor 組成。scheduler 和 Mesos master 通信并決定運行什么任務(wù),而 executor 運行在 slaves 上面,執(zhí)行實際任務(wù)。大多數(shù)的框架實現(xiàn)了自己的 scheduler,并使用 1 個由 Mesos 提供的標(biāo)準(zhǔn) executors 。當(dāng)然,框架也可以自己定制 executor 。在這個例子中即會編寫定制的 scheduler,并使用標(biāo)準(zhǔn)命令執(zhí)行器( executor )運行包含我們比特幣服務(wù)的 Docker 鏡像。

對這里的 scheduler 來說,需要運行的有兩種任務(wù)—— one miner server task and multiple miner worker tasks。 server 會和一個比特幣采礦池通信,并給每個 worker 分配 blocks 。Worker 會努力工作,即開采比特幣。

任務(wù)實際上被封裝在 executor 框架中,因此任務(wù)運行意味著告訴 Mesos master 在其中一個 slave 上面啟動一個 executor 。由于這里使用的是標(biāo)準(zhǔn)命令執(zhí)行器(executor),因此可以指定任務(wù)是二進制可執(zhí)行文件、bash 腳本或者其他命令。由于 Mesos 支持 Docker,因此在本例中將使用可執(zhí)行的 Docker 鏡像。Docker 是這樣一種技術(shù),它允許你將應(yīng)用程序和它運行時需要的依賴一起打包。

為了在 Mesos 中使用 Docker 鏡像,這里需要在 Docker registry 中注冊它們的名稱:

const (
    MinerServerDockerImage = "derekchiang/p2pool"
    MinerDaemonDockerImage = "derekchiang/cpuminer"
)

然后定義一個常量,指定每個任務(wù)所需資源:

const (
    MemPerDaemonTask = 128  // mining shouldn"t be    memory-intensive
    MemPerServerTask = 256
    CPUPerServerTask = 1    // a miner server does not use much     CPU
)

現(xiàn)在定義一個真正的 scheduler ,對其跟蹤,并確保其正確運行需要的狀態(tài):

type MinerScheduler struct { 
    // bitcoind RPC credentials
    bitcoindAddr string
    rpcUser      string
    rpcPass      string
    // mutable state
    minerServerRunning  bool
    minerServerHostname string 
    minerServerPort     int    // the port that miner daemons 
                               // connect to
    // unique task ids
    tasksLaunched        int
    currentDaemonTaskIDs []*mesos.TaskID
}

這個 scheduler 必須實現(xiàn)下面的接口:

type Scheduler interface {
    Registered(SchedulerDriver, *mesos.FrameworkID,     *mesos.MasterInfo)
    Reregistered(SchedulerDriver, *mesos.MasterInfo)
    Disconnected(SchedulerDriver)
    ResourceOffers(SchedulerDriver, []*mesos.Offer)
    OfferRescinded(SchedulerDriver, *mesos.OfferID)
    StatusUpdate(SchedulerDriver, *mesos.TaskStatus)
    FrameworkMessage(SchedulerDriver, *mesos.ExecutorID, 
                     *mesos.SlaveID, string)
    SlaveLost(SchedulerDriver, *mesos.SlaveID)
    ExecutorLost(SchedulerDriver, *mesos.ExecutorID,   *mesos.SlaveID, 
                 int)
    Error(SchedulerDriver, string)
}

現(xiàn)在一起看一個回調(diào)函數(shù):

func (s *MinerScheduler) Registered(_ sched.SchedulerDriver, 
      frameworkId *mesos.FrameworkID, masterInfo *mesos.MasterInfo) {
    log.Infoln("Framework registered with Master ", masterInfo)
}
func (s *MinerScheduler) Reregistered(_ sched.SchedulerDriver, 
      masterInfo *mesos.MasterInfo) {
    log.Infoln("Framework Re-Registered with Master ",  masterInfo)
}
func (s *MinerScheduler) Disconnected(sched.SchedulerDriver) {
    log.Infoln("Framework disconnected with Master")
}

Registered 在 scheduler 成功向 Mesos master 注冊之后被調(diào)用。

Reregistered 在 scheduler 與 Mesos master 斷開連接并且再次注冊時被調(diào)用,例如,在 master 重啟的時候。

Disconnected 在 scheduler 與 Mesos master 斷開連接時被調(diào)用。這個在 master 掛了的時候會發(fā)生。

目前為止,這里僅僅在回調(diào)函數(shù)中打印了日志信息,因為對于一個像這樣的簡單框架,大多數(shù)回調(diào)函數(shù)可以空在那里。然而,下一個回調(diào)函數(shù)就是每一個框架的核心,必須要認(rèn)真的編寫。

ResourceOffers 在 scheduler 從 master 那里得到一個 offer 的時候被調(diào)用。每一個 offer 包含一個集群上可以給框架使用的資源列表。資源通常包括 CPU 、內(nèi)存、端口和磁盤。一個框架可以使用它提供的一些資源、所有資源或者一點資源都不給用。

針對每一個 offer ,現(xiàn)在期望聚集所有的提供的資源并決定是否需要發(fā)布一個新的 server 任務(wù)或者一個新的 worker 任務(wù)。這里可以向每個 offer 發(fā)送盡可能多的任務(wù)以測試最大容量,但是由于開采比特幣是依賴 CPU 的,所以這里每個 offer 運行一個開采者任務(wù)并使用所有可用的 CPU 資源。

for i, offer := range offers {
    // … Gather resource being offered and do setup
    if !s.minerServerRunning && mems >= MemPerServerTask &&
            cpus >= CPUPerServerTask && ports >= 2 {
        // … Launch a server task since no server is running and     we 
        // have resources to launch it.
    } else if s.minerServerRunning && mems >= MemPerDaemonTask {
        // … Launch a miner since a server is running and we have     mem 
        // to launch one.
    }
}

針對每個任務(wù)都需要創(chuàng)建一個對應(yīng)的 TaskInfo message ,它包含了運行這個任務(wù)需要的信息。

s.tasksLaunched++
taskID = &mesos.TaskID {
    Value: proto.String("miner-server-" + 
                        strconv.Itoa(s.tasksLaunched)),
}

Task IDs 由框架決定,并且每個框架必須是唯一的。

containerType := mesos.ContainerInfo_DOCKER
task = &mesos.TaskInfo {
    Name: proto.String("task-" + taskID.GetValue()),
    TaskId: taskID,
    SlaveId: offer.SlaveId,
    Container: &mesos.ContainerInfo {
        Type: &containerType,
        Docker: &mesos.ContainerInfo_DockerInfo {
            Image: proto.String(MinerServerDockerImage),
        },
    },
    Command: &mesos.CommandInfo {
        Shell: proto.Bool(false),
        Arguments: []string {
            // these arguments will be passed to run_p2pool.py
            "--bitcoind-address", s.bitcoindAddr,
            "--p2pool-port", strconv.Itoa(int(p2poolPort)),
            "-w", strconv.Itoa(int(workerPort)),
            s.rpcUser, s.rpcPass,
        },
    },
    Resources: []*mesos.Resource {
        util.NewScalarResource("cpus", CPUPerServerTask),
        util.NewScalarResource("mem", MemPerServerTask),
    },
}

TaskInfo message 指定了一些關(guān)于任務(wù)的重要元數(shù)據(jù)信息,它允許 Mesos 節(jié)點運行 Docker 容器,特別會指定 name、task ID、container information 以及一些需要給容器傳遞的參數(shù)。這里也會指定任務(wù)需要的資源。

現(xiàn)在 TaskInfo 已經(jīng)被構(gòu)建好,因此任務(wù)可以這樣運行:

driver.LaunchTasks([]*mesos.OfferID{offer.Id}, tasks,     &mesos.Filters{RefuseSeconds: proto.Float64(1)})

在框架中,需要處理的最后一件事情是當(dāng)開采者 server 關(guān)閉時會發(fā)生什么。這里可以利用 StatusUpdate 函數(shù)來處理。

在一個任務(wù)的生命周期中,針對不同的階段有不同類型的狀態(tài)更新。對這個框架來說,想要確保的是如果開采者 server 由于某種原因失敗,系統(tǒng)會 Kill 所有開采者 worker 以避免浪費資源。這里是相關(guān)的代碼:

if strings.Contains(status.GetTaskId().GetValue(), "server") &&
    (status.GetState() == mesos.TaskState_TASK_LOST ||
        status.GetState() == mesos.TaskState_TASK_KILLED ||
        status.GetState() == mesos.TaskState_TASK_FINISHED ||
        status.GetState() == mesos.TaskState_TASK_ERROR ||
        status.GetState() == mesos.TaskState_TASK_FAILED) {
    s.minerServerRunning = false
    // kill all tasks
    for _, taskID := range s.currentDaemonTaskIDs {
        _, err := driver.KillTask(taskID)
        if err != nil {
            log.Errorf("Failed to kill task %s", taskID)
        }
    }
    s.currentDaemonTaskIDs = make([]*mesos.TaskID, 0)
}

萬事大吉!通過努力,這里在 Apache Mesos 上建立一個正常工作的分布式比特幣開采框架,它只用了大約 300 行 GO 代碼。這證明了使用 Mesos 框架的 API 編寫分布式系統(tǒng)是多么快速和簡單。

原文鏈接:Creating a Distributed System in 300 Lines With Mesos, Docker, and Go

本文由OneAPM工程師編譯 ,想閱讀更多技術(shù)文章,請訪問OneAPM官方技術(shù)博客。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/26433.html

相關(guān)文章

  • 新視界 | 也許這才是大規(guī)模分發(fā)容器鏡像的正確姿勢

    摘要:負(fù)責(zé)承載操作系統(tǒng)的分布式文件系統(tǒng)只需要使用必要的文件,而且事實上只需要下載并在本地緩存這部分必要數(shù)據(jù)。而第二項原則在于元數(shù)據(jù)即與文件存在相關(guān)的信息,而非文件內(nèi)容被優(yōu)先對待。這套鏡像隨后可進行任意分發(fā),并被用于啟動該項任務(wù)。 隨著Docker技術(shù)的日漸火熱,一些容器相關(guān)的問題也浮出水面。本文就容器數(shù)量激增后造成的分發(fā)效率低下問題進行了探討,并提出了一種新的解決方法。發(fā)現(xiàn)問題,解決問題,正...

    hufeng 評論0 收藏0
  • DockerMesos 的前生今世 | 數(shù)人云CTO肖德時@KVM分享實錄

    摘要:今天小數(shù)給大家?guī)硪黄夹g(shù)正能量滿滿的分享來自社區(qū)線上群分享的實錄,分享嘉賓是數(shù)人云肖德時。第二級調(diào)度由被稱作的組件組成。它們是最小的部署單元,由統(tǒng)一創(chuàng)建調(diào)度管理。 今天小數(shù)給大家?guī)硪黄夹g(shù)正能量滿滿的分享——來自KVM社區(qū)線上群分享的實錄,分享嘉賓是數(shù)人云CTO肖德時。 嘉賓介紹: 肖德時,數(shù)人云CTO 十五年計算機行業(yè)從業(yè)經(jīng)驗,曾為紅帽 Engineering Service ...

    0x584a 評論0 收藏0
  • 數(shù)人云工程師手記 | 容器日志管理實踐

    摘要:容器內(nèi)文件日志平臺支持的文件存儲是,避免了許多復(fù)雜環(huán)境的處理。以上是數(shù)人云在實踐容器日志系統(tǒng)過程中遇到的問題,更高層次的應(yīng)用包括容器日志分析等,還有待繼續(xù)挖掘和填坑,歡迎大家提出建議,一起交流。 業(yè)務(wù)平臺每天產(chǎn)生大量日志數(shù)據(jù),為了實現(xiàn)數(shù)據(jù)分析,需要將生產(chǎn)服務(wù)器上的所有日志收集后進行大數(shù)據(jù)分析處理,Docker提供了日志驅(qū)動,然而并不能滿足不同場景需求,本次將結(jié)合實例分享日志采集、存儲以...

    saucxs 評論0 收藏0
  • Docker相關(guān)的項目

    摘要:相關(guān)基于項目和項目,并遵循應(yīng)用的十二因素風(fēng)格。相關(guān)在設(shè)計上,項目盡量保持驅(qū)動和模塊化,以便模塊支持不同的實現(xiàn)方案。相關(guān)不僅可以管理眾多虛擬機,其計算服務(wù)還支持對的驅(qū)動,管理引擎的子項目還可用于通過模板管理容器?,F(xiàn)已整合公司所支持的項目。 整理自《Docker技術(shù)入門與實踐》 PaaS(Platform as a Service) PaaS 是希望提供一個統(tǒng)一的可供所有軟件直接運行而無需...

    littlelightss 評論0 收藏0
  • 容器集群管理工具各項對比

    摘要:由谷歌開發(fā),允許你在許多不同的主機上管理容器化應(yīng)用程序。它已經(jīng)被完全開源,谷歌在年首次宣布開發(fā)它,第一版在夏天的時候發(fā)布。除了最近幾年的收獲,本身也是基于谷歌內(nèi)部十多年使用容器技術(shù)的經(jīng)驗。 基于云的基礎(chǔ)設(shè)施,容器,微服務(wù)和新編程平臺在世界范圍占據(jù)了一大塊媒體領(lǐng)域,橫掃IT界。Docker、容器的使用在這幾個月內(nèi)呈爆炸式增長,已經(jīng)提交了20億的鏡像pulls;鏡像數(shù)在2015年11月就已...

    Faremax 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<