随着腾讯云Elasticsearch产品功能越来越丰富、产品体验越来越好。越来越多的客户将自建的ES集群或者部署在其他云厂商的 ES 集群迁移到腾讯云上来。为了更加方便快捷地帮助客户完成集群迁移工作,下面简单介绍下可提供的两种迁移方案,离线迁移和在线迁移。
一、离线迁移
顾名思义,就是需要客户需要迁移的集群先暂停写操作,对集群的查询操作没有影响。然后将集群上的数据通过下面提供的几种方式迁移到腾讯云 ES 上来。因此,使用离线迁移方案的前提,是客户能够接受集群短时间的数据写入。例如对于从消息队列中消费数据写入到 ES 中的日志类场景,暂停一段时间的数据消费通常不会带来太大的影响。
1、elasticsearch-dump
elasticsearch-dump是一种非常轻量级的数据迁移工具,它适用于源集群的数据量不大,迁移的索引个数不多的场景。对于集群数据规模在TB级别的,则不太建议使用。
github地址:
代码语言:javascript复制https://github.com/elasticsearch-dump/elasticsearch-dump
安装nodejs
代码语言:javascript复制yum install -y nodejs
安装elasticsearch-dump:
代码语言:javascript复制npm install elasticdump -g
常用参数说明:
代码语言:javascript复制--input: 源地址,可为ES集群URL、文件或stdin,可指定索引,格式为:{protocol}://{host}:{port}/{index}
--input-index: 源ES集群中的索引
--output: 目标地址,可为ES集群地址URL、文件或stdout,可指定索引,格式为:{protocol}://{host}:{port}/{index}
--output-index: 目标ES集群的索引
--type: 迁移类型,默认为data,表明只迁移数据,可选settings, analyzer, data, mapping, alias
--limit:每次向目标ES集群写入数据的条数,不可设置的过大,以免bulk队列写满
由于本文介绍了从客户自建集群迁移到腾讯云ES的步骤,因此下面只介绍input、output均为URL格式的情况。
迁移步骤:
- 迁移单个索引:
1)迁移索引的settings:
代码语言:javascript复制elasticdump --input=http://source_es_ip:9200/index_name --output=http://dest_es_ip:9200/index_name --type=settings
2)迁移索引的mapping:
代码语言:javascript复制elasticdump --input=http://source_es_ip:9200/index_name --output=http://dest_es_ip:9200/index_name --type=mapping
3)迁移索引的doc数据:
代码语言:javascript复制elasticdump --input=http://source_es_ip:9200/index_name --output=http://dest_es_ip:9200/index_name --type=data
备注:
代码语言:javascript复制source_es_ip: 源集群的ip地址;
dest_es_ip: 目的集群的ip地址,这里为腾讯云ES集群提供的VIP地址;
index_name: 待迁移的索引的名字;
在迁移数据之前,一定要先将该索引的settings和mapping信息提前迁移到目的集群,或者先在目的集群上提前创建好,如果直接迁移数据,可能会丢失索引的配置信息,比如索引的主分片、副本分片数量及refeash_interval等信息。
迁移所有索引:
代码语言:javascript复制elasticdump --input=http://source_es_ip:9200 --output=http://dest_es_ip:9200
我们可以通过上面的命令来将自建集群的所有索引数据都迁移到腾讯云ES集群上。同样需要注意的是,在迁移数据之前,依然需要先将索引的settings和mapping信息提前迁移或者在目的集群上提前创建好。
优势:轻量级的迁移工具,迁移简单。对于集群规模较小、索引数量较少的场景比较适合。
不足:如果源集群的数据量比较大,或者索引的个数比较多,则不太适合。首先需要提前迁移索引的settings和mapping信息,当索引的个数比较多时,则操作比较繁琐,且容易出错。另外,在数据迁移过程中,如果进程退出了,则会从头开始迁移,并不会记录迁移的offset,因此这里需要注意先将已经迁移的部分数据从目的集群中删除,否则会出现数据重复的现象。
2、snapshot
snapshot api是ES提供的一组用于索引数据快速备份及恢复的api 接口,详细介绍可查看官方文档,利用该组api接口,我们可以通过将源es集群的数据备份到远程仓库,再在腾讯云es集群上从远程仓库中通过快照恢复的方式来实现跨集群的离线数据迁移。
注意:目标 ES 集群的主版本号(如6.4.3版本中的6为主版本号)要大于等于源 ES 集群的主版本号。1.x 版本的集群创建的快照不能在 5.x 版本中恢复。例如客户的自建集群版本号为6.4.3,则腾讯云ES集群的版本需>= 6.4.3。
适用场景:
snapshot迁移适用于集群规模较大、索引个数比较多的场景。
迁移步骤:
- 自建ES集群安装COS插件,并重启集群
创建快照前需要在创建repository仓库。一个repository仓库可以存储多个数据快照文件。repository主要有如下几种类型:
代码语言:javascript复制fs:共享文件系统,将快照文件存放于文件系统中。
url:指定文件系统的 URL 路径,支持协议:http、https、ftp、file、jar。
s3:AWS S3 对象存储,快照存放于 S3 中,以插件形式支持,安装插件 repository-s3。
hdfs:快照存放于 hdfs 中,以插件形式支持,安装插件 repository-hdfs。
cos:快照存放于腾讯云 COS 对象存储中,以插件形式支持,安装插件 elasticsearch-repository-cos。
其中COS插件的github地址:https://github.com/tencentyun/elasticsearch-repository-cos
从客户自建ES集群中迁移到腾讯云ES,我们可以直接使用COS进行迁移,如果客户集群没有安装过COS插件,则需要先安装COS插件,最后重启集群。
2. 自建ES集群调用snapshot的api创建repository仓库
代码语言:javascript复制PUT _snapshot/my_cos_backup
{
"type": "cos",
"settings": {
"app_id": "xxxxxxx",
"access_key_id": "xxxxxx",
"access_key_secret": "xxxxxxx",
"bucket": "xxxxxx",
"region": "ap-guangzhou",
"compress": true,
"chunk_size": "500mb",
"base_path": "/"
}
}
- app_id:腾讯云账号 APPID。
- access_key_id:腾讯云 API 密钥 SecretId。
- access_key_secret:腾讯云 API 密钥 SecretKey。
- bucket:COS Bucket 名字,名字不能带
-{appId}
后缀。 - region:COS Bucket 地域,此地域必须与 ES 集群为同一地域。地域编码可参考 地域和可用区。
- base_path:备份目录。
3. 自建ES集群执行创建快照
将自建ES集群的索引数据备份到COS的my_cos_backup仓库下,命名为:snapshot_1
代码语言:javascript复制PUT _snapshot/my_cos_backup/snapshot_1
执行完上面的命令后会立即返回,及数据的备份是异步执行的,我们可以通过如下的命令查看快照执行的状态:
代码语言:javascript复制GET _snapshot/my_cos_backup/snapshot_1
返回格式如下,其中state若返回的是 "SUCESS",则表示快照备份完成。若是 "IN_PROCESS",则表示快照还在备份中。
代码语言:javascript复制{
"snapshots": [
{
"snapshot": "snapshot_1",
"uuid": "zUSugNiGR-OzH0CCcgcLmQ",
"version_id": 5060499,
"version": "5.6.4",
"indices": [
"index_1",
"index_2"
],
"state": "SUCCESS",
"start_time": "2018-05-04T11:44:15.975Z",
"start_time_in_millis": 1525434255975,
"end_time": "2018-05-04T11:45:29.395Z",
"end_time_in_millis": 1525434329395,
"duration_in_millis": 73420,
"failures": [],
"shards": {
"total": 3,
"failed": 0,
"successful": 3
}
}
]
}
如果不希望快照异步执行,而是阻塞同步的执行,则可以在备份快照的命令中加上参数:wait_for_completion,并设置为true。这时候该命令会等到快照备份完成后才返回,其中执行的时间和索引数据的大小有关。
代码语言:javascript复制PUT _snapshot/my_cos_backup/snapshot_1?wait_for_completion=true
上面备份的是整个索引,如果我们只想将部分索引迁移到云上,也可以通过下面的命令:
代码语言:javascript复制PUT _snapshot/my_cos_backup/snapshot_1
{
"indices": "index_1,index_2"
}
4. 在腾讯云ES集群上创建快照仓库
5. 云ES集群上执行恢复命令,从COS仓库中恢复快照:
代码语言:javascript复制POST _snapshot/my_cos_backup/snapshot_1/_restore
上面这一步就是将COS中刚备份的快照数据恢复到云上的ES集群中,执行这一步的前提是需要先在云上的ES集群中创建仓库,地址和自建集群上一致。
从快照中恢复指定索引:
代码语言:javascript复制POST /_snapshot/my_cos_backup/snapshot_1/_restore
{
"indices": "index_1",
"rename_pattern": "index_(. )",
"rename_replacement": "restored_index_$1"
}
- indices:只恢复 index_1 索引,忽略快照中存在的其他索引。
- rename_pattern:查找所提供的模式能匹配上的正在恢复的索引。
- rename_replacement:将匹配的索引重命名成替代的模式。
6. 查看快照恢复状态
代码语言:javascript复制GET index_1/_recovery
3、Logstash迁移
Logstash是Elastic 公司提供的一款专门用于应用程序日志、事件的传输、处理、管理的产品。这里我们可以通过Logstash完成跨ES集群的数据迁移工作。
适用场景:该中迁移方案适用于集群规模比较大,能够接受集群短时间暂停写的情形。
安装Logstash可参考官方文档。
迁移示例:
代码语言:javascript复制input {
elasticsearch {
hosts => ["http://source_es_ip:9200"]
index => "*"
docinfo => true
}
}
output {
elasticsearch {
hosts => ["http://dest_es_ip:9200"]
index => "%{[@metadata][_index]}"
}
}
上面的配置文件将自建ES集群的所有索引迁移到腾讯云ES集群中。当然,我们也可以只迁移某些特定的索引。Logstash的数据迁移前,提前设置好索引的模板,及索引的settings和mapping信息。
备注说明:Logstash如果是直接从自建ES集群中迁移数据,则读取的数据offset是存储在内存中的,如果在迁移过程中节点宕机或进程异常退出,再次启动时,会从头开始读取数据,可能会出现重复数据的情况。
Logstash的更多功能可以参考官方文档。
二、在线迁移
在线迁移技术是基于腾讯云ES于2020年5月份发布的双网卡技术实现的一种迁移方案。因此,这里需要注意,要迁移的目的ES集群需要是在2020年5月后创建的才适用。
适用场景:适用于客户自建ES集群和云上的ES集群网络互通,且对业务可用性和稳定性要求较高的场景。
迁移原理:将腾讯云ES集群于客户自建ES集群进行融合,构建成一个更大的ES集群,然后通过设置集群的settings配置,将客户ES集群上的索引数据平滑迁移到腾讯云ES的各个节点上,最后再将客户的ES集群节点下线。从而实现一种平滑迁移不停服的效果。
迁移步骤:
1)客户在腾讯云ES控制台购买ES集群,指定集群的配置名称为自建ES集群的名称(客户操作)
需要特别注意的地方:
- 腾讯云ES版本需要大于等于客户自建ES集群的版本。例如客户ES版本是6.5.1,则云上的ES版本最好是6.8.2;
- 创建ES集群的VPC选择自建ES集群所在的VPC
- 指定集群的配置名称需要开白名单
- 腾讯云ES版本选择基础版或者开源版,白金版暂时不支持(如果自建ES集群也是白金版可忽略),可在数据迁移完成后升级到白金版
- 确保自建ES集群没有开启security,如果开启则先关闭
- 确保客户自建ES集群没有安装腾讯云ES集群不支持的插件。
2)设置客户自建ES集群的参数 cluster.routing.allocation.include (客户操作)
代码语言:javascript复制curl -H "Content-Type: application/json" -XPUT source_es_ip:9200/_cluster/settings -d '{
"transient" : {
"cluster.routing.allocation.include._name" : "用户节点名1, 用户节点名2..."
}
}'
这一步建议由客户自己操作完成,里面只填写客户ES集群的数据节点信息,确保数据在融合后不立马进行数据均衡,防止有不可控的风险发生。
3)集群融合:设置腾讯云ES集群的参数:discovery.zen.ping.unicast.hosts(腾讯云后台操作)
代码语言:javascript复制curl localhost:5100/cluster/update -d '{
"cluster_name": "es_name",
"operator": "wr",
"es_config": {
"discovery.zen.ping.unicast.hosts": "["node1_ip:9300", "node2_ip:9300","node3_ip:9300", "node4_ip:9300"]"
},
"restart_type": "full_cluster_restart"
}'
追加客户ES集群的数据节点到腾讯云ES集群的配置文件中。这里调用的是基架的集群更新接口,每个地域的地址都不一样,这里的restart_type设置为full_cluster_restart,重启后方可实现集群融合,7.x版本的集群修改discovery.seed_hosts 参数,而不是discovery.zen.ping.unicast.hosts了。
4)设置集群参数,将客户自建ES集群节点exclude掉(腾讯云后台操作)
代码语言:javascript复制curl -H "Content-Type: application/json" -XPUT source_es_ip:9200/_cluster/settings -d '{
"transient" : {
"cluster.routing.allocation.include._name" : null,
"cluster.routing.allocation.exclude._name" : "用户节点名1, 用户节点名2..."
}
}'
通过上面的参数设置,就可以实现将客户集群上的数据在线迁移到腾讯云ES集群上来,注意这里的_name需是节点的名称。
5)下线客户集群节点 (客户操作)
检查数据迁移完成后,剔除掉客户的集群节点,将客户自建ES集群下线。
6)修改集群参数discovery.zen.ping.unicast.hosts,将该参数的值设置回腾讯云ES集群的节点列表(腾讯云后台操作)
代码语言:javascript复制curl localhost:5100/cluster/update -d '{
"cluster_name": "es_name",
"operator": "wr",
"es_config": {
"discovery.zen.ping.unicast.hosts": "["192.168.0.10:22345", "192.168.0.3:22345","192.168.0.5:9300", "192.168.0.3:9300", "192.168.0.17:9300"]"
},
"restart_type": "no_restart"
}'
这一步是将集群参数 discovery.zen.ping.unicast.hosts 重新设置回腾讯云ES集群的所有节点列表。注意这里的restart_type设置为no_restart,即只是修改配置文件,并不重启节点。在下次节点重启后会自动生效。
总结
- elasticsearch-dump 适用于集群规模较小、索引数量较少的场景;Logstash 适用于集群规模较大的场景。这两种迁移方案都需要实行迁移的机器能够同时访问到源ES集群和腾讯云ES集群。并且这两种方案都不需要源ES集群重启。但是在迁移过程中迁移工具退出或者执行迁移的服务器宕机,则会从头开始迁移,因此需要先将已经迁移的部分数据清空。迁移完成后通过比较索引的doc数量来确定索引是否全部迁移成功;
- snapshot 适用于集群规模较大、索引数量较多的场景。但是由于snapshot在迁移前需要源ES集群的每个节点都配置repository仓库地址,因此集群需要重启。这可能会影响源ES集群的查询性能和稳定性;
- 在线迁移 适用于客户对源ES集群的可用性和稳定性都特别高的场景。且需要腾讯云ES集群是在5月份之后购买的才可以。只要源ES集群和腾讯云ES集群能够网络互通,都可以选择在线迁移的方案,这种方案对源ES集群的可用性和稳定性没有任何影响,彻底做到平滑迁移业务不停服。这也是首选的迁移方案。
参考文档
1、ES官方文档
2、记一次在线跨集群迁移ES数据
3、Elasticsearch跨集群数据迁移之离线迁移
4、使用 COS 进行备份及恢复
问答
Q、客户自建集群在使用snapshot的方式迁移到腾讯云ES上来,会影响客户自建集群的读性能吗?是否可以控制备份的并发或者限速?
A:ES在创建仓库的命令中是可以指定限制备份的并发和速度的,详细参数您可以参考下面的文档:
https://www.elastic.co/guide/en/elasticsearch/reference/7.x/put-snapshot-repo-api.html#put-snapshot-repo-api-request-body
代码语言:javascript复制PUT _snapshot/my_cos_backup
{
"type": "cos",
"settings": {
"app_id": "1254139681",
"access_key_id": "xxxx",
"access_key_secret": "xxxx",
"bucket": "wurong-es-snapshpt",
"region": "ap-beijing",
"compress": true,
"chunk_size": "500mb",
"base_path": "es/",
"max_restore_bytes_per_sec":"40m",
"max_snapshot_bytes_per_sec":"40m"
}
}
"max_restore_bytes_per_sec": 最大恢复速率,40m/s
"max_snapshot_bytes_per_sec": 最大备份速率, 40m/s
Q:如果我在使用snapshot做迁移的时候,在备份某个很大的索引突然失败了,那下次再备份时候是需要把已经部分备份的删除吗?还是说可以重试即可?
A:不需要删除已经备份的快照,您可以直接重试备份即可,snapshot备份是增量的方式进行备份。