Skip to content

Commit af6b23b

Browse files
committed
[VL] Passing hadoop related configurations to native
Signed-off-by: Yuan <yuanzhou@apache.org>
1 parent 649eb78 commit af6b23b

2 files changed

Lines changed: 47 additions & 4 deletions

File tree

backends-velox/src/main/scala/org/apache/gluten/backendsapi/velox/VeloxIteratorApi.scala

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,41 @@ class VeloxIteratorApi extends IteratorApi with Logging {
125125
// Only serialize plan once, save lots time when plan is complex.
126126
val planByteArray = wsCtx.root.toProtobuf.toByteArray
127127

128+
// Capture fs.azure.* / fs.s3a.* / fs.gs.* keys from the driver-side
129+
// Hadoop configuration NOW, while we are still on the driver, and embed
130+
// them in every GlutenPartition. These keys are set by the user via
131+
// spark.conf.set("fs.azure.account.auth.type", ...) or
132+
// sparkContext.hadoopConfiguration.set(...)
133+
// Spark's withSQLConfPropagated only forwards keys starting with "spark"
134+
// as task-local-properties, so "fs.*" keys never reach the executor's
135+
// SQLConf. Serialising them inside the partition is the only safe way
136+
// to make them available to the native runtime on the executor.
137+
// Capture fs.azure.* / fs.s3a.* / fs.gs.* keys while on the driver.
138+
// SparkPlan.sqlContext is available on the driver -- using the first leaf
139+
// gives us access to sessionState.newHadoopConf() which includes all keys
140+
// set via spark.conf.set(), sparkContext.hadoopConfiguration, and
141+
// DataFrameReader.option(). These are NOT propagated to executors by
142+
// Spark's withSQLConfPropagated (it only forwards keys starting with
143+
// "spark"), so embedding them in the serialised GlutenPartition is the
144+
// only reliable transport mechanism.
145+
val fsPrefixes = Seq("fs.azure.", "fs.s3a.", "fs.gs.")
146+
val hadoopConf = leaves.headOption
147+
.map(_ => org.apache.spark.sql.SparkSession.active.sessionState.newHadoopConf())
148+
.getOrElse(org.apache.spark.SparkContext.getOrCreate().hadoopConfiguration)
149+
val fsConf = {
150+
hadoopConf.iterator().asScala
151+
.filter(e => fsPrefixes.exists(e.getKey.startsWith))
152+
.map(e => e.getKey -> e.getValue)
153+
.toMap
154+
}
155+
128156
splitInfos.zipWithIndex.map {
129157
case (splitInfos, index) =>
130158
GlutenPartition(
131159
index,
132160
planByteArray,
133-
splitInfos.toArray
161+
splitInfos.toArray,
162+
fsConf = fsConf
134163
)
135164
}
136165
}
@@ -199,7 +228,16 @@ class VeloxIteratorApi extends IteratorApi with Logging {
199228
iter => new ColumnarBatchInIterator(BackendsApiManager.getBackendName, iter.asJava)
200229
}
201230

202-
val extraConf = Map(GlutenConfig.COLUMNAR_CUDF_ENABLED.key -> enableCudf.toString).asJava
231+
// Merge the fs.* keys captured on the driver (stored in GlutenPartition.fsConf)
232+
// into the extraConf passed to NativePlanEvaluator / VeloxRuntime.
233+
// Runtimes.contextInstance() will call GlutenConfig.getNativeSessionConf() which
234+
// merges extraConf on top of SQLConf.get.getAllConfs. Because the executor-side
235+
// SQLConf never receives "fs.*" keys (Spark only propagates "spark.*" keys via
236+
// task local properties), this is the only path these credentials can take to
237+
// reach the native session config and ultimately the Velox ABFS connector.
238+
val partitionFsConf = inputPartition.asInstanceOf[GlutenPartition].fsConf
239+
val extraConf = (partitionFsConf +
240+
(GlutenConfig.COLUMNAR_CUDF_ENABLED.key -> enableCudf.toString)).asJava
203241
val transKernel = NativePlanEvaluator.create(BackendsApiManager.getBackendName, extraConf)
204242

205243
val splitInfoByteArray = inputPartition

gluten-substrait/src/main/scala/org/apache/gluten/execution/GlutenWholeStageColumnarRDD.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,13 @@ case class GlutenPartition(
3737
index: Int,
3838
plan: Array[Byte],
3939
splitInfos: Array[SplitInfo] = Array.empty[SplitInfo],
40-
files: Array[String] =
41-
Array.empty[String] // touched files, for implementing UDF input_file_name
40+
files: Array[String] = Array.empty[String], // touched files, for UDF input_file_name
41+
// fs.azure.* / fs.s3a.* / fs.gs.* keys captured on the driver from
42+
// sessionState.newHadoopConf() and serialised here so they survive the
43+
// RDD partition boundary. Spark's withSQLConfPropagated only propagates
44+
// keys that start with "spark", so these keys are otherwise invisible on
45+
// the executor side (the executor's SQLConf never sees them).
46+
fsConf: Map[String, String] = Map.empty
4247
) extends BaseGlutenPartition {
4348

4449
override def preferredLocations(): Array[String] =

0 commit comments

Comments
 (0)