天天看點

分布式處理與大資料平台(RabbitMQ&Celery&Hadoop&Spark&Storm&Elasticsearch)

熱門的消息隊列中間件RabbitMQ,分布式任務處理平台Celery,大資料分布式處理的三大重量級武器:Hadoop、Spark、Storm,以及新一代的資料采集和分析引擎Elasticsearch。

RabbitMQ是一個支援Advanced Message Queuing Protocol(AMQP)的開源消息隊列實作,由Erlang編寫,因以高性能、高可用以及可伸縮性出名。它支援多種用戶端,如:Java、Python、PHP、.NET、Ruby、JavaScript等。它主要用于在分布式系統中存儲和轉發消息,友善元件之間的解耦,消息的發送者無需知道消息使用者的存在,反之亦然。

AMQP架構中有兩個主要元件:Exchange和Queue,兩者都在服務端,又稱Broker,由RabbitMQ實作的。用戶端通常有Producer和Consumer兩種類型。

分布式處理與大資料平台(RabbitMQ&Celery&Hadoop&Spark&Storm&Elasticsearch)

在使用RabbitMQ過程中需要注意的是,它将資料存儲在Node中,預設情況為hostname。是以在使用docker run指令運作容器的時候,應該通過-h/--hostname參數指定每一個rabbitmq daemon運作的主機名。這樣就可以輕松地管理和維護資料了:

$ docker run -d --hostname my-rabbit --name some-rabbit rabbitmq:3

3f28f6290e05375363ee661151170d37fbc89ada004c3235f02997b711b4cb2b

使用者使用rabbitmqctl工具進行遠端管理,或跨容器管理的時候,會需要設定持久化的cookie。這裡可以使用RABBITMQ_ERLANG_COOKIE參數進行設定:

$ docker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq:3

使用cookie連接配接至一個獨立的執行個體:

$ docker run -it --rm --link some-rabbit:my-rabbit -e RABBITMQ_ERLANG_COOKIE='secret cookie here' rabbitmq:3 bash

root@f2a2d3d27c75:/# rabbitmqctl -n rabbit@my-rabbit list_users

Listing users ...

guest   [administrator]

同樣,使用者也可以使用RABBITMQ_NODENAME簡化指令:

$ docker run -it --rm --link some-rabbit:my-rabbit -e RABBITMQ_ERLANG_COOKIE='secret cookie here' -e RABBITMQ_NODENAME=rabbit@my-rabbit rabbitmq:3 bash

root@f2a2d3d27c75:/# rabbitmqctl list_users

預設情況下,rabbitmq會安裝并啟動一些管控插件,如rabbitmq:3-management。通常可以通過預設使用者名密碼以及标準管控端口15672通路這些插件:

$ docker run -d --hostname my-rabbit --name some-rabbit rabbitmq:3-management

使用者可以通過浏覽器通路http://container-ip:15672,如果需要從主控端外通路,則使用8080端口:

$ docker run -d --hostname my-rabbit --name some-rabbit -p 8080:15672 rabbitmq:3-management

如果需要修改預設使用者名與密碼(guest:guest),則可以使用RABBITMQ_DEFAULT_USER和RABBITMQ_DEFAULT_PASS環境變量:

$ docker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password rabbitmq:3-management

如果需要修改預設vhost,可以修改RABBITMQ_DEFAULT_VHOST環境變量:

$ docker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_VHOST=my_vhost rabbitmq:3-management

然後連接配接至daemon:

$ docker run --name some-app --link some-rabbit:rabbit -d application-that-uses-rabbitmq

使用者也可以通路官方鏡像倉庫,并對Dockerfile進行更多定制。

除了通用的消息隊列外,任務隊列在分布式進行中也十分重要。任務隊列的輸入是工作的一個單元,稱為任務,有多個工作者監聽隊列來擷取任務并執行。

Celery是一個簡單、靈活、高可用、高性能的開源(BSD許可)分布式任務處理系統,專注于實時處理的任務隊列管理,同時也支援任務排程。Celery基于Python實作,跟包括Django、Pyramid、Pylons、Flask、Tornado等Web架構都無縫內建,有龐大的使用者與貢獻者社群。Celery可以單機運作,也可以在多台機器上運作,甚至可以跨越資料中心運作。

1.使用官方鏡像

啟動一個celery worker,即RabbitMQ Broker:

$ docker run --link some-rabbit:rabbit --name some-celery -d celery:latest

