前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Elasticsearch 重建索引 数据迁移

Elasticsearch 重建索引 数据迁移

原创
作者头像
六月的雨在Tencent
发布2024-11-30 21:57:44
发布2024-11-30 21:57:44
4030
举报

好事发生

今天要分享的好事文章是一篇关于Java线程池底层源码的内容,文章标题【Java线程池底层源码与源码解析】,文章链接:https://cloud.tencent.com/developer/article/2472467 这篇文章通过对话形式,深入浅出地解析了Java线程池的底层源码与源码,涵盖了线程池的概述、功能点、背景、业务点、底层原理、示例、优缺点以及总结,信息量大且结构清晰,提供了多个示例代码,可以帮助读者更好地理解和应用线程池。

下面来开始我今天的正文吧...

众所周知,Elasticsearch(ES)中的索引一旦创建完成,便无法进行修改,这包括字段属性和分词方式等关键配置。然而,随着业务数据的不断增长,我们有时会遇到需要修改现有索引或实际上进行索引重建的情形。面对这种情况,我们应该如何应对呢?本文将围绕这一主题展开深入探讨和处理建议。

处理流程概述

重建索引的整体处理流程可以概括为以下几个步骤:首先,创建一个新的临时索引;接着,将原始索引中的数据逐步迁移至这个临时索引中;然后,删除原有的索引;随后,重新创建一个与原始索引结构相同的索引;最后,将临时索引中的数据迁回至新创建的索引中。通过这一系列操作,我们便能够顺利完成索引的重建工作。

操作流程

在创建索引之前,我们先看一下原始的 es 索引结构,在 kibana 开发工具命令行页面执行命令

代码语言:txt
复制
GET crm_meiqia_conversation/_mapping

在本例中,我们的目标是将字段 convId 的数据类型更改为 text。该字段的原始属性

为实现这一变更,我们需要遵循以下步骤:

创建临时索引

首先,创建一个名为 crm_meiqia_conversation_tmp 的临时索引,并在其中将 convId 字段的数据类型设置为 text。

