以非技術方式解釋(Py)Spark

什麼是Spark和PySpark

以非技術方式解釋(Py)Spark

> Photo by Markus Spiske on Unsplash

在Baskerville Analytics System的演示中曾有人問我,向根本不是技術人員的人解釋Apache Spark。 這讓我感到困惑,因為我非常習慣於用代碼進行思考和討論,而且我的腦子一直在回頭用技術術語,所以我相信我在有限的時間內做得並不出色。 為了一個人問我,讓我們再嘗試一次,因為我認為儘可能簡單地解釋事物是一種很好的發展技巧。

旁註:速記

我一直在閱讀克里斯蒂娜·R·沃特克(Christina R Wodtke)撰寫的《鉛筆我》(Pencil Me In),它講述了Sketchnoting,即保留視覺筆記以幫助理解和記憶的過程。 我一直是一個有視覺見識的人,並在整個童年時代經常塗鴉,這確實幫助我更好地記住了事情,有時還使我陷入麻煩。 而且,由於我在Medium上寫作的整個過程是為了更好地理解我認為的知識,並學習新知識,所以我想我會再嘗試一次。 自從我上次這樣做以來已經有很長的時間了,現在我已經習慣了打字而不是寫作(翻譯:即將出現可怕的草圖!),所以請寬容。

不可能的作業

我想要做的第一件事就是提供一個任何人或幾乎任何人都可以關聯的示例。 因此,假設您要在一週內完成作業,而您要做的就是讀一本非常大的書,長7K頁,並記下作者使用"大數據"一詞的次數,理想情況下還保留包含它的短語(任務艱鉅,但請耐心:))。

以非技術方式解釋(Py)Spark

> The "impossible" homework

考慮到時間的限制,這是一項不可能完成的任務,即使您日夜閱讀,一週之內也無法完成。 但是,您並不孤單,因此您決定與同學和朋友交談並找出解決方案。

拆分頁面似乎很合邏輯,每個人至少要照顧幾個頁面。 每個人都帶回家閱讀的頁面,具有相關內容的內容也很有意義,因此您將要閱讀的內容也很有意義,因此您嘗試按章節進行拆分。

看起來也需要協調員。 假設您要執行此任務,因為這是您的想法。 (理想情況下,您自己會佔用一兩個章節,但是假設管理和溝通將佔用您的大部分時間)

以非技術方式解釋(Py)Spark

> Help each other!

要考慮的另一件事是,根據誰有最多的時間,誰是快速的閱讀器或速度較慢的閱讀器來拆分頁面,以使過程儘可能高效,對嗎? 另外,你們中的某些人可能會在一週內完成其他作業,因此也必須考慮到這一點。

以非技術方式解釋(Py)Spark

> Communicate with each other, know the availability and distribute work accordingly

在整個一週中,最好與同學交談以檢查並查看他們的情況。 當然,由於將無法一次性閱讀各章,因此請使用書籤來記錄您的進度並跟蹤任務的執行情況

以非技術方式解釋(Py)Spark

> Bookmark, keep track and redistribute work in case of failure

如果您必須數個以上的期限怎麼辦? 頁面的拆分可能應根據各章的標題以及該章包含這些術語的可能性進行。 如果發生了什麼而你們中的一個無法完成任務怎麼辦? 相應的頁面應該重新分配給您的其餘部分,最好取決於您每個人還剩下多少頁。

最後,你們都將收集並累加計數以得到結果。

因此,總而言之,要解決此任務,有意義的是:

· 在同學之間分割章節

· 您是否已經組織好事情,因為這是您的主意,並且您知道事情應該如何進行

· 根據每個學生的能力劃分章節-考慮閱讀速度和可用性

· 如果發生某些事情並且一個人無法完成自己的工作,請重新分配工作

· 跟蹤進展情況-使用書籤,與同學交談以跟蹤進度,等等。

· 最後聚集在一起分享和合並結果


這與Spark和PySpark有何關係-變得更具技術性

