快速開始使用Spark和Alluxio

原文[英]:http://www.alluxio.com/2016/04/getting-started-with-alluxio-and-spark/web

簡介

Alluxio是一個基於內存的分佈式文件系統,它是架構在底層分佈式文件系統和上層分佈式計算框架之間的一箇中間件,主要職責是以文件形式在內存或其它存儲設施中提供數據的存取服務。shell

在大數據計算領域,Spark正成爲耀眼的新星。當Spark與其大量的生態系統結合使用時,更加可以發揮出超長的能力。Alluxio, 原名Tachyon, 爲Spark提供了可靠的數據共享層, 使Spark之行應用邏輯而Alluxio用於處理存儲。例如, 全球金融集團 Barclays made the impossible possible,經過Alluxio和Spark融入其體系架構。 Baidu 分析petabytes級別的數據獲得 30x performance improvements ,經過使用基於 Alluxio 和 Spark 的新架構。 經過 Alluxio 1.0 release and 和即將到來的 Spark 2.0 release, 咱們創建了一個簡單而清晰的方式,把二者整合起來。apache

本文針對Alluxio 和 Spark的新的使用者,在單機上如何配置、使用大數據能力提供幫助。後續,咱們將進一步將Spark和Alluxio擴展到分佈式集羣上。bootstrap

本文內容

  • 如何在本地機器上設置 Alluxio 和 Spark。
  • 使用 Alluxio 和 Spark 的優點。
    • Data sharing between multiple jobs: Only one job needs to incur the slow read from cold data
    • Resilience against job failures: Data is preserved in Alluxio across job failures or restarts
    • Managed storage: Alluxio optimizes the utilization of allocated storage across applications
  • 權衡是否使用基於內存的 Spark application storage 仍是 Alluxio storage。
  • 如何鏈接 Alluxio 到外部存儲, 如 S3。

開始

爲了進行本教程, 我建立一個工做目錄而且賦給環境變量。這使在不一樣的項目目錄中引用代碼變得更爲容易。緩存

  1. mkdir alluxio-spark-getting-started
  2. cd alluxio-spark-getting-started
  3. export DEMO_HOME=$(pwd)

爲了啓動 Alluxio 和 Spark, 首先須要下載這兩個軟件的分發版。本文中, 咱們使用 Alluxio 1.0.1 和 Spark 1.6.1, 使用Alluxio 1.0+ 和 Spark 1.0+的步驟是同樣的。網絡

設置 Alluxio

下載, 提取, 和啓動一個預編譯的 Alluxio,網址: Alluxio website:架構

  1. cd $DEMO_HOME
  2. wget http://alluxio.org/downloads/files/1.0.1/alluxio-1.0.1-bin.tar.gz
  3. tar xvfz alluxio-1.0.1-bin.tar.gz
  4. cd alluxio-1.0.1
  5. bin/alluxio bootstrap-conf localhost
  6. bin/alluxio format
  7. bin/alluxio-start.sh local

驗證一下 Alluxio 是否運行正常,訪問: localhost:19999/home.app

設置 Spark

下載預編譯的Spark版本。Spark須要Alluxio客戶端 jar軟件包,鏈接 Spark 到 Alluxio; 如今是時候整合兩個系統。框架

下載完後, 建立一個新的Spark environment配置,拷貝conf/spark-env.sh.template 到 conf/spark-env.sh。而後,你可讓Alluxio client jar可用,經過將其加到文件conf/spark-env.sh的SPARK_CLASSPATH 項中; 確認你的環境的path配置是正確的。機器學習

  1. cd $DEMO_HOME
  2. wget http://apache.mirrors.pair.com/spark/spark-1.6.1/spark-1.6.1-bin-hadoop2.4.tgz
  3. tar xvfz spark-1.6.1-bin-hadoop2.4.tgz
  4. wget http://alluxio.org/downloads/files/1.0.1/alluxio-core-client-spark-1.0.1-jar-with-dependencies.jar
  5. cd spark-1.6.1-bin-hadoop2.4
  6. cp conf/spark-env.sh.template conf/spark-env.sh
  7. echo 'export SPARK_CLASSPATH=/path/to/alluxio-core-client-spark-1.0.1-jar-with-dependencies.jar:$SPARK_CLASSPATH' >> conf/spark-env.sh

 

