Logstash 迁移索引元数据(设置和映射)

https://help.aliyun.com/zh/es/use-cases/use-logstash-to-migrate-full-or-incremental-data-from-self-managed-elasticsearch-to-alibaba-cloud-elasticsearch

在进行数据迁移时,Logstash会帮助您自动创建索引,但是自动创建的索引可能与您待迁移的索引存在差异,导致迁移前后数据的格式不一致。因此建议您在数据迁移前,在阿里云Elasticsearch中手动创建目标索引,确保迁移前后索引数据完全一致。

您可以通过Python脚本创建目标索引,具体操作步骤如下:

适配 Python 3.10.9

bash 复制代码
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:indiceCreate.py
import base64
import http.client
import json

## 源集群host。
oldClusterHost = "localhost:9200"
## 源集群用户名,可为空。
oldClusterUserName = "elastic"
## 源集群密码,可为空。
oldClusterPassword = "xxxxxx"
## 目标集群host,可在阿里云Elasticsearch实例的基本信息页面获取。
newClusterHost = "jiankunking****.elasticsearch.aliyuncs.com:9200"
## 目标集群用户名。
newClusterUser = "elastic"
## 目标集群密码。
newClusterPassword = "xxxxxx"
DEFAULT_REPLICAS = 0


def httpRequest(method, host, endpoint, params="", username="", password=""):
    conn = http.client.HTTPConnection(host)
    headers = {}
    if (username != ""):
        'Hello {name}, your age is {age} !'.format(name='Tom', age='20')
        up = ('{username}:{password}'.format(username=username, password=password))
        # print(up)
        # print(up.encode())
        # base64string = base64.encodestring(
        #     up.encode()).replace('\n', '')
        base64string = base64.b64encode(up.encode()).decode()
        print(base64string)
        headers["Authorization"] = "Basic %s" % base64string;
    if "GET" == method:
        headers["Content-Type"] = "application/x-www-form-urlencoded"
        conn.request(method=method, url=endpoint, headers=headers)
    else:
        headers["Content-Type"] = "application/json"
        conn.request(method=method, url=endpoint, body=params, headers=headers)
    response = conn.getresponse()
    res = response.read()
    return res


def httpGet(host, endpoint, username="", password=""):
    return httpRequest("GET", host, endpoint, "", username, password)


def httpPost(host, endpoint, params, username="", password=""):
    return httpRequest("POST", host, endpoint, params, username, password)


def httpPut(host, endpoint, params, username="", password=""):
    return httpRequest("PUT", host, endpoint, params, username, password)


def getIndices(host, username="", password=""):
    endpoint = "/_cat/indices"
    indicesResult = httpGet(oldClusterHost, endpoint, oldClusterUserName, oldClusterPassword)
    indicesList = indicesResult.decode().split("\n")
    indexList = []
    for indices in indicesList:
        if (indices.find("open") > 0):
            indexList.append(indices.split()[2])
    return indexList


def getSettings(index, host, username="", password=""):
    endpoint = "/" + index + "/_settings"
    indexSettings = httpGet(host, endpoint, username, password)
    print(index + "  原始settings如下:\n" + indexSettings.decode())
    settingsDict = json.loads(indexSettings)
    ## 分片数默认和源集群索引保持一致。
    number_of_shards = settingsDict[index]["settings"]["index"]["number_of_shards"]
    ## 副本数默认为0。
    number_of_replicas = DEFAULT_REPLICAS
    newSetting = "\"settings\": {\"number_of_shards\": %s, \"number_of_replicas\": %s}" % (
        number_of_shards, number_of_replicas)
    return newSetting


def getMapping(index, host, username="", password=""):
    endpoint = "/" + index + "/_mapping"
    indexMapping = httpGet(host, endpoint, username, password)
    print(index + " 原始mapping如下:\n" + indexMapping.decode())
    mappingDict = json.loads(indexMapping)
    mappings = json.dumps(mappingDict[index]["mappings"])
    newMapping = "\"mappings\" : " + mappings
    return newMapping


def createIndexStatement(oldIndexName):
    settingStr = getSettings(oldIndexName, oldClusterHost, oldClusterUserName, oldClusterPassword)
    mappingStr = getMapping(oldIndexName, oldClusterHost, oldClusterUserName, oldClusterPassword)
    createstatement = "{\n" + str(settingStr) + ",\n" + str(mappingStr) + "\n}"
    return createstatement


def createIndex(oldIndexName, newIndexName=""):
    if (newIndexName == ""):
        newIndexName = oldIndexName
    createstatement = createIndexStatement(oldIndexName)
    print("新索引 " + newIndexName + " 的setting和mapping如下:\n" + createstatement)
    endpoint = "/" + newIndexName
    createResult = httpPut(newClusterHost, endpoint, createstatement, newClusterUser, newClusterPassword)
    print("新索引 " + newIndexName + " 创建结果:" + createResult.decode())


## main
indexList = getIndices(oldClusterHost, oldClusterUserName, oldClusterPassword)
systemIndex = []
for index in indexList:
    if (index.startswith(".")):
        systemIndex.append(index)
    else:
        createIndex(index, index)
if (len(systemIndex) > 0):
    for index in systemIndex:
        print(index + " 或许是系统索引,不会重新创建,如有需要,请单独处理~")
相关推荐
余额瞒着我当琳1 小时前
Linux初识:Linux的历史,计算机的发展脉络,发行版本,选购云服务器,安装Xshell,第一次连接,基础命令指南
linux·运维·服务器
时间售卖铺1 小时前
Docker实战:一键部署轻量级容器
运维·docker·云原生
山乐191311 小时前
麒麟系统,安装Nginx并配置https证书
运维·nginx·https
月落汀兰2 小时前
拒绝配置写死镜像!K8s 存储卷与配置管理,PV/PVC、ConfigMap、Secret 实战避坑指南
运维·kubernetes
服务器硬件项目经理2 小时前
《超节点修仙录》· 第一卷·炼气期【第04话】 超节点 vs 普通服务器——不就是多插了几张卡吗?
运维·服务器·人工智能·嵌入式硬件·深度学习·机器学习
杨云龙UP3 小时前
MySQL 主从复制管理:暂停、恢复、清理主从关系及命令执行位置
运维·数据库·mysql·主从配置·主从命令·reset replica·清除复制
Android系统攻城狮3 小时前
Linux FFmpeg深度解析之avcodec_parameters_from_context调用流程与实战(十六)
linux·运维·ffmpeg·音视频进阶·ffmpeg音视频·车载音视频进阶
隔窗听雨眠3 小时前
从存储引擎到执行计划:OceanBase高效运维的调优逻辑与工程实践
运维·oceanbase
运维行者_3 小时前
供应链安全成最大风险源,企业如何构建可控的运维体系?
运维·开发语言·网络·数据库·安全·云计算·流量监控
xiaoyunxuexibiji3 小时前
采购协同管理:从备货计划、进度确认到到货签收
大数据·运维·人工智能