以非技术方式解释(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)


分享到:


相關文章: