【发布时间】:2015-11-29 14:57:15
【问题描述】:
我正在评估 Spark SQL 以实现一个简单的报告模块(很少对已经存储在 HDFS 上的 Avro 数据进行简单聚合)。我毫不怀疑 Spark SQL 可以很好地满足我的功能性和非功能性需求。
但是,除了生产要求之外,我还想确保该模块是可测试的。我们采用 BDD 方法,场景非常集中,这意味着该模块将需要对一些非常简单的数据(1..10 条记录)运行数十/数百个 SQL 查询。
为了大致了解本地模式下 Spark SQL 的性能,我快速构建了一些测试原型:
select count(*) from myTableselect key, count(*) from myTable group by key
第一个测试平均需要 100 毫秒,但第二个测试需要 500 毫秒。这样的性能是不可接受的,这会使测试套件变得太慢。
为了比较,我可以使用 Crunch 及其 MemPipeline 在 10 毫秒内运行相同的测试(在本地模式下使用 MRPipeline 为 1500 毫秒),在嵌入式模式下使用 Hive 也可以在 1500 毫秒内运行。因此,Spark SQL 在本地模式下比 MR 快一点,但在构建良好的测试套件方面仍然很慢。
是否可以在本地模式下加速 Spark SQL?
是否有更好/更快的方法来测试 Spark SQL 模块?
(我还没有分析执行,但是由于 RDD 上的 groupBy().countByKey() 平均需要 40 毫秒,我希望发现罪魁祸首是查询优化器)
我的快速而肮脏的测试代码如下:
SparkConf sparkConf = new SparkConf()
.setMaster("local[4]")
.setAppName("poc-sparksql");
try (JavaSparkContext ctx = new JavaSparkContext(sparkConf)) {
SQLContext sqlCtx = new SQLContext(ctx);
for (int i = 0; i < ITERATIONS; i++) {
Stopwatch testCaseSw = new Stopwatch().start();
DataFrame df = sqlCtx.load("/tmp/test.avro", "com.databricks.spark.avro");
df.registerTempTable("myTable");
DataFrame result = sqlCtx.sql("select count(*) from myTable");
System.out.println("Results: " + result.collectAsList());
System.out.println("Elapsed: " + testCaseSw.elapsedMillis());
}
for (int i = 0; i < ITERATIONS; i++) {
Stopwatch testCaseSw = new Stopwatch().start();
DataFrame df = sqlCtx.load("/tmp/test.avro", "com.databricks.spark.avro");
df.registerTempTable("myTable");
DataFrame result = sqlCtx.sql("select a, count(*) from myTable group by a ");
System.out.println("Results: " + result.collectAsList());
System.out.println("Elapsed: " + testCaseSw.elapsedMillis());
}
}
【问题讨论】:
-
你考虑过缓存吗?
-
如果你在同一数据上测试不同的查询,加载数据一次..然后查询..
-
根据我的测试,缓存没有帮助(sql 调用很慢)。我更多地考虑的是能够禁用一些优化。我不认为缓存是一种解决方案,因为 1-“好”测试的输入旨在使给定行为易于理解,因此每个测试都有不同的输入。我提供的草率代码并没有试图模仿测试套件会做什么(小黄瓜表的自动 Avro 序列化等) 2-如果输入始终相同,则 SQL 查询是确定性的,然后我缓存了收集的输出数据而不是输入
-
已经一年了,但您是否真的找到了使用 .sql() 的慢速测试的解决方案?如果是这样,你能和我们分享一下吗?在我的本地环境中,spark 的初始初始化已经花费了大约 20 秒,但它的测试一直在花费(3 分钟)。
-
Apache Crunch 仍然非常适合我们所做的大多数事情,并决定坚持下去。编写一些额外的代码似乎比了解如何使用 Spark 及其“仅廉价集成测试”设计编写好的测试套件更好。不过,我仍然对这个话题感兴趣。
标签: unit-testing testing apache-spark apache-spark-sql