據我瞭解,該作業示例說明了Apache Spark(以及許多類似的框架和系統,例如水平或垂直數據"分片")背後過於簡化的基本思想,將數據分為合理的組(在Spark的存儲系統中稱為"分區")。情況),因為您知道必須對數據執行什麼樣的任務才能使您高效,並將這些分區分配給理想數量的工作人員(或系統可以提供的儘可能多的工作人員)。這些工人可以在同一臺機器上,也可以在不同的機器上,例如一臺機器(節點)上的每個工作人員。必須有所有這些工作的協調者,以收集執行任務所需的所有必要信息,並在出現故障的情況下重新分配負載。還必須在協調員和工作人員之間建立(網絡)連接,以交流和交換數據和信息。甚至在發生故障或計算需要時對數據進行重新分區(例如,我們需要在數據的每一行中獨立計算某些內容,然後再通過鍵對這些行進行分組)。還有一種以"惰性"方式處理事務的概念,並使用緩存來跟蹤中間結果,而不必一直從頭開始計算所有內容。

PySpark是Apache Spark的python實現,Apache Spark是"用於大規模數據處理的統一分析引擎"。

請注意,這並不是與Spark組件進行精確的一對一的比較,但是從概念上講,這是一個緊密的比較。 為了簡單起見,我還省略了許多Spark內部結構。 如果您想對此進行更深入的研究,可以從Apache Spark官方站點開始獲得大量資源。

以非技術方式解釋(Py)Spark

> Comparison with Spark

我提到的上一張圖像中描述的比較不是很準確。 讓我們再試一次,讓老師也參與其中。 老師是提供家庭作業和說明(駕駛員程序)的人,學生分為工作組,每個工作組都可以完成一部分任務。 為了簡潔起見,並且為了使我的圖紙不那麼複雜,使我的生活更輕鬆,下圖顯示了一個工作組與Spark的比較。 我覺得這與Spark應用程序運行時實際發生的情況有些接近。

以非技術方式解釋(Py)Spark

> Perhaps a better comparison with Spark

用簡單的技術術語來說,假設您的計算機上有一個巨大的文本文件(雖然不是大數據文件,但有一個15GB的文件),您真的想知道有多少個單詞,或者, 作為上面的作業,"大數據"一詞在其中出現了多少次,以及相關的用語,您將面臨以下問題:

· 您實際上無法使用記事本打開此文件,因為即使您有32GB的RAM,用於打開和編輯文本文件的應用程序實際上也無法使用15GB的文件。

· 您可以編寫一些代碼來對該文件中的單詞或特定單詞或短語進行計數,方法是逐行讀取或使用諸如wc之類的代碼,具體取決於您的系統,但這會很慢,非常慢。 如果您需要做更復雜的事情怎麼辦?

因此,我們立即發現沒有快速簡便的方法可以處理大文件的簡單事情,更不用說複雜的事情了。

大家可以想到幾種解決方法,例如將大型文件拆分為多個小文件,然後處理這些小文件,然後使用多處理技術將結果相加。 這就是Spark來提供此問題的簡單解決方案的地方。 我們來看一個使用pyspark的python庫的非常基本的PySpark示例。

<code>from pyspark import SparkConf
from pyspark.sql import SparkSession, functions as F

conf = SparkConf()
# optional but it would be good to set the amount of ram the driver can use to 
# a reasonable (regarding the size of the file we want to read) amount, so that we don't get an OOM exception
conf.set('spark.driver.memory', '6G')

spark = SparkSession.builder \
        .config(conf=conf) \
        .appName('Homework-App') \
        .getOrCreate()