代码语言:txt
复制
PUT /crm_meiqia_conversation_tmp
{
  "mappings" : {
      "meiqiaConversation" : {
        "properties" : {
          "convId" : {
            "type" : "text"
          },
          "enterpriseId" : {
            "type" : "long"
          },
          "devClientId" : {
            "type" : "text"
          },
          "pageFromUrl" : {
            "type" : "text"
          },
          "pageLandUrl" : {
            "type" : "text"
          },
          "pageLandTitle" : {
            "type" : "text"
          },
          "pageConvUrl" : {
            "type" : "text"
          },
          "pageConvTitle" : {
            "type" : "text"
          },
          "searchEngineName" : {
            "type" : "text"
          },
          "searchEngineKw" : {
            "type" : "text"
          },
          "visitorIp" : {
            "type" : "text"
          },
          "visitorLocation" : {
            "type" : "text"
          },
          "visitorOs" : {
            "type" : "text"
          },
          "visitorBrowser" : {
            "type" : "text"
          },
          "visitorTags" : {
            "type" : "text"
          },
          "clientId" : {
            "type" : "long"
          },
          "agentAccount" : {
            "type" : "text"
          },
          "agentName" : {
            "type" : "text"
          },
          "agentId" : {
            "type" : "text"
          },
          "agentNickName" : {
            "type" : "text"
          },
          "groupId" : {
            "type" : "long"
          },
          "groupName" : {
            "type" : "text"
          },
          "convStartTm" : {
            "type" : "long"
          },
          "convStartDate" : {
            "type" : "date"
          },
          "convEndTm" : {
            "type" : "long"
          },
          "convEndDate" : {
            "type" : "date"
          },
          "convFirstRespWaitInSecs" : {
            "type" : "long"
          },
          "convAgentMsgCount" : {
            "type" : "long"
          },
          "convVisitorMsgCount" : {
            "type" : "long"
          },
          "convQualityGrade" : {
            "type" : "text"
          },
          "convLeads" : {
            "type" : "text"
          },
          "commentLevel" : {
            "type" : "long"
          },
          "commentContent" : {
            "type" : "text"
          },
          "platform" : {
            "type" : "text"
          },
          "summaryContent" : {
            "type" : "text"
          },
          "summaryUpdateAt" : {
            "type" : "text"
          },
          "sourceType" : {
            "type" : "text"
          },
          "sourceField" : {
            "type" : "text"
          },
          "agentRespDuration" : {
            "type" : "long"
          },
          "effective" : {
            "type" : "text"
          },
          "missed" : {
            "type" : "text"
          },
          "converseDuration" : {
            "type" : "long"
          },
          "appName" : {
            "type" : "text"
          },
          "mainChannel" : {
            "type" : "text"
          },
          "mainChannelName" : {
            "type" : "text"
          },
          "subChannel" : {
            "type" : "text"
          },
          "subChannelName" : {
            "type" : "text"
          },
          "searchEngine" : {
            "type" : "text"
          },
          "clientInfo" : {
            "properties" : {
              "address" : {
                "type" : "text"
              },
              "age" : {
                "type" : "long"
              },
              "channelName" : {
                "type" : "text"
              },
              "comment" : {
                "type" : "text"
              },
              "contact" : {
                "type" : "text"
              },
              "convId" : {
                "type" : "long"
              },
              "email" : {
                "type" : "text"
              },
              "enterpriseId" : {
                "type" : "long"
              },
              "followSource" : {
                "type" : "text"
              },
              "gender" : {
                "type" : "text"
              },
              "infoId" : {
                "type" : "long"
              },
              "jijiaoCity" : {
                "type" : "text"
              },
              "jijiaoDistrict" : {
                "type" : "text"
              },
              "jijiaoLevel" : {
                "type" : "text"
              },
              "jijiaoProvince" : {
                "type" : "text"
              },
              "mTrackId" : {
                "type" : "text"
              },
              "name" : {
                "type" : "text"
              },
              "openid" : {
                "type" : "text"
              },
              "qq" : {
                "type" : "text"
              },
              "sourceName" : {
                "type" : "text"
              },
              "tel" : {
                "type" : "text"
              },
              "trackId" : {
                "type" : "text"
              },
              "uid" : {
                "type" : "text"
              },
              "vid" : {
                "type" : "text"
              },
              "visitorName" : {
                "type" : "text"
              },
              "weibo" : {
                "type" : "text"
              },
              "weixin" : {
                "type" : "text"
              },
              "appChannel" : {
                "type" : "text"
              }
            }
          },
          "convContent" : {
            "properties" : {
              "contentId" : {
                "type" : "long"
              },
              "convId" : {
                "type" : "long"
              },
              "convFrom" : {
                "type" : "text"
              },
              "timestamp" : {
                "type" : "long"
              },
              "content" : {
                "type" : "text",
                "analyzer":"standard"
              },
              "remoteContent" : {
                "type" : "text"
              },
              "convType" : {
                "type" : "text"
              }
            }
          },
          "convTag" : {
            "properties" : {
              "tagId" : {
                "type" : "long"
              },
              "convId" : {
                "type" : "long"
              },
              "level" : {
                "type" : "long"
              },
              "value" : {
                "type" : "text"
              }
            }
          }
        }
      }
  },
  "settings" : {
      "number_of_shards":2, 
      "number_of_replicas" : 1,
      "refresh_interval":"1s"
  }
}

将编写好的es创建索引语句放在kibana 工具页面点击执行按钮

这里如果看到执行命令报错 400 ,且出现以下信息的话,根据提示信息来看 说明当前 es 中已经存在索引 crm_meiqia_conversation_tmp ,那么执行删除索引命令,删除后再执行刚才创建临时索引命令

代码语言:txt
复制
DELETE /crm_meiqia_conversation_tmp

再次执行创建临时索引命令,执行成功

数据迁移

接下来,将原始索引中的数据逐步迁移到这个临时索引中,确保 convId 字段的新数据类型得到正确应用。在临时索引创建完成之后,我们就可以将原始索引中的数据先迁移到临时索引中,通过 ES 提供了 _reindex 这个API 进行数据复制迁移,执行命令

代码语言:txt
复制
POST _reindex
{  
  "source": {  
    "index": "crm_meiqia_conversation",
    "size":500
  },  
  "dest": {  
    "index": "crm_meiqia_conversation_tmp"  
  }
}

