apache spark
SQL已有一段时间了,人们喜欢它。 但是,支持SQL的引擎已经随着时间而改变,以解决新问题并满足消费者的需求。
诸如Microsoft SQL Server之类的传统引擎在可伸缩性方面存在一些问题,这些问题已通过基于时间和基于云的解决方案得以解决。 另一方面,其他组件是从头开始构建的,可以在分布式环境中工作,因此他们可以将性能放在其优先级列表的顶部。
没有适用于所有用例的工具。 实际上,我们认为工具是在考虑用例的情况下构建的,可以解决特定问题。 然后,它们发展到更成熟的阶段,可以用来解决许多其他问题。
在传统SQL环境中,数据由表及其之间的关系表示,但有时这种表示还不够,因此已经开发了新的工具来解决此问题。 我们到处都可以找到不使用关系数据库的组织。 相反,他们更喜欢使用非SQL的。
Hadoop的
在Hadoop的世界中,我们有各种各样的查询引擎。 他们每个人都有自己的特殊性,他们各自解决各种各样的问题。
在任何Hadoop发行版中,我们都可以找到Apache Hive ,这是一种类似SQL的工具,可提供数据仓库基础结构以及用于大数据查询和分析的功能。
根据Hadoop发行版,我们还可以找到Apache Impala和Apache Drill 。 它们都或多或少提供相同的功能,并具有共同的目标。 我们可以使用SQL或类似SQL的语言来查询存储在Hadoop中的数据。 他们也有自己的局限性和优势,您应该意识到。 这里是有关这些技术的更多详细信息的链接。
Apache Spark
Apache Spark是一种闪电般的集群计算,可以部署在Hadoop集群或独立模式下。 像我们提到的其他引擎一样,它也可以用作SQL引擎。 但是,Spark提供了一些优于以前的优点。
Spark公开了针对不同语言(例如Scala,Java,Python和R)的API。这使得许多类型的人都可以访问它,例如开发人员,数据科学家和具有统计经验的人员。
交互式算法很容易在Spark中实现,尤其是机器学习算法。
让我们来看一个如何将Spark用作SQL引擎的示例。
探索我们的数据源
我们的数据集是一个简单的文件夹,在CSV格式的文件中只有几TB,每个文件大约40MB。 文件的大小不影响性能,因为它们存储在MapR群集中。 正如我在这篇文章中所解释的,MapR 解决了Hadoop小文件问题 。
因为我们使用的是MapR,所以将文件复制到集群非常容易,因为我们已经将卷装入了本地文件系统。
为了挂载MapR卷,我们运行以下命令:
sudo mount_nfs -o "hard,nolock" 10.21.112.209:/mapr/mapr.domain.com/datalake /Users/anicolaspp/mapr/
现在,如果我们在本地文件夹中再次运行POSIX命令,它们实际上将在MapR集群中执行。
为自动模式发现准备环境
我们将使用Scala创建一个Spark应用程序,该应用程序将允许我们对存储在MapR Distribution中的数据执行SQL语句。
在这篇文章中,我解释了如何在Spark中创建应用程序以及我们需要遵循的先前步骤。
我们的应用程序类如下所示:
/**
* Created by anicolaspp.
*/
import org.apache.spark
import org.apache.spark._
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.sql.hive.thriftserver.HiveThriftServer2
import org.apache.spark.sql.{Row, SQLContext}
import org.apache.spark.sql.types.{StringType, StructField, StructType}
object app {
def main(args: Array[String]) {
val conf = new SparkConf().setAppName("testing")
val sc = new SparkContext(conf)
val sql = new HiveContext(sc)
sql.setConf("hive.server2.thrift.port", "10001")
val delimiter = "\t"
val data = sc.textFile("datalake/myTestDataFolder/")
val headers = data.first.split(delimiter)
val schema = StructType(headers.map(h => StructField(h, StringType)))
val rowRDD = data.map(p => Row.fromSeq(p.split(delimiter)))
>
val dataFrame = sql.createDataFrame(rowRDD, schema)
dataFrame.registerTempTable("someTableName")
HiveThriftServer2.startWithContext(sql)
while (true) {
Thread.`yield`()
}
}
}
让我们回顾一下我们的代码。
首先,我们基于Config对象创建Spark Context。
val conf = new SparkConf().setAppName("testing")
val sc = new SparkContext(conf)
val sql = new HiveContext(sc)
然后,我们设置节流端口以避免与Hive等其他组件发生冲突。
sql.setConf("hive.server2.thrift.port", "10001")
现在,我们设置CSV分隔符,在这种情况下为制表符。 我们还通过使用Spark上下文(sc)创建弹性分布式数据集(RDD)来设置数据集的位置。
val delimiter = "\t"
val data = sc.textFile("datalake/myTestDataFolder/")
在这一点上,我们希望能够为我们的数据提供服务而不必担心我们的文件模式; 我们想要一个自助服务BI环境,如我在此处所述 。 使用数据文件中的标头,我们可以自动创建模式,因此我们不必担心将来的模式更改。 有了模式后,我们将创建一个数据框架,该框架将公开以使用SQL查询。
val headers = data.first.split(delimiter)
val schema = StructType(headers.map(h => StructField(h, StringType)))
val rowRDD = data.map(p => Row.fromSeq(p.split(delimiter)))
val dataFrame = sql.createDataFrame(rowRDD, schema)
唯一缺少的部分是将我们的数据集注册为Hive元存储中的表的部分。 我们这样做是:
dataFrame.registerTempTable("someTableName")
HiveThriftServer2.startWithContext(sql)
我们有一个循环来保持我们的应用程序正常运行。 请注意,RDD转换是惰性的,只有在提交查询以执行时才执行。
部署我们的应用程序
我们使用SBT构建和测试我们的应用程序,并且可以将.jar文件复制到集群中,就像复制本地文件系统中的文件一样。
cp pathToOurJar/app.jar /Users/anicolaspp/mapr/testing
请记住,这是可能的,因为我们之前已经在本地文件系统中挂载了MapR卷。
现在,我们需要在集群中提交我们的应用程序,并使用spark-submit命令来完成。 可以在Spark网站上找到有关提交Spark应用程序的详细文档。
在我们的集群中,我们运行:
/spark-submit --master yarn /mapr/mapr.domain.com/datalake/testing/testing_2.10-1.0.jar
如提交时所示,我们的应用程序应开始在YARN上运行。
我们SQL引擎已准备好进行查询,因此让我们继续进行测试。
SQL客户端
测试我们SQL引擎的一种简单方法是运行beeline (一种作为SQL客户端的命令行工具)。
我们可以在Spark bin文件夹中找到beeline。 要启动它,我们输入./beeline。
在beeline中,我们需要连接到我们在应用程序中定义的端点,因此我们运行:
!connect jdbc:hive2://localhost:10001
我们应该已经准备好运行SQL语句,但是让我们验证一下我们可以看到我们注册的表。
show tables;
Spark SQL将返回一个包含已注册表的表,其中包括我们在应用程序中注册的表(someTableName)。
同样,我们可以使用其他客户端(例如Microstrategy或Tableau)进行连接。 我们都尝试过,它们都可以在Spark应用程序注册的表上构建和执行查询。 我们还可以组合不同的源(Spark SQL,MS SQL Server,Hive,Impala等),这使我们可以灵活地将关系源与非关系数据相结合。
Spark SQL的性能相当好,并且通常比Hadoop中的其他提供程序更好,但是请注意,在某些条件和用例下性能可能会下降。
为什么选择Apache Spark
当然,Spark SQL提供了Hadoop中其他工具所具有的某些功能。 但是,由于我们可以在应用程序中编码自定义序列化/反序列化过程,因此有可能探索Spark特有的复杂数据集。 使用Spark SQL,我们可以连接到任何数据源,并将其显示为要由SQL客户端使用的表。 这就像通过更改应用程序中的序列化器来更改如何准备这些源中的数据一样容易。
结局
我们可以在Hadoop中使用非常有用的工具以SQL方式查询数据,并且它们都有其优势。 Apache Spark的Spark SQL模块提供了一些其他灵活性所缺乏的灵活性,同时将性能作为主要优先事项之一。
Spark不是您可以使用的唯一工具,但是我们强烈建议您将其包含在要执行SQL语句的大数据解决方案中。 您可能需要使用多种不同的工具,但是Spark应该是所构建系统的重要组成部分。
翻译自: https://www.javacodegeeks.com/2016/03/apache-spark-distributed-sql-engine.html
apache spark