Title: feat: Bring Your Own Spark - SparkApplication by aniketpalu · Pull Request #6550 · feast-dev/feast · GitHub
Open Graph Title: feat: Bring Your Own Spark - SparkApplication by aniketpalu · Pull Request #6550 · feast-dev/feast
X Title: feat: Bring Your Own Spark - SparkApplication by aniketpalu · Pull Request #6550 · feast-dev/feast
Description: What this PR does / why we need it: Core changes Upstream (feature_store.py): Refactored `materialize()` and `materialize_incremental()` to collect all `MaterializationTask`s and pass them to the engine in a single `batch_engine.materialize(registry, tasks)` call. This enables batching engines to process all feature views in one job. Existing engines are unaffected — `ComputeEngine.materialize()` base class loops tasks internally via `_materialize_one()`. Added public `get_provider()` method on `FeatureStore` (wraps existing private `_get_provider()`). New engine (spark_application/): `config.py`: Pydantic config with Spark resource specs, K8s options, validation (`env` entries must have `name`, `staging_location` warning). `compute.py`: Creates a K8s Secret with `feature_store.yaml` + task list, builds SparkApplication CR, polls for completion, retrieves driver logs on failure. `job.py`: Maps all 14 SparkApplication states to `MaterializationJobStatus`, with exponential backoff retry on transient API errors. `main.py`: Driver script that runs inside the pod — loads config from Secret, materializes each feature view via `provider.materialize_single_feature_view()`. Supports concurrent FV processing via ThreadPoolExecutor + FAIR scheduler. `Dockerfile`: Based on `apache/spark:4.0.1`, installs `feast[redis]==0.64.0`, includes Hadoop AWS JARs for S3A support. Design decisions Two config rewrites in driver pod: `batch_engine` → `spark.engine` (prevents recursive CRD creation, uses local SparkSession), `registry` → `remote` when `registry_address` is set (pod can't access server filesystem). Driver calls `provider.materialize_single_feature_view()`, not `store.materialize()` — avoids FeatureViewState transition conflicts (MATERIALIZING→MATERIALIZING is invalid) and duplicate OpenLineage/MLflow emissions. SQLite online store rejected at init — data written inside a pod is lost on termination. Kueue integration via `queue_name` config field → `kueue.x-k8s.io/queue-name` label. Validated on OpenShift AI (ROSA) with Spark Operator v2.5.0, MinIO (S3A), Redis 5 feature views, 4800 rows each, 2 executors: 2.4x speedup with concurrent mode Test plan 12 unit tests: config defaults, SQLite rejection, registry validation, config rewrites, CR structure, state mapping (14 states), cleanup 404 handling, timeout behavior, job naming Existing tests unaffected: 29 feature_view_state + 22 local_feature_store tests pass Integration test on cluster with real Spark Operator" Which issue(s) this PR fixes: Checks I've made sure the tests are passing. My commits are signed off (git commit -s) My PR title follows conventional commits format Testing Strategy Unit tests Integration tests Manual tests Testing is not required for this change Misc
Open Graph Description: What this PR does / why we need it: Core changes Upstream (feature_store.py): Refactored `materialize()` and `materialize_incremental()` to collect all `MaterializationTask`s and pass them to the...
X Description: What this PR does / why we need it: Core changes Upstream (feature_store.py): Refactored `materialize()` and `materialize_incremental()` to collect all `MaterializationTask`s and pass them to the...
Opengraph URL: https://github.com/feast-dev/feast/pull/6550
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:26f8198a-4e7d-b339-a3ea-d254f00c8b94 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | A5EC:1E0399:C81AF2:10EDC7D:6A51676F |
| html-safe-nonce | 9ab5c0262c16cca0d93b62e3d63f0172c68a5d224fa44dc0af9b7a382d490d8b |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBNUVDOjFFMDM5OTpDODFBRjI6MTBFREM3RDo2QTUxNjc2RiIsInZpc2l0b3JfaWQiOiI5MTAzMTUyMDQ3MTQyODIzNzkxIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 2e12ad8974c04226c7458bbce99807ba0ead57b54fa3620217b554386b09937b |
| hovercard-subject-tag | pull_request:3926298248 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/feast-dev/feast/pull/6550/files |
| twitter:image | https://avatars.githubusercontent.com/u/64416568?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/64416568?s=400&v=4 |
| og:image:alt | What this PR does / why we need it: Core changes Upstream (feature_store.py): Refactored `materialize()` and `materialize_incremental()` to collect all `MaterializationTask`s and pass them to the... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/feast-dev/feast git https://github.com/feast-dev/feast.git |
| octolytics-dimension-user_id | 57027613 |
| octolytics-dimension-user_login | feast-dev |
| octolytics-dimension-repository_id | 161133770 |
| octolytics-dimension-repository_nwo | feast-dev/feast |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 161133770 |
| octolytics-dimension-repository_network_root_nwo | feast-dev/feast |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 60eaaf6d4dbaa817031b556aebd8a0a7eeb81b97 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width