運行一個簡單的例子

做爲第一個例子, 咱們運行Alluxio with Spark 從本地存儲讀取數據,來熟悉一下這兩個系統整合後的使用方法。

注意,這種方式從Alluxio獲得的性能提高是有限的; 本地存儲的快速存取和OS buffer cache極大地幫助了磁盤數據的讀取。 對於小的文件,有可能獲得更低的效率,由於在執行期的通信會增長開銷。

示範數據

能夠下載到一個從英文字典中隨機建立的單詞文件。

  1. cd $DEMO_HOME
  2. # compressed version
  3. wget https://s3.amazonaws.com/alluxio-sample/datasets/sample-1g.gz
  4. gunzip sample-1g.gz
  5. # uncompressed version
  6. wget https://s3.amazonaws.com/alluxio-sample/datasets/sample-1g

使用Spark

開啓 spark-shell,以下面從Spark目錄中啓動。 能夠在交互的shell中操做不通來源的數據,就像本地文件系統同樣。

  1. cd $DEMO_HOME/spark-1.6.1-bin-hadoop2.4
  2. bin/spark-shell

在Spark中處理文件,統計文件中有多少行, 確認下載的示範數據文件在指定的目錄中。

  1. val file = sc.textFile("/path/to/sample-1g")
  2. file.count()

使用Alluxio

Alluxio 也能夠做爲數據源。 你能夠保存文件到Alluxio 或者在Alluxio上的數據運行其餘的數據操做, 就像使用本地文件存儲系統同樣。

  1. val file = sc.textFile("/path/to/sample-1g")
  2. file.saveAsTextFile("alluxio://localhost:19998/sample-1g")
  3. val alluxioFile = sc.textFile("alluxio://localhost:19998/sample-1g")
  4. alluxioFile.count()

你能夠看到兩個操做的結果的性能很接近,但在大文件時Alluxio的表現會更好。

與Alluxio存儲數據在內存而後存取處理同樣,Spark 也使用Spark的 application memory,經過cache() API實現。可是,與Alluxio對比,優劣勢是不同的。

若是你使用一個 1 GB 文件, 你將看到一個提示:緩存RDD在內存的空間不夠。這是由於spark-shell缺省啓動時使用 1 GB 內存,而且僅僅分配那麼大的空間用於存儲。

  1. val file = sc.textFile("/path/to/sample-1g")
  2. file.cache()
  3. file.count()
  4. file.count()

你能夠增長驅動的內存,而後重試:

  1. cd $DEMO_HOME/spark-1.6.1-bin-hadoop2.4
  2. bin/spark-shell --driver-memory 4g

你能夠看見第二個count的執行更快一些。可是,Spark緩存的好處是有限的,由於數據存儲在 JVM 內存中。在特殊狀況下, 數據集更大的狀況下, 還有可能引發降低。除此以外,cache 操做不能存儲 raw data, 所以你將須要比文件要大的內存。

你能夠下載一個 2 GB 的示範數據文件:

  1. cd $DEMO_HOME
  2. # compressed version
  3. wget https://s3.amazonaws.com/alluxio-sample/datasets/sample-2g.gz
  4. gunzip sample-2g.gz
  5. # uncompressed version
  6. wget https://s3.amazonaws.com/alluxio-sample/datasets/sample-2g

Spark中緩存數據

做爲一個簡單的例子, 咱們在 spark-shell 分配4 GB內存,而後處理這個 2 GB 文件. 因爲存儲在JVM堆上的Java對象比實際數據要大, Spark 將不能存儲所有數據集在內存中。這將顯著下降job的執行性能,甚至比從磁盤上讀取還要花費更長的時間。

  1. val file = sc.textFile("/path/to/sample-2g")
  2. file.cache()
  3. file.count()
  4. file.count()

