OpenSearch重新索引需执行两次才能完成的原因咨询
问题:OpenSearch重新索引首次仅同步部分文档的原因
背景信息
我的OpenSearch域中有一个名为shakespeare的索引,包含4998条文档,执行计数请求结果如下:
GET /shakespeare/_count { "count" : 4998, "_shards" : { "total" : 5, "successful" : 5, "skipped" : 0, "failed" : 0 } }
首次重新索引操作及结果
我尝试将该索引重新索引到new_index中,执行的操作及结果如下:
PUT new_index POST _reindex { "source":{ "index":"shakespeare" }, "dest":{ "index":"new_index" } } # 执行结果 { "took" : 309, "timed_out" : false, "total" : 4998, "updated" : 0, "created" : 999, "deleted" : 0, "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ { "index" : "new_index", "id" : "29", "cause" : { "type" : "illegal_argument_exception", "reason" : "mapper [speech_number] cannot be changed from type [text] to [long]" }, "status" : 400 } ] }
可以看到首次操作仅创建了999条文档(数量稳定在997-999之间),同时返回了字段类型冲突的异常。
再次执行重新索引的结果
再次执行相同的重新索引操作后,剩余文档全部同步完成:
# 执行结果 { "took" : 855, "timed_out" : false, "total" : 4998, "updated" : 999, "created" : 3999, "deleted" : 0, "batches" : 5, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ] }
原因分析
- 首次执行
_reindex时,new_index是自动创建的,OpenSearch会根据第一批写入的文档自动生成字段映射。第一批文档的speech_number字段被推断为text类型。 - 当处理到ID为29的文档时,该文档的
speech_number是数值类型(long),与已生成的text类型映射冲突,触发illegal_argument_exception异常,导致当前批量写入批次直接终止。 - 由于
_reindex默认在单文档写入失败时,会停止当前批次内剩余文档的处理,因此仅完成了前999条文档的写入。 - 再次执行
_reindex时,new_index的字段映射已经固定为speech_number:text。此时写入数值类型的speech_number时,OpenSearch会自动将数值转为字符串存入对应字段,不再触发类型冲突异常。同时,_reindex会对已存在的999条文档执行更新操作,剩余3999条未写入的文档则成功创建,最终完成全量同步。
内容的提问来源于stack exchange,提问作者YoavKlein
相关产品推荐
相关产品推荐

