This is an automated email from the ASF dual-hosted git repository.
zhouky pushed a commit to branch branch-0.4
in repository https://gitbox.apache.org/repos/asf/incubator-celeborn.git
The following commit(s) were added to refs/heads/branch-0.4 by this push:
new ef6eabb00 [CELEBORN-1300] Optimize CelebornInputStreamImpl's memory
usage
ef6eabb00 is described below
commit ef6eabb00e6fe020eee111bb817d920e58ba699c
Author: zky.zhoukeyong <[email protected]>
AuthorDate: Tue Mar 5 14:03:11 2024 +0800
[CELEBORN-1300] Optimize CelebornInputStreamImpl's memory usage
### What changes were proposed in this pull request?
To avoid too much memory usage when CelebornShuffleReader creates input
streams.
This PR does the following:
1. Constructor of `CelebornInputStream` does not fetch chunk
2. `compressedBuf` and `rawDataBuf` are created first time `fillBuffer` is
called
3. When `fillBuffer` returns false, which means the inputstream is
exhausted, `close` is called and resource released
4. `CelebornFetchFailureSuite` is only run for Spark 3.0 and newer
### Why are the changes needed?
ditto
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
GA and e2e test.
Closes #2348 from waitinfuture/1300.
Lead-authored-by: zky.zhoukeyong <[email protected]>
Co-authored-by: Keyong Zhou <[email protected]>
Signed-off-by: zky.zhoukeyong <[email protected]>
(cherry picked from commit 8b6bc35997a97a4252fc4c95dac4ca0b6d15aba8)
Signed-off-by: zky.zhoukeyong <[email protected]>
---
.../celeborn/client/read/CelebornInputStream.java | 101 +++---
.../tests/spark/CelebornFetchFailureSuite.scala | 346 +++++++++++----------
.../celeborn/tests/spark/SparkTestBase.scala | 5 +
3 files changed, 248 insertions(+), 204 deletions(-)
diff --git
a/client/src/main/java/org/apache/celeborn/client/read/CelebornInputStream.java
b/client/src/main/java/org/apache/celeborn/client/read/CelebornInputStream.java
index 95a5ad5b2..a10239bf5 100644
---
a/client/src/main/java/org/apache/celeborn/client/read/CelebornInputStream.java
+++
b/client/src/main/java/org/apache/celeborn/client/read/CelebornInputStream.java
@@ -124,19 +124,20 @@ public abstract class CelebornInputStream extends
InputStream {
private final CelebornConf conf;
private final TransportClientFactory clientFactory;
private final String shuffleKey;
- private final PartitionLocation[] locations;
- private final int[] attempts;
+ private PartitionLocation[] locations;
+ private int[] attempts;
private final int attemptNumber;
private final int startMapIndex;
private final int endMapIndex;
- private final Map<Integer, Set<Integer>> batchesRead = new HashMap<>();
+ private Map<Integer, Set<Integer>> batchesRead = new HashMap<>();
private byte[] compressedBuf;
private byte[] rawDataBuf;
private Decompressor decompressor;
private ByteBuf currentChunk;
+ private boolean firstChunk = true;
private PartitionReader currentReader;
private final int fetchChunkMaxRetry;
private int fetchChunkRetryCnt = 0;
@@ -159,7 +160,7 @@ public abstract class CelebornInputStream extends
InputStream {
private boolean fetchExcludeWorkerOnFailureEnabled;
private boolean shuffleCompressionEnabled;
private long fetchExcludedWorkerExpireTimeout;
- private final ConcurrentHashMap<String, Long> fetchExcludedWorkers;
+ private ConcurrentHashMap<String, Long> fetchExcludedWorkers;
private boolean containLocalRead = false;
private ShuffleClient shuffleClient;
@@ -167,6 +168,7 @@ public abstract class CelebornInputStream extends
InputStream {
private int shuffleId;
private int partitionId;
private ExceptionMaker exceptionMaker;
+ private boolean closed = false;
CelebornInputStreamImpl(
CelebornConf conf,
@@ -203,16 +205,6 @@ public abstract class CelebornInputStream extends
InputStream {
this.fetchExcludedWorkerExpireTimeout =
conf.clientFetchExcludedWorkerExpireTimeout();
this.fetchExcludedWorkers = fetchExcludedWorkers;
- int bufferSize = conf.clientFetchBufferSize();
- if (shuffleCompressionEnabled) {
- int headerLen = Decompressor.getCompressionHeaderLength(conf);
- bufferSize += headerLen;
- compressedBuf = new byte[bufferSize];
-
- decompressor = Decompressor.getDecompressor(conf);
- }
- rawDataBuf = new byte[bufferSize];
-
if (conf.clientPushReplicateEnabled()) {
fetchChunkMaxRetry = conf.clientFetchMaxRetriesForEachReplica() * 2;
} else {
@@ -228,7 +220,7 @@ public abstract class CelebornInputStream extends
InputStream {
this.shuffleId = shuffleId;
this.shuffleClient = shuffleClient;
- moveToNextReader();
+ moveToNextReader(false);
}
private boolean skipLocation(int startMapIndex, int endMapIndex,
PartitionLocation location) {
@@ -270,7 +262,7 @@ public abstract class CelebornInputStream extends
InputStream {
return currentLocation;
}
- private void moveToNextReader() throws IOException {
+ private void moveToNextReader(boolean fetchChunk) throws IOException {
if (currentReader != null) {
currentReader.close();
currentReader = null;
@@ -291,7 +283,9 @@ public abstract class CelebornInputStream extends
InputStream {
currentReader = createReaderWithRetry(currentLocation);
fileIndex++;
}
- currentChunk = getNextChunk();
+ if (fetchChunk) {
+ currentChunk = getNextChunk();
+ }
}
private void excludeFailedLocation(PartitionLocation location, Exception
e) {
@@ -517,25 +511,40 @@ public abstract class CelebornInputStream extends
InputStream {
}
@Override
- public void close() {
- int locationsCount = locations.length;
- logger.debug(
- "total location count {} read {} skip {}",
- locationsCount,
- locationsCount - skipCount.sum(),
- skipCount.sum());
- if (currentChunk != null) {
- logger.debug("Release chunk {}", currentChunk);
- currentChunk.release();
- currentChunk = null;
- }
- if (currentReader != null) {
- logger.debug("Closing reader");
- currentReader.close();
- currentReader = null;
- }
- if (containLocalRead) {
- ShuffleClient.printReadStats(logger);
+ public synchronized void close() {
+ if (!closed) {
+ int locationsCount = locations.length;
+ logger.debug(
+ "AppShuffleId {}, shuffleId {}, partitionId {}, total location
count {}, read {}, skip {}",
+ appShuffleId,
+ shuffleId,
+ partitionId,
+ locationsCount,
+ locationsCount - skipCount.sum(),
+ skipCount.sum());
+ if (currentChunk != null) {
+ logger.debug("Release chunk {}", currentChunk);
+ currentChunk.release();
+ currentChunk = null;
+ }
+ if (currentReader != null) {
+ logger.debug("Closing reader");
+ currentReader.close();
+ currentReader = null;
+ }
+ if (containLocalRead) {
+ ShuffleClient.printReadStats(logger);
+ }
+
+ compressedBuf = null;
+ rawDataBuf = null;
+ batchesRead = null;
+ locations = null;
+ attempts = null;
+ decompressor = null;
+ fetchExcludedWorkers = null;
+
+ closed = true;
}
}
@@ -548,7 +557,7 @@ public abstract class CelebornInputStream extends
InputStream {
currentChunk = getNextChunk();
return true;
} else if (fileIndex < locations.length) {
- moveToNextReader();
+ moveToNextReader(true);
return currentReader != null;
}
if (currentReader != null) {
@@ -558,9 +567,27 @@ public abstract class CelebornInputStream extends
InputStream {
return false;
}
+ private void init() {
+ int bufferSize = conf.clientFetchBufferSize();
+
+ if (shuffleCompressionEnabled) {
+ int headerLen = Decompressor.getCompressionHeaderLength(conf);
+ bufferSize += headerLen;
+ compressedBuf = new byte[bufferSize];
+ decompressor = Decompressor.getDecompressor(conf);
+ }
+ rawDataBuf = new byte[bufferSize];
+ }
+
private boolean fillBuffer() throws IOException {
try {
+ if (firstChunk && currentReader != null) {
+ init();
+ currentChunk = getNextChunk();
+ firstChunk = false;
+ }
if (currentChunk == null) {
+ close();
return false;
}
diff --git
a/tests/spark-it/src/test/scala/org/apache/celeborn/tests/spark/CelebornFetchFailureSuite.scala
b/tests/spark-it/src/test/scala/org/apache/celeborn/tests/spark/CelebornFetchFailureSuite.scala
index 291bdca18..bdc834b5c 100644
---
a/tests/spark-it/src/test/scala/org/apache/celeborn/tests/spark/CelebornFetchFailureSuite.scala
+++
b/tests/spark-it/src/test/scala/org/apache/celeborn/tests/spark/CelebornFetchFailureSuite.scala
@@ -93,193 +93,205 @@ class CelebornFetchFailureSuite extends AnyFunSuite
}
test("celeborn spark integration test - Fetch Failure") {
- val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
- val sparkSession = SparkSession.builder()
- .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
- .config("spark.sql.shuffle.partitions", 2)
- .config("spark.celeborn.shuffle.forceFallback.partition.enabled", false)
- .config("spark.celeborn.shuffle.enabled", "true")
- .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
- .config(
- "spark.shuffle.manager",
- "org.apache.spark.shuffle.celeborn.TestCelebornShuffleManager")
- .getOrCreate()
-
- val celebornConf =
SparkUtils.fromSparkConf(sparkSession.sparkContext.getConf)
- val hook = new ShuffleReaderGetHook(celebornConf)
- TestCelebornShuffleManager.registerReaderGetHook(hook)
-
- val value = Range(1, 10000).mkString(",")
- val tuples = sparkSession.sparkContext.parallelize(1 to 10000, 2)
- .map { i => (i, value) }.groupByKey(16).collect()
-
- // verify result
- assert(hook.executed.get() == true)
- assert(tuples.length == 10000)
- for (elem <- tuples) {
- assert(elem._2.mkString(",").equals(value))
- }
+ if (Spark3OrNewer) {
+ val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
+ val sparkSession = SparkSession.builder()
+ .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
+ .config("spark.sql.shuffle.partitions", 2)
+ .config("spark.celeborn.shuffle.forceFallback.partition.enabled",
false)
+ .config("spark.celeborn.shuffle.enabled", "true")
+ .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
+ .config(
+ "spark.shuffle.manager",
+ "org.apache.spark.shuffle.celeborn.TestCelebornShuffleManager")
+ .getOrCreate()
+
+ val celebornConf =
SparkUtils.fromSparkConf(sparkSession.sparkContext.getConf)
+ val hook = new ShuffleReaderGetHook(celebornConf)
+ TestCelebornShuffleManager.registerReaderGetHook(hook)
+
+ val value = Range(1, 10000).mkString(",")
+ val tuples = sparkSession.sparkContext.parallelize(1 to 10000, 2)
+ .map { i => (i, value) }.groupByKey(16).collect()
+
+ // verify result
+ assert(hook.executed.get() == true)
+ assert(tuples.length == 10000)
+ for (elem <- tuples) {
+ assert(elem._2.mkString(",").equals(value))
+ }
- val shuffleMgr = SparkContextHelper.env
- .shuffleManager
- .asInstanceOf[TestCelebornShuffleManager]
- val lifecycleManager = shuffleMgr.getLifecycleManager
+ val shuffleMgr = SparkContextHelper.env
+ .shuffleManager
+ .asInstanceOf[TestCelebornShuffleManager]
+ val lifecycleManager = shuffleMgr.getLifecycleManager
- shuffleMgr.unregisterShuffle(0)
- assert(lifecycleManager.getUnregisterShuffleTime().containsKey(0))
- assert(lifecycleManager.getUnregisterShuffleTime().containsKey(1))
+ shuffleMgr.unregisterShuffle(0)
+ assert(lifecycleManager.getUnregisterShuffleTime().containsKey(0))
+ assert(lifecycleManager.getUnregisterShuffleTime().containsKey(1))
- sparkSession.stop()
+ sparkSession.stop()
+ }
}
test("celeborn spark integration test - unregister shuffle with
throwsFetchFailure disabled") {
- val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
- val sparkSession = SparkSession.builder()
- .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
- .config("spark.sql.shuffle.partitions", 2)
- .config("spark.celeborn.shuffle.forceFallback.partition.enabled", false)
- .config("spark.celeborn.shuffle.enabled", "true")
- .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "false")
- .getOrCreate()
-
- val value = Range(1, 10000).mkString(",")
- val tuples = sparkSession.sparkContext.parallelize(1 to 10000, 2)
- .map { i => (i, value) }.groupByKey(16).collect()
-
- // verify result
- assert(tuples.length == 10000)
- for (elem <- tuples) {
- assert(elem._2.mkString(",").equals(value))
- }
+ if (Spark3OrNewer) {
+ val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
+ val sparkSession = SparkSession.builder()
+ .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
+ .config("spark.sql.shuffle.partitions", 2)
+ .config("spark.celeborn.shuffle.forceFallback.partition.enabled",
false)
+ .config("spark.celeborn.shuffle.enabled", "true")
+ .config("spark.celeborn.client.spark.fetch.throwsFetchFailure",
"false")
+ .getOrCreate()
+
+ val value = Range(1, 10000).mkString(",")
+ val tuples = sparkSession.sparkContext.parallelize(1 to 10000, 2)
+ .map { i => (i, value) }.groupByKey(16).collect()
+
+ // verify result
+ assert(tuples.length == 10000)
+ for (elem <- tuples) {
+ assert(elem._2.mkString(",").equals(value))
+ }
- val shuffleMgr = SparkContextHelper.env
- .shuffleManager
- .asInstanceOf[SparkShuffleManager]
- val lifecycleManager = shuffleMgr.getLifecycleManager
+ val shuffleMgr = SparkContextHelper.env
+ .shuffleManager
+ .asInstanceOf[SparkShuffleManager]
+ val lifecycleManager = shuffleMgr.getLifecycleManager
- shuffleMgr.unregisterShuffle(0)
- assert(lifecycleManager.getUnregisterShuffleTime().containsKey(0))
+ shuffleMgr.unregisterShuffle(0)
+ assert(lifecycleManager.getUnregisterShuffleTime().containsKey(0))
- sparkSession.stop()
+ sparkSession.stop()
+ }
}
test("celeborn spark integration test - Fetch Failure with multiple shuffle
data") {
- val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
- val sparkSession = SparkSession.builder()
- .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
- .config("spark.sql.shuffle.partitions", 2)
- .config("spark.celeborn.shuffle.forceFallback.partition.enabled", false)
- .config("spark.celeborn.shuffle.enabled", "true")
- .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
- .config(
- "spark.shuffle.manager",
- "org.apache.spark.shuffle.celeborn.TestCelebornShuffleManager")
- .getOrCreate()
-
- val celebornConf =
SparkUtils.fromSparkConf(sparkSession.sparkContext.getConf)
- val hook = new ShuffleReaderGetHook(celebornConf)
- TestCelebornShuffleManager.registerReaderGetHook(hook)
-
- import sparkSession.implicits._
-
- val df1 = Seq((1, "a"), (2, "b")).toDF("id", "data").groupBy("id").count()
- val df2 = Seq((2, "c"), (2, "d")).toDF("id", "data").groupBy("id").count()
- val tuples = df1.hint("merge").join(df2, "id").select("*").collect()
-
- // verify result
- assert(hook.executed.get() == true)
- val expect = "[2,1,2]"
- assert(tuples.head.toString().equals(expect))
- sparkSession.stop()
+ if (Spark3OrNewer) {
+ val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
+ val sparkSession = SparkSession.builder()
+ .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
+ .config("spark.sql.shuffle.partitions", 2)
+ .config("spark.celeborn.shuffle.forceFallback.partition.enabled",
false)
+ .config("spark.celeborn.shuffle.enabled", "true")
+ .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
+ .config(
+ "spark.shuffle.manager",
+ "org.apache.spark.shuffle.celeborn.TestCelebornShuffleManager")
+ .getOrCreate()
+
+ val celebornConf =
SparkUtils.fromSparkConf(sparkSession.sparkContext.getConf)
+ val hook = new ShuffleReaderGetHook(celebornConf)
+ TestCelebornShuffleManager.registerReaderGetHook(hook)
+
+ import sparkSession.implicits._
+
+ val df1 = Seq((1, "a"), (2, "b")).toDF("id",
"data").groupBy("id").count()
+ val df2 = Seq((2, "c"), (2, "d")).toDF("id",
"data").groupBy("id").count()
+ val tuples = df1.hint("merge").join(df2, "id").select("*").collect()
+
+ // verify result
+ assert(hook.executed.get() == true)
+ val expect = "[2,1,2]"
+ assert(tuples.head.toString().equals(expect))
+ sparkSession.stop()
+ }
}
test("celeborn spark integration test - Fetch Failure with RDD reuse") {
- val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
- val sparkSession = SparkSession.builder()
- .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
- .config("spark.sql.shuffle.partitions", 2)
- .config("spark.celeborn.shuffle.forceFallback.partition.enabled", false)
- .config("spark.celeborn.shuffle.enabled", "true")
- .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
- .config(
- "spark.shuffle.manager",
- "org.apache.spark.shuffle.celeborn.TestCelebornShuffleManager")
- .getOrCreate()
-
- val celebornConf =
SparkUtils.fromSparkConf(sparkSession.sparkContext.getConf)
- val hook = new ShuffleReaderGetHook(celebornConf)
- TestCelebornShuffleManager.registerReaderGetHook(hook)
-
- val sc = sparkSession.sparkContext
- val rdd1 = sc.parallelize(0 until 10000, 3).map(v => (v, v)).groupByKey()
- val rdd2 = sc.parallelize(0 until 10000, 2).map(v => (v, v)).groupByKey()
- val rdd3 = rdd1.map(v => (v._2, v._1))
-
- hook.executed.set(true)
-
- rdd1.count()
- rdd2.count()
-
- hook.executed.set(false)
- rdd3.count()
- hook.executed.set(false)
- rdd3.count()
- hook.executed.set(false)
- rdd3.count()
- hook.executed.set(false)
- rdd3.count()
-
- sparkSession.stop()
+ if (Spark3OrNewer) {
+ val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
+ val sparkSession = SparkSession.builder()
+ .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
+ .config("spark.sql.shuffle.partitions", 2)
+ .config("spark.celeborn.shuffle.forceFallback.partition.enabled",
false)
+ .config("spark.celeborn.shuffle.enabled", "true")
+ .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
+ .config(
+ "spark.shuffle.manager",
+ "org.apache.spark.shuffle.celeborn.TestCelebornShuffleManager")
+ .getOrCreate()
+
+ val celebornConf =
SparkUtils.fromSparkConf(sparkSession.sparkContext.getConf)
+ val hook = new ShuffleReaderGetHook(celebornConf)
+ TestCelebornShuffleManager.registerReaderGetHook(hook)
+
+ val sc = sparkSession.sparkContext
+ val rdd1 = sc.parallelize(0 until 10000, 3).map(v => (v, v)).groupByKey()
+ val rdd2 = sc.parallelize(0 until 10000, 2).map(v => (v, v)).groupByKey()
+ val rdd3 = rdd1.map(v => (v._2, v._1))
+
+ hook.executed.set(true)
+
+ rdd1.count()
+ rdd2.count()
+
+ hook.executed.set(false)
+ rdd3.count()
+ hook.executed.set(false)
+ rdd3.count()
+ hook.executed.set(false)
+ rdd3.count()
+ hook.executed.set(false)
+ rdd3.count()
+
+ sparkSession.stop()
+ }
}
test("celeborn spark integration test - Fetch Failure with read write
shuffles in one stage") {
- val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
- val sparkSession = SparkSession.builder()
- .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
- .config("spark.sql.shuffle.partitions", 2)
- .config("spark.celeborn.shuffle.forceFallback.partition.enabled", false)
- .config("spark.celeborn.shuffle.enabled", "true")
- .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
- .config(
- "spark.shuffle.manager",
- "org.apache.spark.shuffle.celeborn.TestCelebornShuffleManager")
- .getOrCreate()
-
- val celebornConf =
SparkUtils.fromSparkConf(sparkSession.sparkContext.getConf)
- val hook = new ShuffleReaderGetHook(celebornConf)
- TestCelebornShuffleManager.registerReaderGetHook(hook)
-
- val sc = sparkSession.sparkContext
- val rdd1 = sc.parallelize(0 until 10000, 3).map(v => (v, v)).groupByKey()
- val rdd2 = rdd1.map(v => (v._2, v._1)).groupByKey()
-
- hook.executed.set(true)
- rdd1.count()
-
- hook.executed.set(false)
- rdd2.count()
-
- sparkSession.stop()
+ if (Spark3OrNewer) {
+ val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
+ val sparkSession = SparkSession.builder()
+ .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
+ .config("spark.sql.shuffle.partitions", 2)
+ .config("spark.celeborn.shuffle.forceFallback.partition.enabled",
false)
+ .config("spark.celeborn.shuffle.enabled", "true")
+ .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
+ .config(
+ "spark.shuffle.manager",
+ "org.apache.spark.shuffle.celeborn.TestCelebornShuffleManager")
+ .getOrCreate()
+
+ val celebornConf =
SparkUtils.fromSparkConf(sparkSession.sparkContext.getConf)
+ val hook = new ShuffleReaderGetHook(celebornConf)
+ TestCelebornShuffleManager.registerReaderGetHook(hook)
+
+ val sc = sparkSession.sparkContext
+ val rdd1 = sc.parallelize(0 until 10000, 3).map(v => (v, v)).groupByKey()
+ val rdd2 = rdd1.map(v => (v._2, v._1)).groupByKey()
+
+ hook.executed.set(true)
+ rdd1.count()
+
+ hook.executed.set(false)
+ rdd2.count()
+
+ sparkSession.stop()
+ }
}
test("celeborn spark integration test - empty shuffle data") {
- val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
- val sparkSession = SparkSession.builder()
- .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
- .config("spark.sql.shuffle.partitions", 2)
- .config("spark.celeborn.shuffle.forceFallback.partition.enabled", false)
- .config("spark.celeborn.shuffle.enabled", "true")
- .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
- .getOrCreate()
-
- sparkSession.sql("create table if not exists t_1 (a bigint) using parquet")
- sparkSession.sql("create table if not exists t_2 (a bigint) using parquet")
- sparkSession.sql("create table if not exists t_3 (a bigint) using parquet")
- val df1 = sparkSession.table("t_1")
- val df2 = sparkSession.table("t_2")
- val df3 = sparkSession.table("t_3")
- df1.union(df2).union(df3).count()
-
- sparkSession.stop()
+ if (Spark3OrNewer) {
+ val sparkConf = new
SparkConf().setAppName("rss-demo").setMaster("local[2,3]")
+ val sparkSession = SparkSession.builder()
+ .config(updateSparkConf(sparkConf, ShuffleMode.HASH))
+ .config("spark.sql.shuffle.partitions", 2)
+ .config("spark.celeborn.shuffle.forceFallback.partition.enabled",
false)
+ .config("spark.celeborn.shuffle.enabled", "true")
+ .config("spark.celeborn.client.spark.fetch.throwsFetchFailure", "true")
+ .getOrCreate()
+
+ sparkSession.sql("create table if not exists t_1 (a bigint) using
parquet")
+ sparkSession.sql("create table if not exists t_2 (a bigint) using
parquet")
+ sparkSession.sql("create table if not exists t_3 (a bigint) using
parquet")
+ val df1 = sparkSession.table("t_1")
+ val df2 = sparkSession.table("t_2")
+ val df3 = sparkSession.table("t_3")
+ df1.union(df2).union(df3).count()
+
+ sparkSession.stop()
+ }
}
}
diff --git
a/tests/spark-it/src/test/scala/org/apache/celeborn/tests/spark/SparkTestBase.scala
b/tests/spark-it/src/test/scala/org/apache/celeborn/tests/spark/SparkTestBase.scala
index e2cb3c98a..05af928e6 100644
---
a/tests/spark-it/src/test/scala/org/apache/celeborn/tests/spark/SparkTestBase.scala
+++
b/tests/spark-it/src/test/scala/org/apache/celeborn/tests/spark/SparkTestBase.scala
@@ -19,6 +19,7 @@ package org.apache.celeborn.tests.spark
import scala.util.Random
+import org.apache.spark.SPARK_VERSION
import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.internal.SQLConf
@@ -32,6 +33,10 @@ import org.apache.celeborn.service.deploy.MiniClusterFeature
trait SparkTestBase extends AnyFunSuite
with Logging with MiniClusterFeature with BeforeAndAfterAll with
BeforeAndAfterEach {
+
+ val Spark3OrNewer = SPARK_VERSION >= "3.0"
+ println(s"Spark version is $SPARK_VERSION, Spark3OrNewer: $Spark3OrNewer")
+
private val sampleSeq = (1 to 78)
.map(Random.alphanumeric)
.toList