说明
本文描述问题及解决方法同样适用于 腾讯云 Elasticsearch Service(ES)。
ES 简介
Elasticsearch Service(ES)是基于开源搜索引擎 Elasticsearch 打造的高可用、可伸缩的云端全托管的 Elasticsearch 服务,包含 Kibana 及常用插件,并集成了安全、SQL、机器学习、告警、监控等高级特性(X-Pack)。使用腾讯云 ES,您可以快速部署、轻松管理、按需扩展您的集群,简化复杂运维操作,快速构建日志分析、异常监控、网站搜索、企业搜索、BI 分析等各类业务。
整体背景
ES 迁移方案
ES一般有如下几种迁移方式:
迁移方案 | 在线迁移 | 增量同步 | 删除/更新同步 | 清洗/转化/过滤 | 版本限制 | 迁移方式 | 迁移速度 |
---|---|---|---|---|---|---|---|
融合方案 | 是 | 支持 | 支持 | 不支持 | 源端<=目标端 | 剪切 | 很快 |
snapshot快照方案 | 否 | 支持 | 支持 | 不支持 | 源端<=目标端 | 复制 | 快 |
logstash方案 | 否 | 部分场景支持 | 不支持 | 支持复杂转化 | 无要求 | 复制 | 慢 |
CCR方案 | 准实时 | 支持 | 支持 | 不支持 | > 7.x | 复制 | 快 |
reindex remote方案 | 否 | 部分场景支持 | 不支持 | 支持query、script | 无要求 | 复制 | 慢 |
elasticdump方案 | 否 | 部分场景支持 | 不支持 | 仅支持query | 无要求 | 复制 | 很慢 |
ES 迁移流程
1. 数据拷贝及校验
数据全量迁移:存量数据迁移;
数据增量迁移:数据在不停的变化,有些业务不能停服,需要有增量同步的方案;
数据校验:迁移完成后的数据要进行校验;
元数据同步:索引属性同步(settings、mapping),模板迁移;
其他内容迁移:用户迁移,role权限迁移;
单独组件迁移:kibana迁移。
2. 任务双跑
3. 集群割接
ES 迁移实施痛点
1. 没有简单,快速,自动化,使用方便的界面化的工具,运行脚本比较麻烦,容易出错,需要投入大量的人力;
2. 如何保证迁移过程中数据的正确性;
3. 如何保证迁移过程中对业务影响最小;
4. 迁移的大部分重复命令行操作,需要手动校验数据完整性、一致性,总体迁移进度也不方便查看;
5. 迁移之后检验业务使用组件版本兼容性问题、参数配置调整与权限管理;
6. 迁移过程中历史数据变动涉及到增量迁移,人工扫描筛选变动数据同步操作复杂;
7. 工具脚本分散,需要系统化,自动化串联起来。
自动化在线迁移方案设计
融合迁移工具输入
- 用户只需填写任意一个自建节点的ip,以及http port。假设用户填写的自建节点为 10.10.10.10,http port 为 9200;
- 用户控制台需要提供迁移界面,后台需要同步提供迁移界面,以观测当前迁移进展。
融合迁移工具流程图
一、 集群自动化检测
注:本文检测方式均以curl为例
1. 自建ES版本检测
自建ES版本需要<=云上ES版本,否则不允许继续操作,API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200?pretty' | grep -oP '(?<="number" : ")[^"] '
2. 自建license版本检测
自建ES license版本需要与云上完全一致,否则不允许继续操作,API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200/_license?pretty' | grep -oP '(?<="type" : ")[^"] '
3. 自建jdk版本检测
自建jdk版本需要<=11.0.9.1-ga,因为云上ES使用的是11.0.9.1-ga,如果比该版本高,则会有证书加密算法不支持等问题。API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200/_nodes?filter_path=nodes.*.jvm.version&pretty'
4. 自建http端口联通性检测
4.1. 获取自建节点list及http端口
API例如:
代码语言:javascript复制curl '10.10.10.10:9200/_nodes/http?pretty' | grep -oP '(?<="publish_address" : ")[^"] '
4.2. 检测自建http端口联通性
在云上每个节点,对上面获取到的自建所有节点进行http端口的遍历请求,确保两端集群所有节点端口皆是互通的,API例如:
代码语言:javascript复制curl '10.10.10.10:9200'
5. 自建transport端口联通性检测
5.1. 获取自建节点list及transport端口
融合方案依赖transport端口进行通信,需要在云上集群节点对自建节点的transport端口发起联通性测试,API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200/_nodes/http?pretty' | grep -oP '(?<="transport_address" : ")[^"] '
5.2. 检测transport端口联通性
在云上每个节点,对上面获取到的自建所有节点进行transport端口的遍历请求,确保两端集群所有节点端口皆是互通的,API例如:
代码语言:javascript复制curl '10.10.10.10:9300'
6. 自建discovery hosts获取
首先获取master节点的ip,API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200/_cat/nodes?h=ip,node.role' | grep "m" | awk '{print $1}'
然后根据master ip获取transport端口,API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200/_nodes/http?pretty' | grep -oP '(?<="transport_address" : ")[^"] ' | grep "10.10.10.10|10.10.10.11|10.10.10.12"
云上 discovery hosts 从管控元数据中获取即可。
7. 自建cluster.name检测
自建cluster.name需要与云上完全一致,否则不允许发起融合,检测API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200/_cluster/health?pretty' | grep -oP '(?<="cluster_name" : ")[^"] '
8. 自建插件检测
检测自建集群安装的插件,并与云上集群对比。云上集群不存在的插件,自动评估该插件是否需要进行自定义安装。检测API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200/_cat/plugins?h=component,version' | sort | uniq
9. 自建自定义词典检测
9.1. 同义词
遍历所有索引的settings,获取index.analysis.filter.*.synonyms_path,如果有值则说明索引包含同义词。有同义词则需要先进行同义词上传,上传后对集群节点目录下的同义词文件路径及文件名与索引settings进行对比,需要完全一致,否则不允许发起融合,检测API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200/{index_name}/_settings?pretty' | grep synonyms_path
9.2. IK分词/停用词
ik分词器的词典无法通过api获取,需要在控制台引导用户通过以下方式获取,将获取到的分词词典以及停用词词典上传至ES控制台的ik分词器里,获取方式例如:
代码语言:javascript复制[root@tencentos es]# cat config/analysis-ik/IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="ext_dict">ext-dict/test.dic</entry>
<entry key="ext_stopwords">ext-dict/stop.dic</entry>
</properties>
10. 自建close索引检测
融合前和融合后都需要不断检测自建集群是否包含 close 索引,如包括 close 索引,融合前则不允许发起融合,融合后则在控制台发出严重警告;
11. 自建total_shards检测
遍历所有索引,检测索引参数 index.routing.allocation.total_shards_per_node,确保为默认值,否则会发生分片搬迁不完的情况。
二、 自动化清空云上系统索引
1. 关闭云上自动创建索引
为了防止清空云上系统索引后自动创建,需要先关闭索引自动创建,API例如:
代码语言:javascript复制PUT _cluster/settings
{
"transient": {
"action": {
"auto_create_index": "false"
}
},
"persistent": {
"action": {
"auto_create_index": "false"
}
}
}
2. 开启模糊匹配
代码语言:javascript复制PUT _cluster/settings
{
"transient": {
"action.destructive_requires_name": "false"
}
}
3. 删除云上系统索引
API例如:
代码语言:javascript复制DELETE .mo*
DELETE .apm*
DELETE .kibana*
DELETE .s*
DELETE .t*
DELETE .w*
DELETE _data_stream/ilm-history-5
DELETE ilm-history-3-000001
DELETE _data_stream/.logs-deprecation.elasticsearch-default
三、 获取自建data node,自动化锁定源端数据
1. 自动获取自建node name
API例如:
代码语言:javascript复制curl -s '10.10.10.10:9200/_cat/nodes?h=name'
2. 锁定源端数据
API例如:
代码语言:javascript复制curl -H "Content-Type: application/json" -XPUT http://10.10.10.10:9200/_cluster/settings -d '
{
"transient" : {
"cluster.routing.allocation.include._name" : "node-01,node-02,node-03"
}
}'
四、 发起融合
显示融合按钮,让用户自助发起融合
● <7.x 融合
将自建集群的discovery.zen.ping.unicast.hosts参数值与云上进行融合,对云上集群发起如下请求,管控请求例如:
代码语言:javascript复制curl localhost:5100/cluster/update -d '{
"cluster_name": "es-xxxxxxxx",
"operator": "xxxxxxxx",
"es_config": {
"discovery.zen.ping.unicast.hosts": "["10.10.10.10:9300", "10.10.10.11:9300", "10.10.10.12:9300", "172.17.245.162:9300", "172.17.244.19:9300", "172.17.244.137:9300"]"
},
"restart_type": "full_cluster_restart"
}'
● >=7.x 融合
1. 对云上集群进行改名
发起cluster.name改名流程,让目标集群重新组建为名为merge_temp的集群(全量重启),管控请求例如:
代码语言:javascript复制curl localhost:5100/cluster/update -d '{
"cluster_name": "es-xxxxxxxx",
"operator": "xxxxxxxx",
"es_config": {
"cluster.name": "merge_temp"
},
"restart_type": "full_cluster_restart"
}'
2. 改名回滚以及seed融合
组建成功后再次下发改名流程 discovery.seed_hosts融合流程,放在一个流程里,把cluster.name改回去且加上seed融合(仅下发不重启),管控请求例如:
代码语言:javascript复制curl localhost:5100/cluster/update -d '{
"cluster_name": "es-xxxxxxxx",
"operator": "daemonyue",
"es_config": {
"cluster.name": "qcloud",
"discovery.seed_hosts": "["10.10.25.17:9300", "10.10.18.194:9300", "10.10.26.129:9300", "10.10.25.79:9300", "10.10.26.54:9300", "10.10.18.158:9300"]"
},
"restart_type": "no_restart"
}'
3. 元数据初始化
最后再执行元数据初始化流程,进行正式滚动融合,脚本执行例如:
代码语言:javascript复制./init_cloud_metadata.sh --sourceEndPoint 10.10.10.10 --sourcePort 9200 --user elastic --password xxxxxxxx --cloudInfoJsonFile json/qytest
五、 发起迁移
1. 迁移速率控制
全局提供一个迁移速率限速开关,可以实时动态调整搬迁速率,以及非实时调整搬迁并发。搬迁并发需要有个提示,向上是实时生效,向下是延迟生效。API例如:
代码语言:javascript复制PUT _cluster/settings
{
"transient":{
"cluster.routing.allocation.node_concurrent_recoveries":10,
"cluster.routing.allocation.node_concurrent_incoming_recoveries":10,
"cluster.routing.allocation.node_initial_primaries_recoveries":10,
"cluster.routing.allocation.node_concurrent_outgoing_recoveries":10,
"cluster.routing.allocation.cluster_concurrent_rebalance":10,
"indices.recovery.max_bytes_per_sec":"100mb"
}
}
2. 发起迁移
提供迁移按钮,发起分片迁移,API例如:
代码语言:javascript复制curl -H "Content-Type: application/json" -XPUT http://10.10.10.10:9200/_cluster/settings -d '
{
"transient" : {
"cluster.routing.allocation.include._name" : null,
"cluster.routing.allocation.exclude._name" : "node-01,node-02,node-03"
}
}'
3. 实时检测迁移进度并展示
对 _cat/allocation 接口进行实时监控,计算迁移进度并展示
六、 下线自建节点并回滚元数据
1. 提示用户下线自建节点
迁移完成后提示用户切换访问ip到云上并下线旧节点,并建议旧集群的cluster.name最好改个名,例如:
代码语言:javascript复制[root@tencentos es]# grep "cluster.name" config/elasticsearch.yml
cluster.name: "qcloud"
# 将 cluster.name 由原先 qcloud 改为 qcloud_local
[root@tencentos es]# grep "cluster.name" config/elasticsearch.yml
cluster.name: "qcloud_local"
2. 回滚管控元数据
检测到自建节点完全下线后,青鹅后台提供回滚管控元数据按钮:
● <7.x 回滚
管控请求例如:
代码语言:javascript复制curl localhost:5100/cluster/update -d '{
"cluster_name": "es-xxxxxxxx",
"operator": "daemonyue",
"es_config": {
"discovery.zen.ping.unicast.hosts": "null"
},
"restart_type": "no_restart"
}'
● >=7.x 回滚
管控请求例如:
代码语言:javascript复制curl localhost:5100/cluster/update -d '{
"cluster_name": "es-xxxxxxxx",
"operator": "xxxxxxxx",
"es_config": {
"discovery.seed_hosts": "null"
},
"restart_type": "no_restart"
}'
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!