df = spark.read.text('full/path/to/file.txt)
df =  df.withColumn('has_big_data', F.when(F.col('value').contains('big data'), True).otherwise(False))
result = df.select('value').where(F.col('has_big_data')==True).count()/<code>

看起來很簡單,不是嗎? 僅幾行Python代碼。 現在,讓我們解釋一下它的作用:

<code>from pyspark import SparkConf
from pyspark.sql import SparkSession, functions as F

conf = SparkConf()
# optional but it would be good to set the amount of ram the driver can use to 
# a reasonable (regarding the size of the file we want to read) amount, so that we don't get an OOM exception
conf.set('spark.driver.memory', '6G')

# create a spark session - nothing can be done without this:
spark = SparkSession.builder \
        .config(conf=conf) \
        .appName('Homework-App') \
        .getOrCreate()

# spark.read.text returns a dataframe, which is easier to manipulate and also more efficient
# you can also use: spark.sparkContext.textFile('') but that will return RDD[String]
df = spark.read.text('full/path/to/file.txt)

# spark is "lazy" so, nothing has happened so far, besides the initialization of the session
# let's call .show() to see that we've actually read the file and what it looks like
df.show()

+--------------------+
|               value|
+--------------------+
|                   1|
|                    |
|              Spark |
|The Definitive Guide|
|Excerpts from the...|
|big data simple w...|
|                    |
|By Bill Chambers ...|
|                    |
|http://databricks...|
|http://databricks...|
|                    |
|                    |
|Apache Spark has ...|
|several years. Th...|
|a true reflection...|
|made itself into ...|
|is proud to share...|
|Spark: The Defini...|
|courtesy of Datab...|
+--------------------+
only showing top 20 rows

# Now let's get back to the task: identify where `big data` is used. 
# For this task, we add a column to the dataframe and populate it with True when `big data` is identified in a row
df =  df.withColumn('has_big_data', F.when(F.col('value').contains('big data'), True).otherwise(False))
df.show()
+--------------------+------------+
|               value|has_big_data|
+--------------------+------------+
|                   1|       false|
|                    |       false|
|              Spark |       false|
|The Definitive Guide|       false|
|Excerpts from the...|       false|
|big data simple w...|        true|
|                    |       false|
|By Bill Chambers ...|       false|
|                    |       false|
|http://databricks...|       false|
|http://databricks...|       false|
|                    |       false|
|                    |       false|
|Apache Spark has ...|       false|
|several years. Th...|       false|
|a true reflection...|       false|
|made itself into ...|       false|
|is proud to share...|       false|
|Spark: The Defini...|       false|
|courtesy of Datab...|       false|
+--------------------+------------+
only showing top 20 rows

# and the answer to the homework is to select the rows where the 'has_big_data' column is True
df.select('value').where(F.col('has_big_data')==True).show()
+--------------------+
|               value|
+--------------------+
|big data simple w...|
|In the previous e...|
|of functions that...|
|and genomics have...|
|This part of the ...|
|When working with...|
+--------------------+

df.select('value').where(F.col('has_big_data')==True).count()
# 6 - the number of rows that contain this term

# just to see that `big data` is indeed included in these few rows :)
df.select('value').where(F.col('has_big_data')==True).show(100, False)
+----------------------------------------------------------------------------------------------------------------------+
|value                                                                                                                 |
+----------------------------------------------------------------------------------------------------------------------+
|big data simple with Apache Spark.                                                                                    |
|In the previous example, we created a DataFrame of a range of numbers. Not exactly groundbreaking big data. In        |
|of functions that you can leverage and import to help you resolve your big data problems faster. We will use the max  |
|and genomics have seen a particularly large surge in opportunity for big data applications. For example, the ADAM     |
|This part of the book will cover all the core ideas behind the Structured APIs and how to apply them to your big data |
|When working with big data, the second most common task you will do after filtering things is counting things. For    |
+----------------------------------------------------------------------------------------------------------------------+
         /<code>

沒有明顯的文件拆分成"章節",沒有協調,沒有跟蹤,什麼也沒有。 那是因為Spark會處理所有幕後的複雜性,而我們不必擔心告訴工作人員和執行者讀取文件的一部分或如何拆分文件,或者如果執行者突然放棄其部分會發生什麼,等等。 上。 因此,在這裡,我們僅用幾行代碼就完成了作業。

別誤會,Spark看起來很簡單,但背後隱藏著許多複雜性,而對它進行故障排除根本不是一件容易的事,但是,讓我們暫時欣賞一下這些好地方,稍後我們將討論這些困難。

此外,這裡的示例是最簡單的示例之一,但是我相信,一旦您瞭解了此類框架背後的機制和邏輯,就會更容易掌握您可以做什麼,更重要的是,您不能使用它們,如何進行結構化 利用這些框架並擅長估算以某種方式執行操作是否會快速有效的系統。 同樣,保持簡單,我現在將不再進一步詳細介紹。

我希望這可以幫到你。 任何想法,問題,更正和建議都非常歡迎:)


(本文翻譯自Maria Karanasou的文章《On explaining technical stuff in a non-technical way — (Py)Spark》,參考:https://towardsdatascience.com/explaining-technical-stuff-in-a-non-techincal-way-apache-spark-274d6c9f70e9)


分享到:


相關文章: