一键导入
spark-submit
How to submit, monitor, and configure Spark jobs on oleander using MCP, the CLI, and the TypeScript SDK.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
How to submit, monitor, and configure Spark jobs on oleander using MCP, the CLI, and the TypeScript SDK.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
| name | spark-submit |
| description | How to submit, monitor, and configure Spark jobs on oleander using MCP, the CLI, and the TypeScript SDK. |
Use this skill when submitting Spark jobs to oleander, monitoring run state, or building automated workflows that execute Spark jobs.
Use these tools when working through the oleander MCP server (Claude Code,
Cursor, etc.). Tool names use dot notation — for example spark.jobs.submit,
not oleander_submit_spark_job.
For Spark SQL jobs that write to a table, use spark.sql.submit instead
(see the lake-query skill).
Before submitting a PySpark script, check whether it is already uploaded:
spark.artifacts.list — list ready artifacts and versionsspark.artifacts.upload
with entrypoint, entrypoint_content_base64, and confirm: truespark.artifacts.getPass the artifact basename from the list (for example my_job.py) as
properties.entrypoint in spark.jobs.submit, not the storage URI.
Call spark.jobs.submit with:
namespace and name — job identityproperties.entrypoint — artifact basenameproperties.entrypointArguments — optional args passed to the scriptproperties.driverMachineType, properties.executorMachineType,
properties.executorNumbers — sizing (defaults: spark.1.b, 2 executors)confirm: trueThe response includes runId and initial state (typically SUBMITTED).
Cluster is always oleander-managed serverless Spark.
Poll until the run reaches a terminal state (COMPLETE, FAIL, or ABORT):
jobs.runs.get with the run_id from submitRelated tools after submit:
jobs.runs.list — recent runs for a namespace + job namejobs.logs.get — driver and executor logsjobs.traces.get — OpenTelemetry tracesjobs.cost.get — run cost breakdownjobs.lineage.get — datasets read and writtenAlways gather cost and lineage for completed runs before presenting final output to the user.
Call spark.jobs.abort with run_id and confirm: true to stop an active
run. Check state with jobs.runs.get first if unsure whether it is still
running.
Upload a script and submit it from the terminal:
oleander spark jobs submit my_job.py \
--namespace my_namespace \
--name my-job-name \
--wait
With arguments passed to the script:
oleander spark jobs submit my_job.py \
--namespace my_namespace \
--name my-job-name \
--wait \
--args "--input-table oleander.default.sf_311 --output-catalog oleander.results"
--wait blocks until the run reaches a terminal state (COMPLETE, FAIL, or ABORT).
With explicit driver and executor sizing:
oleander spark jobs submit my_job.py \
--namespace my_namespace \
--name my-job-name \
--driverMachineType spark.8.c \
--executorMachineType spark.8.c \
--executorNumbers 4 \
--wait
Use @oleanderhq/sdk to submit jobs programmatically:
import { Oleander, RunNotFoundError } from "@oleanderhq/sdk";
const oleander = new Oleander(); // reads OLEANDER_API_KEY from env
const { runId } = await oleander.submitSparkJob({
cluster: "oleander",
namespace: "my_namespace",
name: "my-job-name",
entrypoint: "my_job.py",
});
Submit and wait for completion with built-in polling:
const result = await oleander.submitSparkJobAndWait({
cluster: "oleander",
namespace: "my_namespace",
name: "my-job-name",
entrypoint: "my_job.py",
});
When not using submitSparkJobAndWait, poll manually with getRun:
import { Oleander, RunNotFoundError } from "@oleanderhq/sdk";
const oleander = new Oleander();
const { runId } = await oleander.submitSparkJob({ ... });
const started = Date.now();
const timeoutMs = 900_000; // 15 minutes
let notFoundRetries = 10;
while (Date.now() - started < timeoutMs) {
await wait.for({ seconds: 60 });
try {
const run = await oleander.getRun(runId);
const state = run.state ?? "";
if (state === "COMPLETE" || state === "FAIL" || state === "ABORT") {
return { runId, state, run };
}
} catch (error) {
if (error instanceof RunNotFoundError) {
notFoundRetries--;
if (notFoundRetries <= 0) throw error;
continue; // run may not be visible yet; retry
}
throw error;
}
}
throw new Error(`Timeout waiting for run ${runId}`);
Always handle RunNotFoundError — a freshly submitted run may not be immediately visible.
Machine types follow the pattern spark.<size>.<class>. Default: spark.1.b for both driver and executors.
Compute (c) — 2:1 RAM:vCPU, CPU-bound transformations:
| Type | vCPU | RAM |
|---|---|---|
| spark.1.c | 1 | 2 GB |
| spark.2.c | 2 | 4 GB |
| spark.4.c | 4 | 8 GB |
| spark.8.c | 8 | 16 GB |
| spark.16.c | 16 | 32 GB |
Balanced (b) — 4:1 RAM:vCPU, general purpose:
| Type | vCPU | RAM |
|---|---|---|
| spark.1.b | 1 | 4 GB |
| spark.2.b | 2 | 8 GB |
| spark.4.b | 4 | 16 GB |
| spark.8.b | 8 | 32 GB |
| spark.16.b | 16 | 64 GB |
Memory (m) — 8:1 RAM:vCPU, joins/aggregations that spill:
| Type | vCPU | RAM |
|---|---|---|
| spark.1.m | 1 | 8 GB |
| spark.2.m | 2 | 16 GB |
| spark.4.m | 4 | 30 GB |
| spark.8.m | 8 | 60 GB |
| spark.16.m | 16 | 120 GB |
Run a single SQL query against the lake and print results as a table:
oleander query "SELECT * FROM oleander.my_namespace.my_table LIMIT 20"
Save results as a new table (named by query hash):
oleander query "SELECT id, sum(value) FROM oleander.my_namespace.my_table GROUP BY 1" --save
Launch a full DuckDB REPL with all registered catalogs pre-attached:
oleander duckdb
argparse arguments, not hardcoded.sys.exit(2)), not just a log message.Use lake-query to explore your data; compare seasonal revenue, analyze product changes, count new user signups, or find whatever answers are hidden in your data.
Run Polars queries or scripts on oleander, locally or distributed, and save results to the lake catalog.
Engine-agnostic guidance for working with the oleander lake catalog, including naming conventions, catalog hierarchy, and table reference patterns.
Spark-specific patterns for reading and writing oleander lake catalog tables, including append vs overwrite, avoiding driver writes, and reusable table naming.
General Apache Spark best practices for scalable, maintainable, and performant DataFrame jobs.
oleander-specific Spark guidance for connected OpenLineage, collect() pitfalls, and environment variable usage.
基于 SOC 职业分类