檢查叢集狀态:

$ docker run --link some-rabbit:rabbit --rm celery celery status

啟動一個celery worker,即Redis Broker:

$ docker run --link some-redis:redis -e CELERY_BROKER_URL=redis://redis --name some-celery -d celery

$ docker run --link some-redis:redis -e CELERY_BROKER_URL=redis://redis --rm celery celery status

2.使用Celery庫

如果使用者使用的架構已有Celery庫,那麼使用起來會更友善。

下面是Python中調用Celery的hello world程式:

作為當今大資料處理領域的經典分布式平台,Apache Hadoop主要基于Java語言實作,由三個核心子系統組成:HDFS、YARN、MapReduce,其中,HDFS是一套分布式檔案系統;YARN是資源管理系統,MapReduce是運作在YARN上的應用,負責分布式處理管理。如果從作業系統的角度看,HDFS相當于Linux的ext3/ext4檔案系統,而Yarn相當于Linux的程序排程和記憶體配置設定子產品。

可以通過docker run指令運作鏡像,同時打開bash指令行,如下所示:

$ docker run -it sequenceiq/hadoop-docker:2.7.0 /etc/bootstrap.sh -bash

bash-4.1#

此時可以檢視各種配置資訊和執行操作,例如檢視namenode日志等資訊:

bash-4.1# cat /usr/local/hadoop/logs/hadoop-root-namenode-d4e1e9d8f24f.out

2.安裝驗證

需要驗證Hadoop環境是否安裝成功。打開容器的bash指令行環境,進入Hadoop目錄:

bash-4.1# cd $HADOOP_PREFIX

bash-4.1# pwd

/usr/local/hadoop

然後通過運作Hadoop内置的執行個體程式來進行測試:

bash-4.1# bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.0.jar grep input output 'dfs[a-z.]+'

最後可以使用hdfs指令檢查輸出結果:

bash-4.1# bin/hdfs dfs -cat output/*

Apache Spark是一個圍繞速度、易用性和複雜分析建構的大資料處理架構,基于Scala開發。最初在2009年由加州大學伯克利分校的AMPLab開發,并于2010年成為Apache的開源項目之一。與Hadoop和Storm等其他大資料和MapReduce技術相比,Spark支援更靈活的函數定義,可以将應用處理速度提升一到兩個數量級,并且提供了衆多友善的實用工具,包括SQL查詢、流處理、機器學習和圖處理等。

Spark體系架構包括如下三個主要元件:資料存儲、API、管理架構,如圖13-3所示。

分布式處理與大資料平台(RabbitMQ&Celery&Hadoop&Spark&Storm&Elasticsearch)

使用者可以使用sequenceiq/spark鏡像,版本方面支援Hadoop 2.6.0,Apache Spark v1.6.0(CentOS)。同時此鏡像還包含Dockerfile,使用者可以基于它建構自定義的Apache Spark鏡像。

使用者使用docker pull指令直接擷取鏡像:

$ docker pull sequenceiq/spark:1.6.0

也可以使用docker build指令建構spark鏡像:

$ docker build --rm -t sequenceiq/spark:1.6.0 .

另外,使用者在運作容器時,需要映射YARN UI需要的端口:

$ docker run -it -p 8088:8088 -p 8042:8042 -h sandbox sequenceiq/spark:1.6.0 bash

啟動後,可以使用bash指令行來檢視namenode日志等資訊:

bash-4.1# cat /usr/local/hadoop/logs/hadoop-root-namenode-sandbox.out

2.驗證

基于YARN部署Spark系統時,使用者有兩種部署方式可選:YARN用戶端模式和YARN叢集模式。

下面分别論述兩種部署方式。

1.YARN用戶端模式

在YARN用戶端模式中,SparkContext(或稱為驅動程式,driver program)運作在用戶端程序中,應用的master僅處理來自YARN的資源管理請求:

2.YARN叢集模式

在YARN叢集模式中,Spark driver驅動程式運作于應用master的程序中,即由YARN從叢集層面進行管理。

下面,使用者以Pi值計算為例子,展現兩種模式的差別:

Pi計算(YARN叢集模式):

Pi計算(YARN用戶端模式):

3.容器外通路Spark

如果需要從容器外通路Spark環境,則需要設定YARN_CONF_DIR環境變量。隻能使用根使用者通路Docker的HDFS環境。

yarn-remote-client檔案夾内置遠端通路的配置資訊:

