Jay*_*ati 2 apache-spark apache-spark-sql
我正在尝试使用数据源MySQL的Apache spark.我有一个拥有1个主节点和1个从节点的集群,它们都有8 GB内存和2个内核我使用spark-shell将该SQL查询提交给spark,而该表有6402821这么多行.我正在那张桌子上表演一个小组.并采取时间MySQL是5.2secs使用火花当我执行查询的时间21Secs.为什么会这样?
我也设置了一些配置,如partitionColumn,upperBound,lowerBound和numofPartitions,但仍然没有变化.
我也试过使用1,2,4核执行查询,但是火花所花费的时间是21Secs.
出现这个问题是因为我的MySQL数据库是在一台机器上而且所有的火花节点都试图在这台机器上查询数据?
任何人都可以帮我解决这个问题吗?
我想要查询的数据库有一个名为demo_call_stats的表是:
val jdbcDF = spark.read.format("jdbc").options( Map("url" -> "jdbc:mysql://192.168.0.31:3306/cmanalytics?user=root&password=","zeroDateTimeBehaviour"->"convertToNull", "dbtable" -> "cmanalytics.demo_call_stats", "fetchSize" -> "10000", "partitionColumn" -> "newpartition", "lowerBound" -> "0", "upperBound" -> "4", "numPartitions" -> "4")).load()
jdbcDF.createOrReplaceTempView("call_stats")
val sqlDF = sql("select Count(*), classification_id from call_stats where campaign_id = 77 group by classification_id")
sqlDF.show()
Run Code Online (Sandbox Code Playgroud)
任何帮助将非常感谢.
谢谢
Fur*_*ine 21
你应该在这里理解一些事情:
尽管你可能听说过,但Spark并不比"比MySQL更快",只是因为这种普遍性并不意味着什么.对于某些查询,Spark比MySQL更快,而对于其他查询,MySQL比Spark更快.一般来说,MySQL是一个关系数据库,这意味着它被认为是一个应用程序的后端.只要将索引编入索引,它就会进行优化以有效地访问记录.
在考虑数据库时,我喜欢将它们视为一个图书管理员的图书馆,以帮助您获得所需的书籍(我在这里谈论一个非常古老的学校图书馆,没有任何计算机来帮助图书管理员).
如果你问你的图书管理员: "我想知道你有多少关于地缘政治的书籍",图书管理员可以去地缘政治书架并计算该书架上的书籍数量.
如果你问你的图书管理员: "我想知道你有多少本书,至少有500页",图书管理员将不得不查看图书馆里的每本书来回答你的问题.在SQL中,这称为全表扫描.当然,你可以让几个图书管理员(处理器)处理查询以加快速度,但你的库(计算机)里面不能有多个(比方说多达16个).
现在,Spark已被设计用于处理大量数据,即图书馆如此之大,以至于它们不适合单个建筑物,即使如此,它们也会如此之多,即使是16位图书馆员也需要数天时间才能看到他们都回答你的第二个问题.
是什么让Spark比MySQL更快就是这样:如果你把你的书放在几栋建筑物中,你可以让每个建筑物里有16名图书管理员来处理你的答案.您还可以处理大量图书.
此外,由于Spark主要是为了回答第二类查询,而不是像"请带我去多利安·格雷的肖像",奥斯卡·王尔德这样的问题,"这意味着Spark至少在默认情况下并不关心以任何特定方式对您的书进行排序.这意味着如果你想找到带有spark的特定书籍,你的图书馆员将不得不通过整个图书馆找到它.
当然,Spark使用许多其他类型的优化来更有效地执行某些查询,但索引不是其中之一(如果您熟悉mySQL中的主键概念,那么Spark中就没有这样的东西).其他优化包括Parquet和ORC等存储格式,允许您只读取有助于回答查询的列和压缩(例如Snappy),这些列旨在增加您可以放入库中的书籍数量,而无需推墙.
我希望这个比喻对你有所帮助,但请记住,这只是一个隐喻,并不完全适合现实.
现在,回到您的问题具体细节:
假设campaign_id您是主键或者您在此列上创建了索引,MySQL只需读取其中的行campaign_id = 77.另一方面,Spark必须要求mySQL将该表中的所有行发送给Spark.如果Spark很聪明,它只会询问一个campaign_id = 77,并且它可能会向mySQL发送多个查询以获得并行的范围.但这意味着MySQL只能读取和聚合的所有数据都必须序列化,发送到Spark,并由Spark聚合.我希望你明白为什么这需要更长的时间.
如果您希望Spark比MySQL更快地回答您的查询,您应该尝试以另一种格式复制您的表格.
// replace this line :
// jdbcDF.createOrReplaceTempView("call_stats")
// with :
jdbcDF.write.format("orc").saveAsTable("call_stats")
Run Code Online (Sandbox Code Playgroud)
您可以尝试的另一件事是缓存您的数据,如下所示:
jdbcDF.cache().createOrReplaceTempView("call_stats")
Run Code Online (Sandbox Code Playgroud)
缓存不会为第一个查询带来任何改进,因为它会在执行时缓存数据,但如果继续查询相同的视图,它可能会更快.但正如我上面解释的那样,这并不意味着Spark会比mySQL更快.
对于小型数据和本地部署,您还可以通过更改此配置参数来获得性能改进:spark.sql.shuffle.partitions=4默认情况下为200.
希望这可以帮助.
| 归档时间: |
|
| 查看次数: |
2272 次 |
| 最近记录: |