其实方案有三种:

  1. 外部数据导入方案
  2. 基于scroll+bulk+索引别名
  3. Reindex API 方案

第一种方案对数据库的压力和ES服务器压力都大,所以不做介绍

基于scroll+bulk+索引别名

  1. 若Java客户端没有使用别名,需要给客户端分配一个: PUT /book/_alias/book_alias
  2. 新建索引book_new,将mapping信息,settings信息等按新的要求全部定义好。
  3. 使用scroll api将数据批量查询出来

    为了使用 scroll,初始搜索请求应该在查询中指定 scroll 参数,这可以告诉 Elasticsearch 需要 保持搜索的上下文环境多久,1m 就是一分钟。

  1. GET /book/_search?scroll=1m
  2. {
  3. "query": {
  4. "match_all": {}
  5. },
  6. "sort": [
  7. "_doc"
  8. ],
  9. "size": 2
  10. }
  1. 采用bulk api将scoll查出来的一批数据,批量写入新索引

    1. POST /_bulk
    2. { "index":
    3. {
    4. "_index": "book_new", "_id": "对应的id值"
    5. }
    6. }
    7. { 查询出来的数据值 }
  2. 反复执行修改后的步骤3和步骤4,查询一批导入一批,以后可以借助Java Client或其他语言的API支持。

    1. GET /_search/scroll
    2. {
    3. "scroll": "1m",
    4. "scroll_id" : "步骤三中查询出来的值"
    5. }
  3. 切换别名book_alias到新的索引book_new上面,此时Java客户端仍然使用别名访问,也不需要修改任何代码,不需要停机。

    1. POST /_aliases
    2. {
    3. "actions": [
    4. {
    5. "remove": {
    6. "index": "book",
    7. "alias": "book_alias"
    8. }
    9. },
    10. {
    11. "add": {
    12. "index": "book_new",
    13. "alias": "book_alias"
    14. }
    15. }
    16. ]
    17. }
  4. 验证别名查询的是否为新索引的数据

Reindex API 方案

基础命令

  1. POST _reindex
  2. {
  3. "source": {
  4. "index": "book"
  5. },
  6. "dest": {
  7. "index": "book_new"
  8. }
  9. }

如果不手动创建新索引book_new的mapping信息,那么Elasticsearch将启动自动映射模板对数据进行类型映射,可能不是期望的类型,这点要注意一下。

version_type

使用reindex api也是创建快照后再执行迁移的,这样目标索引的数据可能会与原索引有差异, version_type属性可以决定乐观锁并发处理的规则。

  1. POST _reindex
  2. {
  3. "source": {
  4. "index": "book"
  5. },
  6. "dest": {
  7. "index": "book_new",
  8. "version_type": "internal"
  9. }
  10. }

version_type属性含义如下:

  • internal:直接拷贝文档到目标索引,对相同的type、文档ID直接进行覆盖,默认值
  • external:迁移文档到目标索引时,保留version信息,对目标索引中不存在的文档进行创建,已存在的文档按version进行更新,遵循乐观锁机制。

    op_type 属性和conflflicts 属性

    如果op_type设置为create,那么迁移时只在目标索引中创建ID不存在的文档,已存在的文档,会提示 错误,如下请求:
    1. POST _reindex
    2. {
    3. "source": {
    4. "index": "book"
    5. },
    6. "dest": {
    7. "index": "book_new",
    8. "op_type": "create"
    9. }
    10. }
    如果加上”conflflicts”: “proceed”配置项,那么冲突信息将不展示,只展示冲突的文档数量
    1. POST _reindex
    2. {
    3. "conflicts": "proceed",
    4. "source": {
    5. "index": "book"
    6. },
    7. "dest": {
    8. "index": "book_new",
    9. "op_type": "create"
    10. }
    11. }

    query支持

    1. POST _reindex
    2. {
    3. "size": 100,
    4. "source": {
    5. "index": "book",
    6. "query": {
    7. "term": {
    8. "language": "english"
    9. }
    10. },
    11. "sort": {
    12. "likes": "desc"
    13. }
    14. },
    15. "dest": {
    16. "index": "book_new"
    17. }
    18. }