Elasticsearch 实战:Bulk API 数据批量导入完整教程(百万级数据无痛导入)
-
- 前言
- 一、核心概念:Bulk API 批量导入是什么?
-
- 1.1 定义
- 1.2 批量导入核心优势
- 1.3 Bulk 批量导入执行流程图
- 二、Bulk API:批量导入基础语法格式
-
- 2.1 请求方式
- 2.2 请求地址
- 2.3 固定语法规则(必须遵守)
- 2.4 标准格式
- 三、步骤:Bulk API 批量导入完整流程
-
- 步骤1:创建索引(可选但推荐)
- 步骤2:编写 Bulk 批量导入 DSL
- 步骤3:在 Kibana / curl 执行
- 步骤4:查看结果是否成功
- 步骤5:查询数据验证
- 四、实战:Bulk API 批量导入示例(可直接运行)
-
- 4.1 Bulk API:批量导入 3 条用户数据
- 4.2 Bulk API:不带 ID 自动生成(导入更快)
- 4.3 Bulk API:批量导入同一索引(简化写法)
- 五、验证批量导入是否成功
-
- 5.1 查询所有数据
- 5.2 查看命中条数
- 六、生产级:Bulk 批量导入性能优化(百万级必备)
-
- 6.1 每批数据量建议
- 6.2 写入前关闭副本、关闭刷新
- 6.3 导入完成后恢复配置
- 6.4 使用自动生成 ID(速度更快)
- 七、Bulk 批量导入常见错误与解决方案
-
- 7.1 报错:json malformed
- 7.2 报错:mapper parsing exception
- 7.3 部分数据导入失败
- 7.4 写入超时
- 八、Bulk 批量导入 vs 单条导入 对比
- 九、总结(核心 3 条)
- 总结
|
🌺The Begin🌺点点关注,收藏不迷路🌺 |
前言
在 Elasticsearch 生产环境中,海量数据快速入库是高频场景,如日志采集、数据同步、全量初始化等。单条写入效率极低,而 Bulk API 是 ES 官方提供的批量数据导入神器,一次请求可执行上千条写入操作,性能提升 10~100 倍。
本文详细讲解如何使用 Bulk API 进行数据批量导入,包含原理、流程图、标准格式、实战案例、性能调优、常见问题,内容可直接发布 CSDN,适用于 7.x/8.x 全版本。
一、核心概念:Bulk API 批量导入是什么?
1.1 定义
Bulk API 批量导入:通过 一次 HTTP 请求,向 Elasticsearch 写入多条文档数据,减少网络开销,大幅提升写入速度,是海量数据导入的标准方案。
1.2 批量导入核心优势
1.3 Bulk 批量导入执行流程图
#mermaid-svg-ixZ7jFlvoK2KPRnB{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ixZ7jFlvoK2KPRnB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ixZ7jFlvoK2KPRnB .error-icon{fill:#552222;}#mermaid-svg-ixZ7jFlvoK2KPRnB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ixZ7jFlvoK2KPRnB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ixZ7jFlvoK2KPRnB .marker.cross{stroke:#333333;}#mermaid-svg-ixZ7jFlvoK2KPRnB svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ixZ7jFlvoK2KPRnB p{margin:0;}#mermaid-svg-ixZ7jFlvoK2KPRnB .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ixZ7jFlvoK2KPRnB .cluster-label text{fill:#333;}#mermaid-svg-ixZ7jFlvoK2KPRnB .cluster-label span{color:#333;}#mermaid-svg-ixZ7jFlvoK2KPRnB .cluster-label span p{background-color:transparent;}#mermaid-svg-ixZ7jFlvoK2KPRnB .label text,#mermaid-svg-ixZ7jFlvoK2KPRnB span{fill:#333;color:#333;}#mermaid-svg-ixZ7jFlvoK2KPRnB .node rect,#mermaid-svg-ixZ7jFlvoK2KPRnB .node circle,#mermaid-svg-ixZ7jFlvoK2KPRnB .node ellipse,#mermaid-svg-ixZ7jFlvoK2KPRnB .node polygon,#mermaid-svg-ixZ7jFlvoK2KPRnB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ixZ7jFlvoK2KPRnB .rough-node .label text,#mermaid-svg-ixZ7jFlvoK2KPRnB .node .label text,#mermaid-svg-ixZ7jFlvoK2KPRnB .image-shape .label,#mermaid-svg-ixZ7jFlvoK2KPRnB .icon-shape .label{text-anchor:middle;}#mermaid-svg-ixZ7jFlvoK2KPRnB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ixZ7jFlvoK2KPRnB .rough-node .label,#mermaid-svg-ixZ7jFlvoK2KPRnB .node .label,#mermaid-svg-ixZ7jFlvoK2KPRnB .image-shape .label,#mermaid-svg-ixZ7jFlvoK2KPRnB .icon-shape .label{text-align:center;}#mermaid-svg-ixZ7jFlvoK2KPRnB .node.clickable{cursor:pointer;}#mermaid-svg-ixZ7jFlvoK2KPRnB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ixZ7jFlvoK2KPRnB .arrowheadPath{fill:#333333;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ixZ7jFlvoK2KPRnB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ixZ7jFlvoK2KPRnB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ixZ7jFlvoK2KPRnB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ixZ7jFlvoK2KPRnB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ixZ7jFlvoK2KPRnB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ixZ7jFlvoK2KPRnB .cluster text{fill:#333;}#mermaid-svg-ixZ7jFlvoK2KPRnB .cluster span{color:#333;}#mermaid-svg-ixZ7jFlvoK2KPRnB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ixZ7jFlvoK2KPRnB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ixZ7jFlvoK2KPRnB rect.text{fill:none;stroke-width:0;}#mermaid-svg-ixZ7jFlvoK2KPRnB .icon-shape,#mermaid-svg-ixZ7jFlvoK2KPRnB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ixZ7jFlvoK2KPRnB .icon-shape p,#mermaid-svg-ixZ7jFlvoK2KPRnB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ixZ7jFlvoK2KPRnB .icon-shape .label rect,#mermaid-svg-ixZ7jFlvoK2KPRnB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ixZ7jFlvoK2KPRnB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ixZ7jFlvoK2KPRnB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ixZ7jFlvoK2KPRnB :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
准备待导入数据
按照Bulk格式组装数据
发送POST _bulk请求
ES批量写入数据
返回导入结果
验证数据是否导入成功
二、Bulk API:批量导入基础语法格式
2.1 请求方式
POST
2.2 请求地址
POST /_bulk
2.3 固定语法规则(必须遵守)
2.4 标准格式
{"index":{"_index":"索引名","_id":"文档ID"}}
{"字段1":"值1","字段2":"值2"}
{"index":{"_index":"索引名","_id":"文档ID"}}
{"字段1":"值1","字段2":"值2"}
三、步骤:Bulk API 批量导入完整流程
步骤1:创建索引(可选但推荐)
PUT /user_data
{
"settings": {
"number_of_shards": 1
},
"mappings": {
"properties": {
"name": { "type": "text" },
"age": { "type": "integer" },
"city": { "type": "keyword" }
}
}
}
步骤2:编写 Bulk 批量导入 DSL
步骤3:在 Kibana / curl 执行
步骤4:查看结果是否成功
步骤5:查询数据验证
四、实战:Bulk API 批量导入示例(可直接运行)
4.1 Bulk API:批量导入 3 条用户数据
标题格式:Bulk API:批量数据导入基础示例
POST /_bulk
{"index":{"_index":"user_data","_id":"1001"}}
{"name":"张三","age":25,"city":"北京"}
{"index":{"_index":"user_data","_id":"1002"}}
{"name":"李四","age":30,"city":"上海"}
{"index":{"_index":"user_data","_id":"1003"}}
{"name":"王五","age":28,"city":"深圳"}
4.2 Bulk API:不带 ID 自动生成(导入更快)
POST /_bulk
{"index":{"_index":"user_data"}}
{"name":"赵六","age":26,"city":"广州"}
{"index":{"_index":"user_data"}}
{"name":"钱七","age":35,"city":"杭州"}
4.3 Bulk API:批量导入同一索引(简化写法)
可以在 URL 上指定索引,内部无需重复写
POST /user_data/_bulk
{"index":{"_id":"2001"}}
{"name":"小明","age":22,"city":"成都"}
{"index":{"_id":"2002"}}
{"name":"小红","age":24,"city":"重庆"}
五、验证批量导入是否成功
5.1 查询所有数据
GET /user_data/_search
{
"query": {
"match_all": {}
}
}
5.2 查看命中条数
hits.total.value 显示导入数量,即代表成功。
六、生产级:Bulk 批量导入性能优化(百万级必备)
6.1 每批数据量建议
- 每批 500~1000 条
- 总大小 5MB~15MB
6.2 写入前关闭副本、关闭刷新
PUT /user_data/_settings
{
"number_of_replicas": 0,
"refresh_interval": "-1"
}
6.3 导入完成后恢复配置
PUT /user_data/_settings
{
"number_of_replicas": 1,
"refresh_interval": "1s"
}
6.4 使用自动生成 ID(速度更快)
不指定 _id,ES 自动生成,写入性能提升 30%+。
七、Bulk 批量导入常见错误与解决方案
7.1 报错:json malformed
- 原因:格式错误、空行、换行不对
- 解决:严格遵循 一行操作 + 一行数据
7.2 报错:mapper parsing exception
- 原因:字段类型不匹配
- 解决:检查索引映射类型
7.3 部分数据导入失败
- 原因:ID 冲突、字段缺失
- 解决:查看返回结果 errors:true
7.4 写入超时
- 原因:批次太大
- 解决:减少每批条数
八、Bulk 批量导入 vs 单条导入 对比
| 单条导入 | N | 极慢 | 测试、少量数据 |
| Bulk 批量导入 | 1 | 极快 | 生产、海量数据 |
九、总结(核心 3 条)
总结

|
🌺The End🌺点点关注,收藏不迷路🌺 |






