Elasticsearch:搜索视图、查询契约与 PIT 实验
教学源码基线 Elasticsearch 8.15.1 / Lucene 9.11.1。入口分为不访问服务的有限模型与访问现有服务的实验,两个结果不能互相替代。机制与源码见Elasticsearch 正文。
下载完整输入
从仓库根目录运行下列命令。单独下载时把五份文件放在同一目录,运行 bash run.sh --model 或 bash run.sh --service;脚本按自身位置读取依赖。
- run.sh:公开命令,依赖 Bash 与 Python 3.9+。
- fixture.json:a/b 同时间、c 后时间、PIT 打开后插入 d;object/nested 对照和恢复条件。
- model.py:Python 标准库有限模型。
- verify_service.py:Python 标准库 HTTP 真服务断言,无需 pip 包、curl 或 ES CLI。
- compose.yaml:可选隔离单节点 8.15.1,绑定
127.0.0.1:19200。
无服务也能运行的模型
服务模式默认严格核对 8.15.1/9.11.1。其他 ES 8.x 可以显式传 --server-version 指定精确运行版本;输出仍保留教材源码基线和实际 ES/Lucene 版本,不把新版 API 结果当作固定 tag 的实机证明。
bash labs/data-senior/elasticsearch/run.sh --model输入三份文档后尚未发布搜索视图,模型中 realtime GET 为 true、search 为 0;发布后为 3。第一次版本条件更新成功、第二次同条件冲突,版本停在 2。对象字段跨元素命中 a/b,同元素只命中 a。PIT 固定为 a/b/c,实时视图加入 d 后为 a/b/d/c。12 片、from=100000,size=20 的候选上界为 1,200,240。恢复四例中仅同 history、完整操作且 lease 覆盖起点的 complete 例为 true。此处只覆盖给定非空 lease 的子集,不模拟无 lease 分支或完整恢复协议。
入口带字面断言,失败返回非零。它只检验这些有限输入下的谓词、视图副本与算术;没有执行 analyzer、Lucene、translog、fsync、分片复制、选举或真实 PIT。
已有服务的断言入口
先由学习者准备独立实验服务,再运行:
bash labs/data-senior/elasticsearch/run.sh --service
# 若独立实验服务使用默认端口,显式指定;脚本不启动或修改服务配置。
bash labs/data-senior/elasticsearch/run.sh --service --url http://127.0.0.1:9200服务模式先只读根版本,默认要求 8.15.1/9.11.1 才写入。每次生成 UUID 名 study-t18-es-…,写前定向检查名称不存在,仅创建本次索引:1 primary、0 replica、refresh_interval=-1 与显式 mapping。这是本实验索引设置,不修改集群默认配置。顺序与断言为:
- 插 a/b/c,realtime GET 找到 a,refresh 前 search=0,显式 refresh 后=3。
match name:apple=2;对 text 发整串term "Red Apple"=0;keywordname.raw精确匹配=1。- 普通 object 的 color/red 两条件命中 2,nested 同元素命中 1。
- 第一次携
_seq_no/_primary_term更新成功;重用旧值得 409 version_conflict_engine_exception,GET 的业务 version 仍为 2。 - 打开 PIT 后插 d 并 refresh;实时搜索为 4,PIT 分两页仍恰好 a/b/c。用
created_at,item_id排序,将返回的完整 sort 数组(含 PIT tie-breaker)原样传search_after,不裁掉_shard_doc。
输出 JSON 记录实际版本、完成断言与 sort 数组。mapping 内存本次 owner 标记;finally 关闭当前 PIT,定向读取已尝试创建的索引,核对 owner 后仅 DELETE 本次 UUID 索引,并 GET 确认 404。这样创建成功但响应丢失时仍可检查归属;显式冲突或 owner 不同拒删。不使用通配删除。清理时断网或强杀进程仍可能留下本次索引,不能据 finally 承诺绝无遗留,报告会记录 namespace 和清理错误。
可选隔离容器与实际范围
compose.yaml 要求可用 Docker daemon 和镜像。它关闭认证仅为本机隔离教学,不用于生产;项目名应唯一,勿复用日常服务项目。若学习者选择运行,先确认 19200 未占用:
es_project="t18-es-$(python3 -c 'import uuid; print(uuid.uuid4().hex[:12])')"
docker compose -p "$es_project" -f labs/data-senior/elasticsearch/compose.yaml up -d
# 等待服务就绪后执行 --service,结束只关闭这个专用项目。
docker compose -p "$es_project" -f labs/data-senior/elasticsearch/compose.yaml down2026-10-23 实际结果:有限模型及其公开命令测试通过;服务入口访问 19200 返回 Connection refused,未创建索引,9200 的只读端口探测也拒绝。Docker CLI 29.8.2 存在,但当前 OrbStack daemon socket 不存在;本轮未拉镜像、启动容器、安装软件或改动用户服务。真服务脚本已做语法检查,所有服务断言仍待可用环境验证。
单节点即使跑通也只验证上述 API 语义,不证明多副本成功 ACK、主故障、global checkpoint、retention lease 实际恢复、断电耐久或压力 P99。flush/merge 与复制恢复应另在有故障注入权限的隔离多节点环境验证。
T37 本机服务复核(2026-10-24)
bash labs/data-senior/elasticsearch/run.sh --service --url http://127.0.0.1:9200 --server-version 8.19.23已在用户已有 Elasticsearch 8.19.23 / Lucene 9.12.2 单节点执行全部 API 断言:refresh 前后 0/3、match/term/keyword 2/0/1、object/nested 2/1、过期版本条件 409、实时搜索 4 而 PIT 仍恰为 a/b/c。报告保存服务器返回的完整 sort 数组;PIT 已关闭,本次 UUID 索引已定向删除并检查 404。默认基线预检在该服务上按预期拒绝,未写入。没有修改服务配置或其他索引;未进行多副本、切主、断电或恢复故障试验。