一個變通的方案是將對象以序列化方式存儲,將比 Java objects佔用更少的存儲空間。 第二個count 明顯更快一些, 數據必須存儲在Spark process中,而且退出後將再也不可用。此外, 這很難徹底獲得Spark’s 存儲和執行的分片優點,除非根據處理工做狀況手動調節配置參數。

  1. import org.apache.spark.storage.StorageLevel
  2. val file = sc.textFile("/path/to/sample-2g")
  3. file.persist(StorageLevel.MEMORY_ONLY_SER)
  4. file.count()
  5. file.count()

Alluxio緩存數據

Alluxio能夠解決使用Spark的執行存儲遇到的上述問題。 在Alluxio上運行一樣的例程, 咱們首先須要增長Alluxio管理的內存總量。修改 Alluxio’的行 conf/alluxio-env.sh 從 1GB 到 3GB。 這基本上與spark-shell 中的 4 GB 內存至關 (Alluxio 3 GB + spark-shell 1 GB). 而後從新啓動  Alluxio 讓配置參數生效。

  1. cd $DEMO_HOME/alluxio-1.0.1
  2. vi conf/alluxio-env.sh
  3.  
  4. # Modify the memory size line to 3GB in the file, then save and exit
  5. export ALLUXIO_WORKER_MEMORY_SIZE=${ALLUXIO_WORKER_MEMORY_SIZE:-3GB}
  6.  
  7. bin/alluxio-start.sh local

而後, 咱們加載一樣的文件到 Alluxio 系統。能夠經過 Alluxio shell來容易地完成, 或者經過spark-shell 來進行。

  1. cd $DEMO_HOME/alluxio-1.0.1
  2. bin/alluxio fs copyFromLocal ../sample-2g /sample-2g
  3. cd $DEMO_HOME/spark-1.6.1-bin-hadoop2.4
  4. bin/spark-shell

嘗試運行以前一樣的例子, 但使用這個更大的文件。

  1. val alluxioFile2g = sc.textFile("alluxio://localhost:19998/sample-2g")
  2. alluxioFile2g.count()
  3. val alluxioFile1g = sc.textFile("alluxio://localhost:19998/sample-1g")
  4. alluxioFile1g.count()

結果對比

這裏是運行的結果,使用 1 GB spark-shell 和 3 GB Alluxio,與只使用Spark時 4 GB spark-shell (lower is better)的狀況對比。

 

imageedit_24_2141051996

 

imageedit_22_3012070734

 

遠程數據訪問

如今,咱們已經突破了將 Alluxio 和 Spark整合在一塊兒的障礙, 咱們將進一步嘗試更接近生產環境下的例子。這個例子中,咱們將使用Amazon的 S3 存儲服務做爲數據源, 這也很容易替換爲其餘的存儲系統。

不少時候, 數據並不在本地計算機上而是保存在共享存儲上。這種狀況下, Alluxio 能夠透明地鏈接到遠程存儲的優點馬上體現出來。這意味使用另外一個客戶端或者改變文件路徑的時候,能夠接着使用 Alluxio path,就像保存在一個命名空間下同樣。

除此之外, 不少人可能查詢同一個數據集, 例如一個數據團隊的成員。 使用 Alluxio 攤銷了從S3獲取數據的昂貴成本,能夠將其保存在Alluxio的存儲空間中,而且減小了內存消耗。採用這種方法,只要一我的訪問了數據,後續的調用都會在Alluxio的內存中進行。

訪問S3中的數據集

咱們來看一下如何訪問S3中的數據集。

首先, 更新Alluxio使用想要的數據倉儲。 一個公共的,只讀的 S3 bucket中的樣本數據集位於  s3n://alluxio-sample/datasets。

而後, 指定S3 credentials參數 到 Alluxio,經過在 alluxio-env.sh 中設置環境變量來實現。

訪問S3 bucket這個數據不須要權限, 但須要 AWS 用戶帳號才能訪問 S3. 保存您的keys 環境變量 AWS_ACCESS_KEY 和 AWS_SECRET_KEY, 而後更新 alluxio-env.sh.

  1. cd $DEMO_HOME/alluxio-1.0.1
  2. export AWS_ACCESS_KEY=YOUR_ACCESS_KEY
  3. export AWS_SECRET_KEY=YOUR_SECRET_KEY
  4. vi conf/alluxio-env.sh
  5.  
  6. # Modify the ALLUXIO_JAVA_OPTS to add the two parameters
  7. export ALLUXIO_JAVA_OPTS+="
  8. -Dlog4j.configuration=file:${CONF_DIR}/log4j.properties
  9. ...
  10. -Dfs.s3n.awsAccessKeyId=$AWS_ACCESS_KEY
  11. -Dfs.s3n.awsSecretAccessKey=$AWS_SECRET_KEY
  12. "

