Skip to content

Commit 9f065ff

Browse files
xkrogentgravescs
authored andcommitted
[SPARK-34828][YARN] Make shuffle service name configurable on client side and allow for classpath-based config override on server side
### What changes were proposed in this pull request? Add a new config, `spark.shuffle.service.name`, which allows for Spark applications to look for a YARN shuffle service which is defined at a name other than the default `spark_shuffle`. Add a new config, `spark.yarn.shuffle.service.metrics.namespace`, which allows for configuring the namespace used when emitting metrics from the shuffle service into the NodeManager's `metrics2` system. Add a new mechanism by which to override shuffle service configurations independently of the configurations in the NodeManager. When a resource `spark-shuffle-site.xml` is present on the classpath of the shuffle service, the configs present within it will be used to override the configs coming from `yarn-site.xml` (via the NodeManager). ### Why are the changes needed? There are two use cases which can benefit from these changes. One use case is to run multiple instances of the shuffle service side-by-side in the same NodeManager. This can be helpful, for example, when running a YARN cluster with a mixed workload of applications running multiple Spark versions, since a given version of the shuffle service is not always compatible with other versions of Spark (e.g. see SPARK-27780). With this PR, it is possible to run two shuffle services like `spark_shuffle` and `spark_shuffle_3.2.0`, one of which is "legacy" and one of which is for new applications. This is possible because YARN versions since 2.9.0 support the ability to run shuffle services within an isolated classloader (see YARN-4577), meaning multiple Spark versions can coexist. Besides this, the separation of shuffle service configs into `spark-shuffle-site.xml` can be useful for administrators who want to change and/or deploy Spark shuffle service configurations independently of the configurations for the NodeManager (e.g., perhaps they are owned by two different teams). ### Does this PR introduce _any_ user-facing change? Yes. There are two new configurations related to the external shuffle service, and a new mechanism which can optionally be used to configure the shuffle service. `docs/running-on-yarn.md` has been updated to provide user instructions; please see this guide for more details. ### How was this patch tested? In addition to the new unit tests added, I have deployed this to a live YARN cluster and successfully deployed two Spark shuffle services simultaneously, one running a modified version of Spark 2.3.0 (which supports some of the newer shuffle protocols) and one running Spark 3.1.1. Spark applications of both versions are able to communicate with their respective shuffle services without issue. Closes #31936 from xkrogen/xkrogen-SPARK-34828-shufflecompat-config-from-classpath. Authored-by: Erik Krogen <xkrogen@apache.org> Signed-off-by: Thomas Graves <tgraves@apache.org>
1 parent 24d39a5 commit 9f065ff

8 files changed

Lines changed: 240 additions & 12 deletions

File tree