或者 异步迁移数据

代码语言:txt
复制
POST _reindex?wait_for_completion=false
{  
  "source": {  
    "index": "crm_meiqia_conversation",
    "size":500
  },  
  "dest": {  
    "index": "crm_meiqia_conversation_tmp"  
  }
  
}

其中,source 对应的是原始索引,dest 对应的是新建的临时索引,参数 size 表示每次执行的数据量为500 条,循环执行直到数据迁移复制结束。默认情况下, _reindex 使用 1000 进行批量操作,迁移成功如图

这个时候我们再来看一下原始索引中数据总数 crm_meiqia_conversation 与临时索引 crm_meiqia_conversation_tmp 中数据总数是否一致,执行命令

代码语言:txt
复制
GET crm_meiqia_conversation/_count
GET crm_meiqia_conversation_tmp/_count

执行结果如图

那么这样就完成了数据从原始索引迁移复制到临时索引的操作。

删除原始索引

在数据迁移完成后,我们就可以安全地删除原始索引。执行如下命令

代码语言:txt
复制
# 删除原始索引
DELETE /crm_meiqia_conversation

重新创建原始索引

随后,按照新的字段类型定义重新创建一个与原始索引结构相同的索引。也就是说我们按照临时索引的 创建语句 创建新的索引,最后再将临时索引中的数据 迁移复制到 新建的原始索引中去,执行命令

