数据平台与调度实验二:真实 Spark 与 Jupyter kernel
教材正文:执行引擎与 Notebook 内核:Spark 提交监控、Flink/Hive 对照与 kernel 生命周期。本目录提供可复现的公开实验:真实 Spark 4.0.1(local[2]) 任务与真实 Jupyter kernel,观察提交、状态、产物与内核生命周期,以及三者错位时的表现。
前置条件
| 依赖 | 要求 | 说明 |
|---|---|---|
| MySQL | 8.x,root 可空密码连接 127.0.0.1:3306 | 本机 DBngin;可用 MYSQL_HOST/PORT/USER/PASSWORD/MYSQL_BIN 覆盖 |
| JDK | 21(Spark 4.0.1 要求 17+) | 通过 /usr/libexec/java_home -v 21 或 JAVA_HOME |
| Python | 3.9+(系统 python3 即可) | 脚本自己建 venv 装 jupyter_client/ipykernel/pymysql |
| 磁盘 | 约 1.5GB | Spark 发行包 550MB + 解压 + venv |
| 网络 | 首次运行 | 下载 Spark 发行包(SHA-512 校验)与 pip 包;之后走缓存 |
| zstd | 命令行可用 | 解压 Spark 4 的 v2 事件日志(brew install zstd) |
不启动 YARN/K8s/Flink/Hive 集群;Flink/Hive 只做固定版本源码与文档对照(见正文,标"未运行")。
一条命令
实验代码sh
python3 labs/data-engine/run.py退出码 0 表示 6 组场景全部通过;证据写到 evidence/u86-2026-10-28.json(环境、每场景观察、清理结果、jar/发行包哈希)。失败运行也落盘(exitCode != 0),清理不完整同样使退出码非 0。孤儿库(此前失败运行残留的 study_u86_*)会被本次运行定向清理。
六组场景与真实观察
| 场景 | 观察 | 证据(2026-10-28,exit 0) |
|---|---|---|
| Spark 成功闭环 | 真实聚合 3 行/2 distinct,driver 经 pymysql 写结果行与元表 SUCCESS | sparkOk exit=0 meta=SUCCESS result=success-payload rows=3 distinct=2 |
| 元表成功、结果丢失 | 元表 SUCCESS 而结果行被删 | metaResultMissing meta=SUCCESS resultRows=0 |
| 先标记后执行的失败 | 计算前写 SUCCESS,Spark 失败退出 1,对账改正 | failedMeta exit=1 metaDuringRun=SUCCESS ... metaAfterReconcile=FAILED |
| Spark 事件日志 | job/stage/task 状态与 application 结束 | sparkEventLog jobs=4 jobResults=['JobSucceeded'] stages=4 tasks=5 taskStatuses=['SUCCESS'] appEnd=True |
| kernel 生命周期 | start/execute/interrupt/shutdown 全链路 | kernelLifecycle exec_result=42 interrupt_status=error interrupt_seconds=0.1 state_kept=True kernel_exitcode_after_shutdown=0 |
| kernel 崩溃 | SIGKILL 后会话记录仍显示成功、下一次执行断连 | kernelCrash exit_after_kill=-9 session_record_still_says_success=True new_exec_status=error: Empty |
边界与构造说明
- Spark 为 local[2]:driver 与 executor 同 JVM,无资源协商/跨进程调度/executor 丢失等集群故障;集群模式结论不外推。
- 元数据/结果不一致是实验构造:
job_meta模拟调度侧登记,job_results模拟引擎产物;不是某个生产系统的 bug 复现。 - kernel 崩溃是 SIGKILL 注入,只覆盖"进程死→变量丢失";"记录仍在"用脚本落盘的一份执行记录文件演示,不是 Jupyter 内建能力,也不代表 JupyterHub 多用户行为。
- 未运行:Spark REST/History Server/UI、YARN/K8s、Flink 任何形态、Hive/HiveServer2/Metastore、JupyterHub、kernel message 模式 interrupt、Windows。
- 版本差异:Spark 4 事件日志为 v2 zstd 滚动格式,读取工具需按版本分别实现(本实验未对照 Spark 3.x 读取器);jupyter_client 8.x 的 KernelManager 不再暴露
km.kernel,进程要从km.provisioner.process取。 - 所有任务、库名、标签为合成数据;独有库结束即 DROP,venv 与 Spark 发行包放在仓库外缓存。
- 孤儿库清理会 DROP 所有
study_u86_*命名空间的库:同一时刻只应有一个 U86 运行实例。
目录
| 文件 | 用途 |
|---|---|
| run.py | 公开入口:建库、下载/校验 Spark、建 venv、6 组场景、证据落盘、定向清理 |
| u86-2026-10-28.json | 一次完整运行的证据(环境、场景观察、清理、哈希) |
Spark 任务脚本由 run.py 在运行时生成(runtime/tasks/*.py),不随仓库分发;源码在脚本中以模板字符串形式可审阅。