Eliaaazzz opened a new pull request, #40129:
URL: https://github.com/apache/beam/pull/40129

   Proof of concept for the Dataset-based portable Spark 4 backend discussed in 
the "[DISCUSS] Spark 4 portable runner direction" thread on dev@. Opening this 
as a draft so the discussion has concrete code to work from. Addresses #36841.
   
   ### What this adds
   
   An opt-in `--useStructuredStreaming` flag on the portable Spark runner. With 
the flag set, `SparkPipelineRunner` translates the fused Runner API pipeline 
into Spark Datasets through a new `SparkDatasetPortablePipelineTranslator`:
   
   - `Impulse`, `Flatten`, `Reshuffle` and `GroupByKey` become Dataset 
operations. `GroupByKey` groups on the encoded key and runs 
`SparkGroupAlsoByWindowViaOutputBufferFn` per key. That is the general 
`GroupAlsoByWindow` the RDD batch translator falls back to when a windowing 
strategy is not eligible for the `GroupNonMergingWindowsFunctions` fast paths. 
The Dataset path always takes the general branch, so it gives up the 
non-merging memory optimization and keeps the `ReduceFnRunner` semantics.
   - Executable stages run inside `Dataset.mapPartitions` through the existing 
Fn API bridge, `SparkExecutableStageFunction`, which is unchanged. Outputs are 
demultiplexed with `EncoderHelpers.oneOfEncoder`, following 
`ParDoTranslatorBatch`. Side inputs are collected during translation and 
broadcast.
   - Fully bounded pipelines run as batch Datasets. Unbounded input, user state 
and timers are rejected at translation with a message pointing at the tracking 
issue, so nothing silently runs on a path that cannot support it yet.
   
   The translation context attaches to the `SparkContext` that 
`SparkContextFactory` already created, so the job server code path, the metrics 
accumulator and result handling are unchanged. The translator lives in the 
shared `runners/spark` base and compiles for both the Spark 3 and Spark 4 
modules.
   
   The flag name matches the terminology in the dev@ thread and is provisional. 
Today it only selects the Dataset translator. No Structured Streaming query is 
built yet.
   
   ### The exit gate
   
   Following Yi's suggestion on the thread, 
`validatesPortableRunnerStructuredStreaming` runs the streaming 
`PortableValidatesRunner` suite with the flag on, keeping exactly the same 
categories and test filters as `validatesPortableRunnerStreaming`, and a 
`PostCommit Java PVR Spark4 StructuredStreaming` workflow runs it. That suite 
is the exit gate for flipping the default for portable streaming pipelines.
   
   What that gate currently measures is narrower than its name suggests. 
`--streaming` does not by itself mark any PCollection unbounded, and the 
streaming exclusion list already removes the categories that would produce one. 
`ValidatesRunner` extends `NeedsRunner`, so tests annotated with `NeedsRunner` 
and `UsesUnboundedPCollections` are outside the suite, and the remaining 
`ValidatesRunner` tests carrying `UsesUnboundedPCollections` are each excluded 
by `UsesTimersInParDo`, `UsesTestStream`, `UsesStrictTimerOrdering` or 
`UsesOnWindowExpiration`. The first run therefore exercises bounded Dataset 
execution under the streaming exclusion list. The risk it actually probes is 
windowing, triggers and GroupByKey behaviour on this backend. This matches the 
point on the thread that the suite is mostly batch pipelines after the 
exclusions.
   
   The new task is deliberately not part of the aggregate 
`validatesPortableRunner` task while the backend is a preview.
   
   ### Out of scope, tracked separately
   
   - Unbounded splittable DoFn residuals across micro-batches, #19468.
   - Stateful stages, #20396.
   - Timers, #20397.
   - The Structured Streaming query itself for pipelines with unbounded input, 
#36841.
   
   This does not modify the in-process Structured Streaming runner, including 
the work merged in #39906 and #39939 and the open #39576. It does reuse two of 
its classes, `EncoderHelpers` and `EvaluationContext`, so the portable path 
also picks up the Spark 4 `EncoderHelpers` override that came with the Spark 4 
runner in #38255.
   
   ### Validation
   
   - `SparkDatasetPortableExecutionTest` runs Impulse, ParDo, Flatten, 