代码语言:txt
复制
# 创建更改字段后的新的原始索引 
PUT /crm_meiqia_conversation
{
  "mappings" : {
      "meiqiaConversation" : {
        "properties" : {
          "convId" : {
            "type" : "text"
          },
          "enterpriseId" : {
            "type" : "long"
          },
          "devClientId" : {
            "type" : "text"
          },
          "pageFromUrl" : {
            "type" : "text"
          },
          "pageLandUrl" : {
            "type" : "text"
          },
          "pageLandTitle" : {
            "type" : "text"
          },
          "pageConvUrl" : {
            "type" : "text"
          },
          "pageConvTitle" : {
            "type" : "text"
          },
          "searchEngineName" : {
            "type" : "text"
          },
          "searchEngineKw" : {
            "type" : "text"
          },
          "visitorIp" : {
            "type" : "text"
          },
          "visitorLocation" : {
            "type" : "text"
          },
          "visitorOs" : {
            "type" : "text"
          },
          "visitorBrowser" : {
            "type" : "text"
          },
          "visitorTags" : {
            "type" : "text"
          },
          "clientId" : {
            "type" : "long"
          },
          "agentAccount" : {
            "type" : "text"
          },
          "agentName" : {
            "type" : "text"
          },
          "agentId" : {
            "type" : "text"
          },
          "agentNickName" : {
            "type" : "text"
          },
          "groupId" : {
            "type" : "long"
          },
          "groupName" : {
            "type" : "text"
          },
          "convStartTm" : {
            "type" : "long"
          },
          "convStartDate" : {
            "type" : "date"
          },
          "convEndTm" : {
            "type" : "long"
          },
          "convEndDate" : {
            "type" : "date"
          },
          "convFirstRespWaitInSecs" : {
            "type" : "long"
          },
          "convAgentMsgCount" : {
            "type" : "long"
          },
          "convVisitorMsgCount" : {
            "type" : "long"
          },
          "convQualityGrade" : {
            "type" : "text"
          },
          "convLeads" : {
            "type" : "text"
          },
          "commentLevel" : {
            "type" : "long"
          },
          "commentContent" : {
            "type" : "text"
          },
          "platform" : {
            "type" : "text"
          },
          "summaryContent" : {
            "type" : "text"
          },
          "summaryUpdateAt" : {
            "type" : "text"
          },
          "sourceType" : {
            "type" : "text"
          },
          "sourceField" : {
            "type" : "text"
          },
          "agentRespDuration" : {
            "type" : "long"
          },
          "effective" : {
            "type" : "text"
          },
          "missed" : {
            "type" : "text"
          },
          "converseDuration" : {
            "type" : "long"
          },
          "appName" : {
            "type" : "text"
          },
          "mainChannel" : {
            "type" : "text"
          },
          "mainChannelName" : {
            "type" : "text"
          },
          "subChannel" : {
            "type" : "text"
          },
          "subChannelName" : {
            "type" : "text"
          },
          "searchEngine" : {
            "type" : "text"
          },
          "clientInfo" : {
            "properties" : {
              "address" : {
                "type" : "text"
              },
              "age" : {
                "type" : "long"
              },
              "channelName" : {
                "type" : "text"
              },
              "comment" : {
                "type" : "text"
              },
              "contact" : {
                "type" : "text"
              },
              "convId" : {
                "type" : "long"
              },
              "email" : {
                "type" : "text"
              },
              "enterpriseId" : {
                "type" : "long"
              },
              "followSource" : {
                "type" : "text"
              },
              "gender" : {
                "type" : "text"
              },
              "infoId" : {
                "type" : "long"
              },
              "jijiaoCity" : {
                "type" : "text"
              },
              "jijiaoDistrict" : {
                "type" : "text"
              },
              "jijiaoLevel" : {
                "type" : "text"
              },
              "jijiaoProvince" : {
                "type" : "text"
              },
              "mTrackId" : {
                "type" : "text"
              },
              "name" : {
                "type" : "text"
              },
              "openid" : {
                "type" : "text"
              },
              "qq" : {
                "type" : "text"
              },
              "sourceName" : {
                "type" : "text"
              },
              "tel" : {
                "type" : "text"
              },
              "trackId" : {
                "type" : "text"
              },
              "uid" : {
                "type" : "text"
              },
              "vid" : {
                "type" : "text"
              },
              "visitorName" : {
                "type" : "text"
              },
              "weibo" : {
                "type" : "text"
              },
              "weixin" : {
                "type" : "text"
              },
              "appChannel" : {
                "type" : "text"
              }
            }
          },
          "convContent" : {
            "properties" : {
              "contentId" : {
                "type" : "long"
              },
              "convId" : {
                "type" : "long"
              },
              "convFrom" : {
                "type" : "text"
              },
              "timestamp" : {
                "type" : "long"
              },
              "content" : {
                "type" : "text",
                "analyzer":"standard"
              },
              "remoteContent" : {
                "type" : "text"
              },
              "convType" : {
                "type" : "text"
              }
            }
          },
          "convTag" : {
            "properties" : {
              "tagId" : {
                "type" : "long"
              },
              "convId" : {
                "type" : "long"
              },
              "level" : {
                "type" : "long"
              },
              "value" : {
                "type" : "text"
              }
            }
          }
        }
      }
  },
  "settings" : {
      "number_of_shards":2, 
      "number_of_replicas" : 1,
      "refresh_interval":"1s"
  }
}

数据回迁

最后,将临时索引中的数据迁回至新创建的索引中,完成整个重建过程。迁移复制数据 临时索引》》》新的原始索引

代码语言:txt
复制
POST _reindex
{  
  "source": {  
    "index": "crm_meiqia_conversation_tmp",
    "size":500
  },  
  "dest": {  
    "index": "crm_meiqia_conversation"  
  }
}

最后执行成功后,完成本次关于 索引 crm_meiqia_conversation 的更改字段属性 的操作

写在最后

实际上,在Elasticsearch(ES)中对索引字段进行修改确实是一项较为繁琐的任务。它要求我们先创建一个临时索引,将数据迁移过去,然后删除原索引,接着创建新的索引,并最终将数据从临时索引迁移回来。因此,在最初设计和创建ES索引时,我们就需要进行全面的考量,精确规划字段属性和索引结构,以避免未来需要进行这种复杂且耗时的操作。

此外,如果需要迁移的索引包含大量数据,那么数据的来回迁移不仅会耗费大量时间,还会占用大量的磁盘空间。如果没有足够的磁盘空间,操作可能会因磁盘不足而失败,导致错误提示。因此,在执行此类操作之前,确保有足够的存储空间是非常重要的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 好事发生
  • 处理流程概述
  • 操作流程
    • 创建临时索引
    • 数据迁移
    • 删除原始索引
    • 重新创建原始索引
    • 数据回迁
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档