如今重啓 Alluxio 系統讓Alluxio Server得到須要的受權信息。而後,你能夠直接經過 Alluxio 鏈接到 S3 bucket,經過使用 mount 操做來實現。這將使任何對 Alluxio 路徑 /s3 的訪問直接鏈接到S3 bucket。

  1. cd $DEMO_HOME/alluxio-1.0.1
  2. bin/alluxio-start local
  3. bin/alluxio fs mount /s3 s3n://alluxio-sample/datasets

你將須要添加 S3 credentials 到Spark 環境。以下,在 conf/spark-env.sh中添加下面的行:

  1. cd $DEMO_HOME/spark-1.6.1-bin-hadoop2.4
  2. vi conf/spark-env.sh
  3.  
  4. export SPARK_DAEMON_JAVA_OPTS+="
  5. -Dfs.s3n.awsAccessKeyId=$AWS_ACCESS_KEY
  6. -Dfs.s3n.awsSecretAccessKey=$AWS_SECRET_KEY
  7. "

若是隻是簡單地使用Spark,你能夠以下方式在spark-shell中使用數據。你可能注意到,速度比本地磁盤慢了很多,由於這是經過網路遠程訪問的。 爲了不在後續調用中出現這個問題, 您能夠緩存這個數據,但Spark memory須要至少與數據集同樣大 (在使用serialized cache時須要更大), 而且數據須要緩存在每個Spark context中,不能在不一樣的應用和用戶間共享。注意,運行下面的例子將須要幾分鐘,取決於網絡帶寬的大小。您可使用 100 MB 示例文件,在 s3n://alluxio-sample/datasets/sample-100m。

  1. val file = sc.textFile("s3n://alluxio-sample/datasets/sample-1g")
  2. file.count()
  3. val cachedFile = sc.textFile("s3n://alluxio-sample/datasets/sample-1g")
  4. cachedFile.cache()
  5. cachedFile.count()

使用 Alluxio, 你能夠存取在S3 下的數據。你也許注意到,執行效率同樣, 由於在兩種狀況下都是第一次讀取遠程S3上的數據。可是, 對於後續的讀取來講, 在Alluxio效率更好,由於數據存儲在本地內存上了。 你能夠想象,對於那些非同尋常的計算負荷如數據處理流水線或者遞歸的機器學習, 數據存取的次數會遠遠多於一次。

S3中的數據預取

爲了減小第一次讀取的成本,您能夠預取遠程的數據,經過Alluxio shell的load命令來完成,以下所示。

  1. cd $DEMO_HOME/alluxio-1.0.1
  2. bin/alluxio fs load /s3/sample-1g

若是不預取數據, 直接從 S3 裝入數據到 Alluxio 將設置 partition size 爲1,以確保文件被載入到Alluxio。可是,當讀數據時, 能夠按照適合的方式分區文件。

  1. val file = sc.textFile("alluxio://localhost:19998/s3/sample-1g", 1)
  2. file.count()
  3. val file = sc.textFile("alluxio://localhost:19998/s3/sample-1g", 8)
  4. file.count()

數據訪問性能對比

這裏的執行性能是經過 10 MB/s 網絡鏈接到 S3測試的結果。Alluxio 和 Spark 設置爲分配內存 3 GB 給Alluxio 和 1 GB 給 spark-shell, 與Spark 獨立分配 4 GB 的結果 (下圖中,數值越低越好)。

imageedit_20_4538102820

 

imageedit_18_4833158381

 

結論

這裏介紹了 Alluxio 在 Spark上的運行和使用。後續將進行一些更深刻的案例和 Alluxio 相似於 Spark的計算框架。 你但願下次看到那些內容,和哪些對你有幫助,能夠電郵告訴咱們: blogs@alluxio.com

相關文章
相關標籤/搜索