GroupByKey and PAssert end to end on the Dataset backend with the embedded SDK 
harness, and asserts that unbounded input and a stateful ParDo are rejected at 
translation with the expected message. Three tests, green on 
`:runners:spark:4:test` under JDK 17 and on `:runners:spark:3:test` under JDK 
11.
   - Known coverage gaps in this PR, all of which the PVR run is meant to 
cover: multi-output stages, so the `oneOfEncoder` demux is only ever built with 
one alternative; `Reshuffle`; the `Flatten` re-encode branch for mismatched 
coders; side inputs, which the streaming suite also excludes via 
`UsesSideInputs`; and the timer half of the state and timer rejection.
   - Only the global window is covered by a test here. Sessions, sliding 
windows and non-default timestamp combiners are unverified on this backend.
   - I have not run the full PVR suite locally, so the first run of the new 
workflow is the real signal.
   - The Spark 3 compile runs with the nullness checker enabled. The two new 
files suppress `nullness` at class level, matching the surrounding translator 
code.
   
   ### Notes for review
   
   Three things I would particularly like a second opinion on:
   
   - Setting `pipelineOptions.setStreaming(false)` in the new branch. 
`MetricsAccumulator.init` reads the option directly, not the mode the runner 
resolved, so without this it takes its checkpoint branch and seeds the 
accumulator from a checkpoint file this path never writes back.
   - Persisted Datasets are never unpersisted and the `SparkSession` is never 
cleared. That is fine when `PortableBatchMode.stop()` stops the context, and it 
accumulates when the context is provided or reused.
   - Side inputs are collected eagerly during translation, which makes 
translation itself trigger Spark actions.
   
   ------------------------
   
   Thank you for your contribution! Follow this checklist to help us 
incorporate your contribution quickly and easily:
   
    - [x] Mention the appropriate issue in your description (for example: 
`addresses #123`), if applicable. This will automatically add a link to the 
pull request in the issue. If you would like the issue to automatically close 
on merging the pull request, comment `fixes #<ISSUE NUMBER>` instead.
    - [ ] Update `CHANGES.md` with noteworthy changes. Holding this until the 
flag is more than a preview.
    - [ ] If this contribution is large, please file an Apache [Individual 
Contributor License Agreement](https://www.apache.org/licenses/icla.pdf).
   
   See the [Contributor Guide](https://beam.apache.org/contribute) for more 
tips on [how to make review process 
smoother](https://github.com/apache/beam/blob/master/CONTRIBUTING.md#make-the-reviewers-job-easier).
   
   To check the build health, please visit 
[https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md](https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md)
   
   GitHub Actions Tests Status (on master branch)
   
------------------------------------------------------------------------------------------------
   [![Build python source distribution and 
wheels](https://github.com/apache/beam/actions/workflows/build_wheels.yml/badge.svg?event=schedule&&?branch=master)](https://github.com/apache/beam/actions?query=workflow%3A%22Build+python+source+distribution+and+wheels%22+branch%3Amaster+event%3Aschedule)
   [![Python 
tests](https://github.com/apache/beam/actions/workflows/python_tests.yml/badge.svg?event=schedule&&?branch=master)](https://github.com/apache/beam/actions?query=workflow%3A%22Python+Tests%22+branch%3Amaster+event%3Aschedule)
   [![Java 
tests](https://github.com/apache/beam/actions/workflows/java_tests.yml/badge.svg?event=schedule&&?branch=master)](https://github.com/apache/beam/actions?query=workflow%3A%22Java+tests%22+branch%3Amaster+event%3Aschedule)
   [![Go 
tests](https://github.com/apache/beam/actions/workflows/go_tests.yml/badge.svg?event=schedule&&?branch=master)](https://github.com/apache/beam/actions?query=workflow%3A%22Go+tests%22+branch%3Amaster+event%3Aschedule)
   
   See [CI.md](https://github.com/apache/beam/blob/master/CI.md) for more 
information about GitHub Actions CI or the [workflows 
README](https://github.com/apache/beam/blob/master/.github/workflows/README.md) 
to see a list of phrases to trigger workflows.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to