Spark 和 Drill 之间的等效配置是什么?

What is the equivalent configuration between Spark and Drill?

我想比较一下Spark和Drill的查询性能。因此,这两个系统的配置必须相同。我必须考虑哪些参数,例如 driver memoryexecutor memory 用于 spark,drill max direct memoryplanner memory max query memory per node 用于 Drill 等?有人可以给我一个配置示例吗?

对于特定的重叠用例,可以在 Spark 和 Drill 之间进行密切比较。我将首先描述 Spark 和 Drill 的不同之处,重叠的用例是什么,最后是如何调整 Spark 的内存设置以尽可能匹配 Drill 重叠的用例。

功能比较

Spark 和 Drill 都可以用作 SQL 计算引擎。我对 SQL 计算引擎 的定义是一个可以执行以下操作的系统:

  • 从文件、数据库或消息队列中提取数据。
  • 对提取的数据执行用户提供的 SQL 语句。
  • 将用户 SQL 语句的结果写入终端、文件、数据库 table 或消息队列。

Drill 只是一个SQL计算引擎,而Spark可以做的不仅仅是SQL 计算引擎。 Spark 可以做的额外事情如下:

  • Spark 具有通过函数式编程操作来操作数据的 API,而不仅仅是 SQL。
  • Spark 可以将操作结果保存到数据集。数据集可以在其他操作中有效地重用,并且可以有效地缓存在磁盘和内存中。
  • Spark 有一些流处理概念 API。

因此,要准确比较 Drill 和 Spark,您只能考虑它们重叠的功能,即执行 SQL 语句。

节点比较

运行ning Spark 作业由两种类型的节点组成。一个 Executor 和一个 DriverExecutor 就像一个工作节点,它被赋予简单的计算任务并执行它们。 Driver 编排 Spark 作业。例如,如果您有一个 SQL 查询或一个用 Python 编写的 Spark 作业,Driver 负责规划 SQL 的工作方式查询或 python 脚本将分发给 执行器 。然后 Driver 将监视 Executors 正在完成的工作。 驱动程序可以运行多种模式:在您的笔记本电脑上作为客户端,在单独的专用节点或容器上。

演习略有不同。 SQL 查询中的两个参与者是 ClientDrillbitClient 本质上是一个虚拟命令行终端,用于发送 SQL 命令和接收结果。 Drillbits 负责执行查询的计算工作。当 Client 向 Drill 发送 SQL 命令时,客户端将选择一个 Drillbit 作为 Foreman。对于哪个 Drillbit 可以是工头没有限制,并且可以为每个查询选择不同的 ForemanForeman 在查询期间执行两个功能:

  1. 他计划查询并协调其余的 Drillbits 来分配工作。
  2. 他还参与了查询的执行,并进行了一些数据处理。

Spark的DriverExecutors的功能与Drill的Drillbit工头但不完全一样。主要区别在于 Driver 不能同时充当 Executor,而 Foreman 也充当 Foreman一个 钻头.

在构建比较 Spark 和 Drill 的集群时,我会执行以下操作:

  • 钻取:创建一个有N个节点的集群。
  • Spark:创建一个有N个Executors的集群,确保Driver和Executors拥有相同的内存。

内存模型比较

Spark 和 Drill 都使用 JVM。 JVM 上的应用程序 运行ning 可以访问两种内存。 堆内存堆内存。堆上内存是正常的垃圾回收内存;例如,如果你做 new Object() 对象将被分配到堆上。堆外内存不会被垃圾回收,必须显式分配和释放。当应用程序消耗大量堆内存(16 GB 或更多)时,它们可以向 JVM 垃圾收集器征税。在这种情况下,垃圾收集会产生大量计算开销,并且根据 GC 算法,计算可能会在垃圾收集完成后暂停几秒钟。相比之下,堆外内存不受垃圾收集的影响,不会招致这些性能损失。

Spark 默认情况下将所有内容存储在堆上。它可以配置为将一些数据存储在堆外内存中,但我不清楚它何时真正将数据存储在堆外。

Drill 将其所有数据存储在堆外内存中,并且仅将堆内存用于通用引擎本身。

另一个区别是 Spark 保留了一些内存来缓存数据集,而 Drill 在执行查询后不会在内存中缓存数据。

为了比较 Spark 和 Drill 的优缺点,我们必须将 Spark 和 Drill 配置为使用相同数量的堆外和堆上内存来执行 SQL 查询。在下面的示例中,我们将介绍如何配置 Drill 和 spark 以使用 8gb 的堆上内存和 8gb 的堆外内存。

Drill 内存配置示例

在每个 Drillbitdrill-env.sh 文件中设置以下内容

export DRILL_HEAP="8G"  
export DRILL_MAX_DIRECT_MEMORY="8G"

配置完成后,重新启动您的 Drillbits 并尝试您的查询。您的查询可能 运行 内存不足,因为 Drill 的内存管理仍在积极开发中。为了给你一个答案,你可以使用 planner.width.max_per_nodeplanner.memory.max_query_memory_per_node 通过查询手动控制 Drill 的内存使用选项。这些选项在您的 drill-override.conf 中设置。请注意,您必须在所有节点上更改这些选项并重新启动 Drillbits 才能使它们生效。可以找到这些选项的更详细解释 here.

Spark 内存配置示例

创建属性文件myspark.conf并将其传递给spark submit 命令。 spark 属性文件应包含以下配置。

# 8gb of heap memory for executor
spark.executor.memory            8g
# 8gb of heap memory for driver
spark.driver.memory              8g
# Enable off heap memory and use 8gb of it
spark.memory.offHeap.enabled     true
spark.memory.offHeap.size        8000000000
# Do not set aside memory for caching data frames
# Haven't tested if 0.0 works. If it doesn't make this
# as small as possible
spark.memory.storageFraction     0.0

总结

创建N个节点的Drill集群,N个执行器的Spark集群,部署专用驱动,尝试上面提供的内存配置,运行相同或相似的SQL查询两个集群。希望这有帮助。