export YARN_CONF_DIR="`pwd`/yarn-remote-client"

當使用者從容器叢集外部,使用非根使用者通路Spark環境時,則需要配置HADOOP_USER_NAME環境變量:

export HADOOP_USER_NAME=root

Apache Storm是一個實時流計算架構,由Twitter在2014年正式開源,遵循Eclipse Public License 1.0。Storm基于Clojure等語言實作。 

Storm叢集與Hadoop叢集在工作方式上十分相似,唯一差別在于Hadoop上運作的是MapReduce任務,在Storm上運作的則是topology。MapReduce任務完成處理即會結束,而topology則永遠在等待消息并處理(直到被停止)。

使用Compose搭建Storm叢集

利用Docker Compose模闆,使用者可以在本地單機Docker環境快速地搭建一個Apache Storm叢集,進行應用開發測試。

1.Storm示例架構,Storm架構圖。

分布式處理與大資料平台(RabbitMQ&Celery&Hadoop&Spark&Storm&Elasticsearch)

其中包含如下容器:

·Zookeeper:Apache Zookeeper三節點部署。

·Nimbus:Storm Nimbus。

·Ui:Storm UI

·Supervisor:Storm Supervisor(一個或多個)。

·Topology:Topology部署工具,其中示例應用基于官方示例storm-starter代碼建構。

2.本地開發測試

首先從Github下載下傳需要的代碼:

$ git clone https://github.com/denverdino/docker-storm.git

$ cd docker-swarm/local

代碼庫中的docker-compose.yml檔案描述了典型的Storm應用架構。

使用者可以直接運作下列指令建構測試鏡像:

$ docker-compose build

現在可以用下面的指令來一鍵部署一個Storm應用:

$ docker-compose up -d

當UI容器啟動後,使用者可以通路容器的8080端口來打開操作界面。 

利用如下指令,可以伸縮supervisor的數量,比如伸縮到3個執行個體:

$ docker-compose scale supervisor=3

使用者也許會發現Web界面中并沒有運作中的topology。這是因為Docker Compose目前隻能保證容器的啟動順序,但是無法確定所依賴容器中的應用已經完全啟動并可以被正常通路了。為了解決這個問題,需要運作下面的指令來再次啟動topolgoy服務應用來送出更新的拓撲:

$ docker-compose start topology

稍後重新整理Storm UI,可以發現Storm應用已經部署成功了。

Elasticsearch是一個基于Lucene的開源搜尋伺服器,主要基于Java實作。它提供了一個分布式的,多租戶的全文搜尋引擎,内含RESTful web接口。

Elasticsearch提供了實時的分布式資料存儲和分析查詢功能,很容易擴充到上百台伺服器,支援處理PB級結構化或非結構化資料。配合Logstash、Kibana等元件,可以快速建構一套對日志消息的分析平台。

可以使用官方鏡像,快速運作Elasticsearch容器:

$ docker run -d elasticsearch

也可以在啟動時傳入一些額外的配置參數:

$ docker run -d elasticsearch elasticsearch -Des.node.name="TestNode"

目前使用的鏡像内含預設配置檔案,包含了預先定義好的預設配置。

如果使用者要使用自定義配置,可以使用資料卷,挂載自定義配置檔案至/usr/share/elasticsearch/config:

$ docker run -d -v "$PWD/config":/usr/share/elasticsearch/config elasticsearch

如果需要資料持久化,可以使用資料卷指令,挂載至/usr/share/elasticsearch/data:

$ docker run -d -v "$PWD/esdata":/usr/share/elasticsearch/data elasticsearch

此鏡像會暴露9200 9300兩個預設的HTTP端口,可以通過此端口進行服務通路。9200端口是對外提供服務的API使用的端口。9300端口是内部通信端口,這些通信包括心跳,叢集内部資訊同步。

分布式處理與大資料處理領域的典型熱門工具,包括Rabbitmq、Celery、Hadoop、Spark、Storm和Elasticsearch等。這些開源項目的出現,極大降低了開發者進行分布式處理和資料分析的門檻。

實際上,摩爾定律的失效,必将導緻越來越多的複雜任務必須采用分布式架構進行處理。在新的架構和平台下,如何實作高性能、高可用性,如何讓應用容易開發、友善調試,都是十分複雜的問題。已有的開源平台項目提供了很好的實作參考,友善使用者将更多的精力放到核心業務的維護上。通過基于容器的部署和使用,極大簡化了對如此複雜系統的使用和維護。