common/network-yarn/src/main/java/org/apache/spark/network/yarn/YarnShuffleService.java

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.io.File;
2121
import java.io.IOException;
22+
import java.net.URL;
2223
import java.nio.charset.StandardCharsets;
2324
import java.nio.ByteBuffer;
2425
import java.util.List;
@@ -75,6 +76,20 @@
7576
* is because an application running on the same Yarn cluster may choose to not use the external
7677
* shuffle service, in which case its setting of `spark.authenticate` should be independent of
7778
* the service's.
79+
*
80+
* The shuffle service will produce metrics via the YARN NodeManager's {@code metrics2} system
81+
* under a namespace specified by the {@value SPARK_SHUFFLE_SERVICE_METRICS_NAMESPACE_KEY} config.
82+
*
83+
* By default, all configurations for the shuffle service will be taken directly from the
84+
* Hadoop {@link Configuration} passed by the YARN NodeManager. It is also possible to configure
85+
* the shuffle service by placing a resource named
86+
* {@value SHUFFLE_SERVICE_CONF_OVERLAY_RESOURCE_NAME} into the classpath, which should be an
87+
* XML file in the standard Hadoop Configuration resource format. Note that when the shuffle
88+
* service is loaded in the default manner, without configuring
89+
* {@code yarn.nodemanager.aux-services.<service>.classpath}, this file must be on the classpath
90+
* of the NodeManager itself. When using the {@code classpath} configuration, it can be present
91+
* either on the NodeManager's classpath, or specified in the classpath configuration.
92+
* This {@code classpath} configuration is only supported on YARN versions >= 2.9.0.
7893
*/
7994
public class YarnShuffleService extends AuxiliaryService {
8095
private static final Logger logger = LoggerFactory.getLogger(YarnShuffleService.class);
@@ -83,6 +98,14 @@ public class YarnShuffleService extends AuxiliaryService {
8398
private static final String SPARK_SHUFFLE_SERVICE_PORT_KEY = "spark.shuffle.service.port";
8499
private static final int DEFAULT_SPARK_SHUFFLE_SERVICE_PORT = 7337;
85100

101+
/**
102+
* The namespace to use for the metrics record which will contain all metrics produced by the
103+
* shuffle service.
104+
*/
105+
static final String SPARK_SHUFFLE_SERVICE_METRICS_NAMESPACE_KEY =
106+
"spark.yarn.shuffle.service.metrics.namespace";
107+
private static final String DEFAULT_SPARK_SHUFFLE_SERVICE_METRICS_NAME = "sparkShuffleService";
108+
86109
// Whether the shuffle server should authenticate fetch requests
87110
private static final String SPARK_AUTHENTICATE_KEY = "spark.authenticate";
88111
private static final boolean DEFAULT_SPARK_AUTHENTICATE = false;
@@ -103,6 +126,13 @@ public class YarnShuffleService extends AuxiliaryService {
103126
private static final LevelDBProvider.StoreVersion CURRENT_VERSION = new LevelDBProvider
104127
.StoreVersion(1, 0);
105128

129+
/**
130+
* The name of the resource to search for on the classpath to find a shuffle service-specific
131+
* configuration overlay. If found, this will be parsed as a standard Hadoop
132+
* {@link Configuration config} file and will override the configs passed from the NodeManager.
133+
*/
134+
static final String SHUFFLE_SERVICE_CONF_OVERLAY_RESOURCE_NAME = "spark-shuffle-site.xml";
135+
106136
// just for integration tests that want to look at this file -- in general not sensible as
107137
// a static
108138
@VisibleForTesting
@@ -139,6 +169,13 @@ public class YarnShuffleService extends AuxiliaryService {
139169
private DB db;
140170

141171
public YarnShuffleService() {
172+
// The name of the auxiliary service configured within the NodeManager
173+
// (`yarn.nodemanager.aux-services`) is treated as the source-of-truth, so this one can be
174+
// arbitrary. The NodeManager will log a warning if the configured name doesn't match this name,
175+
// to inform operators of a potential misconfiguration, but this name is otherwise not used.
176+
// It is hard-coded instead of using the value of the `spark.shuffle.service.name` configuration
177+
// because at this point in instantiation there is no Configuration object; it is not passed
178+
// until `serviceInit` is called, at which point it's too late to adjust the name.
142179
super("spark_shuffle");
143180
logger.info("Initializing YARN shuffle service for Spark");
144181
instance = this;
@@ -157,10 +194,18 @@ private boolean isAuthenticationEnabled() {
157194
* Start the shuffle server with the given configuration.
158195
*/
159196
@Override
160-
protected void serviceInit(Configuration conf) throws Exception {
161-
_conf = conf;
197+
protected void serviceInit(Configuration externalConf) throws Exception {
198+
_conf = new Configuration(externalConf);
199+
URL confOverlayUrl = Thread.currentThread().getContextClassLoader()
200+
.getResource(SHUFFLE_SERVICE_CONF_OVERLAY_RESOURCE_NAME);
201+
if (confOverlayUrl != null) {
202+
logger.info("Initializing Spark YARN shuffle service with configuration overlay from {}",
203+
confOverlayUrl);
204+
_conf.addResource(confOverlayUrl);
205+
}
206+
super.serviceInit(_conf);
162207

163-
boolean stopOnFailure = conf.getBoolean(STOP_ON_FAILURE_KEY, DEFAULT_STOP_ON_FAILURE);
208+
boolean stopOnFailure = _conf.getBoolean(STOP_ON_FAILURE_KEY, DEFAULT_STOP_ON_FAILURE);
164209

165210
try {
166211
// In case this NM was killed while there were running spark applications, we need to restore
@@ -172,7 +217,7 @@ protected void serviceInit(Configuration conf) throws Exception {
172217
registeredExecutorFile = initRecoveryDb(RECOVERY_FILE_NAME);
173218
}
174219

175-
TransportConf transportConf = new TransportConf("shuffle", new HadoopConfigProvider(conf));
220+
TransportConf transportConf = new TransportConf("shuffle", new HadoopConfigProvider(_conf));
176221
MergedShuffleFileManager shuffleMergeManager = newMergedShuffleFileManagerInstance(
177222
transportConf);
178223
blockHandler = new ExternalBlockHandler(
@@ -181,7 +226,7 @@ protected void serviceInit(Configuration conf) throws Exception {
181226
// If authentication is enabled, set up the shuffle server to use a
182227
// special RPC handler that filters out unauthenticated fetch requests
183228
List<TransportServerBootstrap> bootstraps = Lists.newArrayList();
184-
boolean authEnabled = conf.getBoolean(SPARK_AUTHENTICATE_KEY, DEFAULT_SPARK_AUTHENTICATE);
229+
boolean authEnabled = _conf.getBoolean(SPARK_AUTHENTICATE_KEY, DEFAULT_SPARK_AUTHENTICATE);
185230
if (authEnabled) {
186231
secretManager = new ShuffleSecretManager();
187232
if (_recoveryPath != null) {
@@ -190,7 +235,7 @@ protected void serviceInit(Configuration conf) throws Exception {
190235
bootstraps.add(new AuthServerBootstrap(transportConf, secretManager));
191236
}
192237

193-
int port = conf.getInt(
238+
int port = _conf.getInt(
194239
SPARK_SHUFFLE_SERVICE_PORT_KEY, DEFAULT_SPARK_SHUFFLE_SERVICE_PORT);
195240
transportContext = new TransportContext(transportConf, blockHandler, true);
196241
shuffleServer = transportContext.createServer(port, bootstraps);
@@ -203,13 +248,16 @@ protected void serviceInit(Configuration conf) throws Exception {
203248
blockHandler.getAllMetrics().getMetrics().put("numRegisteredConnections",
204249
shuffleServer.getRegisteredConnections());
205250
blockHandler.getAllMetrics().getMetrics().putAll(shuffleServer.getAllMetrics().getMetrics());
251+
String metricsNamespace = _conf.get(SPARK_SHUFFLE_SERVICE_METRICS_NAMESPACE_KEY,
252+
DEFAULT_SPARK_SHUFFLE_SERVICE_METRICS_NAME);
206253
YarnShuffleServiceMetrics serviceMetrics =
207-
new YarnShuffleServiceMetrics(blockHandler.getAllMetrics());
254+
new YarnShuffleServiceMetrics(metricsNamespace, blockHandler.getAllMetrics());
208255

209256
MetricsSystemImpl metricsSystem = (MetricsSystemImpl) DefaultMetricsSystem.instance();
210257
metricsSystem.register(
211-
"sparkShuffleService", "Metrics on the Spark Shuffle Service", serviceMetrics);
212-
logger.info("Registered metrics with Hadoop's DefaultMetricsSystem");
258+
metricsNamespace, "Metrics on the Spark Shuffle Service", serviceMetrics);
259+
logger.info("Registered metrics with Hadoop's DefaultMetricsSystem using namespace '{}'",
260+
metricsNamespace);
213261

214262
logger.info("Started YARN shuffle service for Spark on port {}. " +
215263
"Authentication is {}. Registered executor file is {}", port, authEnabledString,

common/network-yarn/src/main/java/org/apache/spark/network/yarn/YarnShuffleServiceMetrics.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@
3232
*/
3333
class YarnShuffleServiceMetrics implements MetricsSource {
3434

35+
private final String metricsNamespace;
3536
private final MetricSet metricSet;
3637

37-
YarnShuffleServiceMetrics(MetricSet metricSet) {
38+
YarnShuffleServiceMetrics(String metricsNamespace, MetricSet metricSet) {
39+
this.metricsNamespace = metricsNamespace;
3840
this.metricSet = metricSet;
3941
}
4042

@@ -46,7 +48,7 @@ class YarnShuffleServiceMetrics implements MetricsSource {
4648
*/
4749
@Override
4850
public void getMetrics(MetricsCollector collector, boolean all) {
49-
MetricsRecordBuilder metricsRecordBuilder = collector.addRecord("sparkShuffleService");
51+
MetricsRecordBuilder metricsRecordBuilder = collector.addRecord(metricsNamespace);
5052

5153
for (Map.Entry<String, Metric> entry : metricSet.getMetrics().entrySet()) {
5254
collectMetric(metricsRecordBuilder, entry.getKey(), entry.getValue());

core/src/main/scala/org/apache/spark/internal/config/package.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,16 @@ package object config {
680680
private[spark] val SHUFFLE_SERVICE_PORT =
681681
ConfigBuilder("spark.shuffle.service.port").version("1.2.0").intConf.createWithDefault(7337)
682682

683+
private[spark] val SHUFFLE_SERVICE_NAME =
684+
ConfigBuilder("spark.shuffle.service.name")
685+
.doc("The configured name of the Spark shuffle service the client should communicate with. " +
686+
"This must match the name used to configure the Shuffle within the YARN NodeManager " +
687+
"configuration (`yarn.nodemanager.aux-services`). Only takes effect when " +
688+
s"$SHUFFLE_SERVICE_ENABLED is set to true.")
689+
.version("3.2.0")
690+
.stringConf
691+
.createWithDefault("spark_shuffle")
692+
683693
private[spark] val KEYTAB = ConfigBuilder("spark.kerberos.keytab")
684694
.doc("Location of user's keytab.")
685695
.version("3.0.0")

docs/running-on-yarn.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,8 +773,28 @@ The following extra configuration options are available when the shuffle service
773773
NodeManagers where the Spark Shuffle Service is not running.
774774
</td>
775775
</tr>
776+
<tr>
777+
<td><code>spark.yarn.shuffle.service.metrics.namespace</code></td>
778+
<td><code>sparkShuffleService</code></td>
779+
<td>
780+
The namespace to use when emitting shuffle service metrics into Hadoop metrics2 system of the
781+
NodeManager.
782+
</td>
783+
</tr>
776784
</table>
777785

786+
Please note that the instructions above assume that the default shuffle service name,
787+
`spark_shuffle`, has been used. It is possible to use any name here, but the values used in the
788+
YARN NodeManager configurations must match the value of `spark.shuffle.service.name` in the
789+
Spark application.
790+
791+
The shuffle service will, by default, take all of its configurations from the Hadoop Configuration
792+
used by the NodeManager (e.g. `yarn-site.xml`). However, it is also possible to configure the
793+
shuffle service independently using a file named `spark-shuffle-site.xml` which should be placed
794+
onto the classpath of the shuffle service (which is, by default, shared with the classpath of the
795+
NodeManager). The shuffle service will treat this as a standard Hadoop Configuration resource and
796+
overlay it on top of the NodeManager's configuration.
797+
778798
# Launching your application with Apache Oozie
779799

780800
Apache Oozie can launch Spark applications as part of a workflow.
@@ -823,3 +843,54 @@ do the following:
823843
to the list of filters in the <code>spark.ui.filters</code> configuration.
824844

825845
Be aware that the history server information may not be up-to-date with the application's state.
846+
847+
# Running multiple versions of the Spark Shuffle Service
848+
849+
Please note that this section only applies when running on YARN versions >= 2.9.0.
850+
851+
In some cases it may be desirable to run multiple instances of the Spark Shuffle Service which are
852+
using different versions of Spark. This can be helpful, for example, when running a YARN cluster
853+
with a mixed workload of applications running multiple Spark versions, since a given version of
854+
the shuffle service is not always compatible with other versions of Spark. YARN versions since 2.9.0
855+
support the ability to run shuffle services within an isolated classloader
856+
(see [YARN-4577](https://issues.apache.org/jira/browse/YARN-4577)), meaning multiple Spark versions
857+
can coexist within a single NodeManager. The
858+
`yarn.nodemanager.aux-services.<service-name>.classpath` and, starting from YARN 2.10.2/3.1.1/3.2.0,
859+
`yarn.nodemanager.aux-services.<service-name>.remote-classpath` options can be used to configure
860+
this. In addition to setting up separate classpaths, it's necessary to ensure the two versions
861+
advertise to different ports. This can be achieved using the `spark-shuffle-site.xml` file described
862+
above. For example, you may have configuration like:
863+
864+
```properties
865+
yarn.nodemanager.aux-services = spark_shuffle_x,spark_shuffle_y
866+
yarn.nodemanager.aux-services.spark_shuffle_x.classpath = /path/to/spark-x-yarn-shuffle.jar,/path/to/spark-x-config
867+
yarn.nodemanager.aux-services.spark_shuffle_y.classpath = /path/to/spark-y-yarn-shuffle.jar,/path/to/spark-y-config
868+
```
869+
870+
The two `spark-*-config` directories each contain one file, `spark-shuffle-site.xml`. These are XML
871+
files in the [Hadoop Configuration format](https://hadoop.apache.org/docs/r3.2.2/api/org/apache/hadoop/conf/Configuration.html)
872+
which each contain a few configurations to adjust the port number and metrics name prefix used:
873+
```xml
874+
<configuration>
875+
<property>
876+
<name>spark.shuffle.service.port</name>
877+
<value>7001</value>
878+
</property>
879+
<property>
880+
<name>spark.yarn.shuffle.service.metrics.namespace</name>
881+
<value>sparkShuffleServiceX</value>
882+
</property>
883+
</configuration>
884+
```
885+
The values should both be different for the two different services.
886+
887+
Then, in the configuration of the Spark applications, one should be configured with:
888+
```properties
889+
spark.shuffle.service.name = spark_shuffle_x
890+
spark.shuffle.service.port = 7001
891+
```
892+
and one should be configured with:
893+
```properties
894+
spark.shuffle.service.name = spark_shuffle_y
895+
spark.shuffle.service.port = <other value>
896+
```

resource-managers/yarn/src/main/scala/org/apache/spark/deploy/yarn/ExecutorRunnable.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ private[yarn] class ExecutorRunnable(
115115
// Authentication is not enabled, so just provide dummy metadata
116116
ByteBuffer.allocate(0)
117117
}
118-
ctx.setServiceData(Collections.singletonMap("spark_shuffle", secretBytes))
118+
val serviceName = sparkConf.get(SHUFFLE_SERVICE_NAME)
119+
logInfo(s"Initializing service data for shuffle service using name '$serviceName'")
120+
ctx.setServiceData(Collections.singletonMap(serviceName, secretBytes))
119121
}
120122

121123
// Send the start request to the ContainerManager
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.spark.deploy.yarn
19+
20+
import java.net.URLClassLoader
21+
22+
import org.apache.hadoop.yarn.conf.YarnConfiguration
23+
24+
import org.apache.spark._
25+
import org.apache.spark.internal.config._
26+
import org.apache.spark.network.yarn.{YarnShuffleService, YarnTestAccessor}
27+
import org.apache.spark.tags.ExtendedYarnTest
28+
29+
/**
30+
* SPARK-34828: Integration test for the external shuffle service with an alternate name and
31+
* configs (by using a configuration overlay)
32+
*/
33+
@ExtendedYarnTest
34+
class YarnShuffleAlternateNameConfigSuite extends YarnShuffleIntegrationSuite {
35+
36+
private[this] val shuffleServiceName = "custom_shuffle_service_name"
37+
38+
override def newYarnConfig(): YarnConfiguration = {
39+
val yarnConfig = super.newYarnConfig()
40+
yarnConfig.set(YarnConfiguration.NM_AUX_SERVICES, shuffleServiceName)
41+
yarnConfig.set(YarnConfiguration.NM_AUX_SERVICE_FMT.format(shuffleServiceName),
42+
classOf[YarnShuffleService].getCanonicalName)
43+
val overlayConf = new YarnConfiguration()
44+
// Enable authentication in the base NodeManager conf but not in the client. This would break
45+
// shuffle, unless the shuffle service conf overlay overrides to turn off authentication.
46+
overlayConf.setBoolean(NETWORK_AUTH_ENABLED.key, true)
47+
// Add the authentication conf to a separate config object used as an overlay rather than
48+
// setting it directly. This is necessary because a config overlay will override previous
49+
// config overlays, but not configs which were set directly on the config object.
50+
yarnConfig.addResource(overlayConf)
51+
yarnConfig
52+
}
53+
54+
override protected def extraSparkConf(): Map[String, String] =
55+
super.extraSparkConf() ++ Map(SHUFFLE_SERVICE_NAME.key -> shuffleServiceName)
56+
57+
override def beforeAll(): Unit = {
58+
val configFileContent =
59+
s"""<?xml version="1.0" encoding="UTF-8"?>
60+
|<configuration>
61+
| <property>
62+
| <name>${NETWORK_AUTH_ENABLED.key}</name>
63+
| <value>false</value>
64+
| </property>
65+
|</configuration>
66+
|""".stripMargin
67+
val jarFile = TestUtils.createJarWithFiles(Map(
68+
YarnTestAccessor.getShuffleServiceConfOverlayResourceName -> configFileContent
69+
))
70+
// Configure a custom classloader which includes the conf overlay as a resource
71+
val oldClassLoader = Thread.currentThread().getContextClassLoader
72+
Thread.currentThread().setContextClassLoader(new URLClassLoader(Array(jarFile)))
73+
try {
74+
super.beforeAll()
75+
} finally {
76+
Thread.currentThread().setContextClassLoader(oldClassLoader)
77+
}
78+
}
79+
}

resource-managers/yarn/src/test/scala/org/apache/spark/network/yarn/YarnShuffleServiceSuite.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ class YarnShuffleServiceSuite extends SparkFunSuite with Matchers with BeforeAnd
5656

5757
override def beforeEach(): Unit = {
5858
super.beforeEach()
59+
// Ensure that each test uses a fresh metrics system
60+
DefaultMetricsSystem.shutdown()
61+
DefaultMetricsSystem.setInstance(new MetricsSystemImpl())
5962
yarnConfig = new YarnConfiguration()
6063
yarnConfig.set(YarnConfiguration.NM_AUX_SERVICES, "spark_shuffle")
6164
yarnConfig.set(YarnConfiguration.NM_AUX_SERVICE_FMT.format("spark_shuffle"),
@@ -413,6 +416,16 @@ class YarnShuffleServiceSuite extends SparkFunSuite with Matchers with BeforeAnd
413416
))
414417
}
415418

419+
test("SPARK-34828: metrics should be registered with configured name") {
420+
s1 = new YarnShuffleService
421+
yarnConfig.set(YarnShuffleService.SPARK_SHUFFLE_SERVICE_METRICS_NAMESPACE_KEY, "fooMetrics")
422+
s1.init(yarnConfig)
423+
424+
assert(DefaultMetricsSystem.instance.getSource("sparkShuffleService") === null)
425+
assert(DefaultMetricsSystem.instance.getSource("fooMetrics")
426+
.isInstanceOf[YarnShuffleServiceMetrics])
427+
}
428+
416429
test("create default merged shuffle file manager instance") {
417430
val mockConf = mock(classOf[TransportConf])
418431
when(mockConf.mergedShuffleFileManagerImpl).thenReturn(

resource-managers/yarn/src/test/scala/org/apache/spark/network/yarn/YarnTestAccessor.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ object YarnTestAccessor {
3434
service.registeredExecutorFile
3535
}
3636

37+
def getShuffleServiceConfOverlayResourceName: String = {
38+
YarnShuffleService.SHUFFLE_SERVICE_CONF_OVERLAY_RESOURCE_NAME
39+
}
3740
}

0 commit comments

Comments
 (0)