• 0

    Spark的速度快是以喪失計算結果正確性為代價的

    n5em 9年前發布 | 21K 次閱讀 Spark

    是的,Spark很快。但是它不保證它算出的值是對的,哪怕你要做的只是簡單的整數累加。

    Spark最著名的一篇論文是:《Spark: Cluster Computing with Working Sets》。當你讀它的時候你需要明白:文中代碼不保證計算結果是正確的。具體來說,它的Logistic Regression的代碼在map階段用到了accumulator。下面解釋為什么這么做是錯誤的。

    假設有這樣一個簡單的任務:

    input file的每一行是100個整數,要求豎著加下來

    例如:

    輸入

    1 2 3 4 5 ... 100
    1 2 3 4 5 ... 200
    1 3 3 4 5 ... 100

    輸出

    3 7 9 12 15 ... 400

    很簡單,對吧?是個豬都會算。 在hadoop上這個問題可以通過Map reduce來解決。首先把輸入文件分成N個大小相等的塊。然后每個塊輸出一行100個整數,如 2 4 6 8 10 ... 200
    然后reducer接收每個mapper的輸出結果,累加起來得到最終結果。

    缺點是: 從mapper到reducer是需要DISK-IO及網絡傳輸的。那么需要傳輸N*100個整數。當輸入集的維數很大(每行有上百萬個字節)的時候,很浪費。

    spark很巧妙的引入了accumulator的概念。同一臺機器上所有的task的輸出,會先在這個機器上進行本地匯總,然后再發給 reducer。這樣就不再是task數量*維數,而是機器數量*維數。會節省不少。具體來說,在做機器學習的時候,大家很習慣的用 accumulator來做這樣的計算。

    accumulator是被很careful設計的。比如,只有master節點能讀取accumulator的值,worker節點不能。在“Performance and Scalability of Broadcast in Spark
    ”一文中,作者寫到:“Accumulators can be defined for any type that has an “add” operation and a “zero” value. Due to their “add-only” semantics, they are easy to make fault-tolerant.” 。但真的是這樣嗎?并不是。

    accumulator如果不是運行在運算的最后一環,那么正確性無法保證。因為accumulator不是map/reduce函數的輸入或輸出,accumulator是表達式求值中的side-effect。舉個例子:

    val acc = sc.accumulator(0)  
    data.map(x => acc += 1; f(x))  
    data.count()  
    // acc should equal data.count() here
    data.foreach{...}  
    // Now, acc = 2 * data.count() because the map() was recomputed. 

    這個問題被spark的創始人Matei標為Won't Fix。

    那么是不是寫代碼小心點不要觸發重復計算就行了呢?也不是。task是有可能fail-retry的,再或者因為某一個task執行的慢,所以同時 有它的多個副本在跑。這些都可能會導致accumulator結果不正確。 Accumulators只能用在RDD的actions中,不能用在Transformations。舉例來說:可以在reduce函數中用,但是不能 在map函數中用。

    如果不用accumlators,但又想節省網絡傳輸,那么Matei說:“I would suggest creating fewer tasks. If your input file has a lot of blocks and hence a lot of parallel tasks, you can use CoalescedRDD to create an RDD with fewer blocks from it. ”

    意思就是說,那你就把task劃分大一點,把task的數量減少。比如每臺機器只有1個task。 Downside其實也很明顯,任務的執行容易不balance。

    參考: https://issues.apache.org/jira/browse/SPARK-732
    https://issues.apache.org/jira/browse/SPARK-3628
    https://issues.apache.org/jira/browse/SPARK-5490

    https://github.com/apache/spark/pull/228

    </section>來自:http://www.sunchangming.com/blog/post/4672.html

     本文由用戶 n5em 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
     轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
     本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!
  • sesese色