4. 索引与数据模型验收

索引与数据模型验收是 Elastic 数据平台交付中最容易被“能写入就算通过”掩盖的一环。真正需要验收的不是索引是否存在,而是索引模板是否可复用、映射是否与查询方式匹配、分片与副本是否与集群规模和数据量匹配、生命周期策略是否真正生效、数据流与别名是否支撑了读写分离与滚动切换。本节围绕这五个检查面展开,给出可执行的评审与验证方法。

一、索引模板与映射设计评审

索引模板验收的核心是“模板能否被正确命中,映射是否与业务字段一致”。评审时先确认模板的匹配模式与优先级:可组合模板(composable template)由 index_patterns、priority、template 三部分构成,多个模板命中同一索引时按 priority 从高到低合并,高优先级覆盖低优先级。验收时应构造一个真实索引名,用 _index_template 模拟命中,确认最终生效的 settings 与 mappings 与设计一致。

PUT _index_template/order_logs_tpl
{
  "index_patterns": ["order-logs-*"],
  "priority": 200,
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1,
      "refresh_interval": "10s"
    },
    "mappings": {
      "dynamic": "strict",
      "properties": {
        "order_id":   { "type": "keyword" },
        "amount":     { "type": "scaled_float", "scaling_factor": 100 },
        "created_at": { "type": "date", "format": "epoch_millis" },
        "status":     { "type": "keyword" },
        "remark":     { "type": "text", "analyzer": "ik_max_word" }
      }
    }
  }
}

映射评审要重点看三类问题:一是把仅用于精确过滤的字段误设为 text,导致聚合和排序失效;二是把高基数字段设为 keyword 并开启 fielddata,造成堆内存压力;三是 dynamic 未设为 strict,导致脏字段被自动映射。验收时可用 GET order-logs-000001/_mapping 与设计文档逐字段比对,并检查是否存在 dynamic: true 的意外字段。

二、分片与副本策略验证

分片数不是越大越好。验收时要结合数据量、节点数和查询模式判断。经验上单分片大小控制在 10GB~50GB,分片总数与节点数保持合理比例,避免“分片过多导致集群状态膨胀”。副本数则直接决定高可用与查询吞吐:副本为 0 时节点故障即数据不可用,副本为 1 可容忍单节点故障,副本为 2 适合读多写少场景。

验证方法:用 _cat/shards 查看分片分布是否均匀,用 _cat/allocation 确认各节点分片数与磁盘占用是否倾斜。若发现某节点分片数明显偏高,应检查分片分配过滤或节点角色配置。对于写入量大的索引,可先设副本为 0 完成批量导入,再调回副本数,减少写入放大。

三、生命周期策略配置

ILM 验收要确认策略是否真正绑定到索引或数据流,以及各阶段动作是否按预期触发。一个典型的日志类策略包含 hot、warm、cold、delete 四个阶段:hot 阶段滚动写入,warm 阶段降低副本并 force merge,cold 阶段迁移到低配节点,delete 阶段按保留期删除。

PUT _ilm/policy/order_logs_policy
{
  "policy": {
    "phases": {
      "hot":    { "actions": { "rollover": { "max_primary_shard_size": "30gb", "max_age": "1d" } } },
      "warm":   { "min_age": "3d", "actions": { "shrink": { "number_of_shards": 1 }, "forcemerge": { "max_num_segments": 1 } } },
      "delete": { "min_age": "30d", "actions": { "delete": {} } }
    }
  }
}

验收时用 GET order-logs-*/_ilm/explain 查看每个索引所处阶段、是否满足推进条件、是否有错误。常见问题是 min_age 从滚动时间起算而非创建时间,导致阶段推进比预期晚;以及 rollover 条件未满足时索引长期停留在 hot 阶段。

四、数据流与别名设计

数据流(data stream)是面向时序数据的写入抽象,背后由多个隐藏索引组成,写入时自动路由到当前写索引,读取时通过数据流名称跨全部后备索引查询。验收要确认:数据流是否绑定了正确的索引模板与 ILM 策略,写索引是否可正常滚动,别名是否指向数据流而非单个索引。

别名设计要区分读写:写别名只指向当前写索引,读别名可指向数据流或一组索引。验收时用 GET _data_stream/order-logs 查看后备索引列表,用 POST order-logs/_rollover 验证滚动是否成功,并确认滚动后旧索引仍可被读别名检索到。

索引与数据模型验收:五个检查面与数据流关系 写入客户端 POST order-logs/_doc 数据流 order-logs 写别名 → 当前写索引 读别名 → 全部后备索引 索引模板 index_patterns / priority settings + mappings ILM 生命周期策略 hot → warm → delete rollover / shrink / forcemerge 后备索引(写) .ds-order-logs-000001 3 主分片 / 1 副本 后备索引(只读) .ds-order-logs-000002 已 shrink / forcemerge 后备索引(待删) .ds-order-logs-000003 超过 30d 后删除 查询客户端 GET order-logs/_search 跨全部后备索引 验收检查面 模板与映射 命中 / 字段类型 分片与副本 分布 / 容量 生命周期策略 阶段 / 推进条件 数据流与别名 读写分离 / 滚动 字段与查询 类型匹配

五、字段类型与查询性能匹配

字段类型选择直接决定查询能否走索引。验收时要按查询模式反推字段类型:精确过滤与聚合用 keyword,全文检索用 text 并配置合适分词器,数值范围查询用数值类型,时间范围用 date。若把 order_id 设为 text,则 term 查询会因分词而失配;若把 status 设为 text,则 terms 聚合会因字段数据加载而变慢。

性能验证可用 _search 的 profile 参数查看查询在各分片上的耗时分布,确认是否命中索引而非全表扫描。对于高基数 keyword 字段,应避免开启 fielddata,改用 doc_values 支撑排序与聚合。验收结论应落到“字段类型—查询方式—性能表现”三者一致,而不是只看映射是否合法。

验收时建议按“模板命中 → 映射比对 → 分片分布 → ILM 阶段 → 数据流滚动 → 查询 profile”顺序逐项留痕,每项记录实际命令与输出,形成可复核的验收证据链。

综合来看,索引与数据模型验收不是单点检查,而是从写入路径到查询路径的贯通验证。模板与映射决定数据如何被组织,分片与副本决定数据如何被分布与容错,ILM 决定数据如何随时间演进,数据流与别名决定读写如何解耦,字段类型决定查询能否高效执行。五者一致,索引层才算真正通过验收。