本文介绍如何将 Amazon Web Services(简称 AWS)ES 中的索引数据迁移至阿里云 Elasticsearch。该方案采用快照迁移方式,将AWS ES 的快照数据存入 AWS S3,然后将快照数据迁移至阿里云 OSS,最后在阿里云 Elasticsearch 中恢复索引。
迁移方案
迁移基于Elasticsearch的快照机制,不依赖特定云厂商:在源端AWS ES中创建快照并存入AWS S3存储空间,将快照数据迁移至阿里云OSS,再在目标端阿里云Elasticsearch中从OSS恢复索引。其中快照数据的跨云搬迁也可使用在线迁移服务完成(同样适用于腾讯云COS中的ES快照数据),恢复环节使用ES的快照恢复功能。
ES快照仅支持恢复到同版本或更高版本的集群,且精确到小版本号,详见快照兼容性。例如源端AWS ES为7.10.2时,目标端阿里云Elasticsearch选择7.10.0会在恢复时报错the snapshot was created with Elasticsearch version [7.10.2] which is higher than the version of this node [7.10.0],此时应选择7.16.2等更高版本。

迁移过程分为四个阶段,与下文四个步骤一一对应:
准备资源:源端AWS域、AWS S3存储空间、IAM角色与策略,目标端阿里云Elasticsearch实例、OSS Bucket。
在AWS ES中注册指向S3存储空间的快照存储库。
迁移首次全量快照:创建快照、提取至OSS、在阿里云Elasticsearch中注册OSS存储库并恢复索引。
迁移增量快照并切换:停止源端写入、创建增量快照、增量提取至OSS、恢复并核对数据量后切换业务流量。
步骤一:准备迁移所需资源
迁移只能使用存储在自有AWS S3存储空间中的手动快照。AWS每天自动创建的快照保留14天且不能迁移到其他域,仅可用于恢复本域;手动快照按S3标准计费。开始迁移前,需完成以下准备。
准备源端AWS资源
创建AWS域。AWS OpenSearch Service已下线Elasticsearch 7.1.0.0等早期版本,请以控制台当前可选版本为准(本文以Elasticsearch 7.10.2为例),地域可任选(本文以us-east-1为例)。具体操作请参见创建Amazon OpenSearch Service域。
说明如果该域启用了精细访问控制(Fine-grained access control)且主用户类型为IAM,或访问策略仅允许IAM主体(如
es:ESHttp*仅授权给账号根用户),则无法直接用浏览器登录该域的Kibana控制台,会返回403User: anonymous is not authorized to perform: es:ESHttpGet。此时请统一使用带AWS签名(SigV4)的方式执行本文中AWS侧的各条命令,例如复用步骤二中的Python客户端。创建AWS S3存储空间,用于存放手动快照,并记录其AWS资源名称(ARN)。该ARN在两处会用到:IAM策略的Resource语句、注册快照存储库的Python客户端。
ARN示例如下。
arn:aws:s3:::eric-es-index-backups在AWS ES中准备待迁移的索引,本文示例索引名称为
movies。
创建IAM角色与策略
IAM角色用于为AWS ES授权访问S3存储空间,IAM策略用于限定该角色可执行的操作,两者需配套创建并绑定。
创建IAM角色,用于为AWS ES授权。注册快照存储库时需使用该角色,且只有具备该角色访问权限的IAM用户才能注册。
该角色信任关系中的
Service语句必须指定为es.amazonaws.com,如下所示。{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "es.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }在IAM控制台左侧导航栏选择Roles,找到目标角色后单击Trust relationships页签,再单击Edit trust relationship,即可查看和编辑信任策略。
说明在IAM控制台创建AWS服务角色时,Select role type下拉列表中不包含AWS ES。可先选择AWS EC2完成角色创建,再将
ec2.amazonaws.com修改为es.amazonaws.com。创建IAM策略并附加给上述IAM角色,用于限定该角色可对S3存储空间执行的操作。
策略的Resource语句中需指定存放快照的S3存储空间ARN。以下示例指定了存储空间
eric-es-index-backups。{ "Version": "2012-10-17", "Statement": [ { "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::eric-es-index-backups" ] }, { "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::eric-es-index-backups/*" ] } ] }创建完成后可在IAM控制台核对:左侧导航栏选择Policies,单击策略名称进入详情页,在Permissions页签的JSON视图中确认策略内容与上述示例一致,Policy summary中显示该策略对S3授予Limited: List, Read, Write访问级别。
再在左侧导航栏单击Roles,选择目标角色,在Permissions页签下确认策略已附加成功。
准备目标端阿里云资源
创建阿里云Elasticsearch实例,地域为杭州,版本不低于源端AWS ES的具体小版本(源端为7.10.2时选择7.16.2)。具体操作请参见创建阿里云Elasticsearch实例。
创建OSS Bucket,用于接收从S3迁移过来的快照数据。本文使用的Bucket地域为华东1(杭州)、存储类型为标准存储、读写权限为私有,其他参数保持默认,具体操作请参见创建存储空间。
步骤二:在AWS ES中注册快照存储库
只有在AWS ES中注册了指向S3存储空间的快照存储库,才能创建手动快照。注册请求需使用步骤一:准备迁移所需资源中IAM角色信任关系所指定的用户或角色进行AWS签名(SigV4)。curl命令不支持AWS请求签名,因此需使用以下Python客户端完成注册。
准备注册脚本
修改脚本中注释标注的参数值,并另存为snapshot.py。
各参数说明如下。
变量名
描述
region
创建快照存储库所在的AWS地域。
host
AWS ES域的访问地址。
aws_access_key_id
IAM凭证ID。
aws_secret_access_key
IAM凭证Key。
service
签名使用的AWS服务标识,Amazon OpenSearch Service(含Elasticsearch版本)固定为
es。url
注册快照存储库的请求地址,格式为
https://{host}/_snapshot/{仓库名称},其中仓库名称需与后续创建、恢复快照时使用的名称保持一致。payload
必须包含上文步骤一:准备迁移所需资源中,为IAM角色创建的S3存储空间的名字和ARN。
重要建议在settings中增加
"base_path": "<自定义前缀>",让本实例的快照文件集中存放在该前缀下,避免与同一S3存储空间中其他实例的快照混用同一路径(详见下文常见问题中的仓库唯一性说明)。请记录该前缀,后续在阿里云ES中注册OSS仓库时,base_path必须与快照数据迁移到OSS后的实际前缀保持一致。如果要为快照存储库启用S3托管密钥的服务器端加密,请将
"server_side_encryption": true添加到settings JSON中。如果S3存储空间在ap-southeast-1地域,请使用
"endpoint": "s3.amazonaws.com"替代"region": "ap-southeast-1"。
安装依赖并执行注册
安装示例Python客户端所需的依赖。
示例Python客户端使用requests发送请求、使用requests-aws4auth完成AWS签名,请在执行注册操作的机器上(Python 3环境)安装这两个依赖。
pip install requests requests_aws4auth执行Python客户端,注册快照存储库。执行成功后返回HTTP状态码200及
{"acknowledged" : true}。python snapshot.py
验证注册结果
进入对应AWS ES的Kibana控制台,在Dev Tools页面的Console中,执行以下命令,查看请求结果。如果该域启用了精细访问控制或访问策略仅允许IAM主体,导致无法登录Kibana,请改用带签名的方式(如复用上述Python客户端,把请求方法改为GET)执行同样的命令。
GET _snapshot执行该命令后,返回已注册的快照仓库配置信息。其中系统自动创建的仓库名为
cs-automated;若该域开启了静态加密,则为cs-automated-enc。{ "eric-snapshot-repository": { "type": "s3", "settings": { "bucket": "eric-es-index-backups", "base_path": "eric-aws", "region": "us-east-1", "role_arn": "arn:aws:iam::xxx:role/eric-iam-role-es" } }, "cs-automated-enc": { "type": "s3" } }
步骤三:首次迁移全量快照
本步骤将源端现有数据整体迁移到目标端:在AWS ES中创建全量快照,把快照数据提取至阿里云OSS,再在阿里云Elasticsearch中注册OSS存储库并恢复索引。
在AWS ES中创建全量快照
以下AWS侧命令在AWS ES的Kibana控制台的Dev Tools中执行。如果该域无法通过浏览器登录Kibana,请改用带SigV4签名的请求执行同样的命令。
为在
eric-snapshot-repository存储库中的movies索引,创建名称为snapshot_movies_1的快照。PUT _snapshot/eric-snapshot-repository/snapshot_movies_1 { "indices": "movies" }查看快照状态,
state为SUCCESS表示快照创建完成。GET _snapshot/eric-snapshot-repository/snapshot_movies_1{ "snapshots": [ { "snapshot": "snapshot_movies_1", "uuid": "BlgKLvgoSpSgwBnbD4hIWg", "version_id": 7100299, "version": "7.10.2", "indices": [ "movies" ], "data_streams": [], "include_global_state": true, "state": "SUCCESS", "start_time": "2018-02-28T03:00:44.591Z", "start_time_in_millis": 1519786844591, "end_time": "2018-02-28T03:00:46.236Z", "end_time_in_millis": 1519786846236, "duration_in_millis": 1645, "failures": [], "shards": { "total": 5, "failed": 0, "successful": 5 } } ] }在AWS S3控制台确认快照文件已生成。
快照创建成功后,在S3存储桶eric-es-index-backups中可以看到生成的快照文件,包括
indices文件夹、index-0、index.latest、meta-BlgKLvgoSpSgwBhbD4hTWg.dat和snap-BlgKLvgoSpSgwBhbD4hTWg.dat等文件。
将快照数据迁移至阿里云OSS
从AWS S3提取快照数据至阿里云OSS,详细操作方法请参见从Amazon S3上的应用无缝切换至OSS。
迁移完成后,在OSS控制台确认快照数据已到位。
OSS存储桶中可看到以下快照文件:indices/(文件夹)、index-0、index.latest、meta-BlgKLvgoSpSgwBhbD4hTWg.dat和snap-BlgKLvgoSpSgwBhbD4hTWg.dat。
在阿里云ES中注册OSS快照存储库
创建快照存储库。
重要在进行Elasticsearch快照迁移过程中,必须确保每个Elasticsearch实例使用独立的快照仓库或路径。多实例共享同一仓库将导致数据无法恢复,造成数据丢失风险。
进入目标阿里云Elasticsearch实例的Kibana控制台(登录Kibana控制台),在Dev Tools页面的Console中,执行如下命令创建一个同名的快照存储库。其中
base_path必须与快照数据迁移到OSS后的实际前缀一致(若AWS侧仓库未设置base_path、快照文件位于存储空间根目录,则此处也不要设置base_path)。PUT _snapshot/eric-snapshot-repository { "type": "oss", "settings": { "base_path": "my/snapshot/directory", "endpoint": "http://oss-cn-hangzhou-internal.aliyuncs.com", "access_key_id": "your AccessKeyID", "secret_access_key": "your AccessKeySecret", "bucket": "eric-oss-aws-es-snapshot-s3", "compress": true } }查看名称为
snapshot_movies_1的快照状态。GET _snapshot/eric-snapshot-repository/snapshot_movies_1返回结果中
state为SUCCESS,表示阿里云Elasticsearch已能从OSS存储库中读到该快照。如果返回snapshot_missing_exception,请检查base_path是否与快照数据在OSS中的实际前缀一致。说明记录本次快照的起始时间和结束时间,迁移增量快照数据时需要用到。例如:
“start_time_in_millis”: 1519786844591
“end_time_in_millis”: 1519786846236
恢复索引并核对数据
在阿里云Elasticsearch的Kibana控制台执行以下命令恢复快照。
POST _snapshot/eric-snapshot-repository/snapshot_movies_1/_restore
{
"indices": "movies"
}执行以下命令,查看movies索引的可用性。
GET movies/_recovery恢复完成后,movies索引中的文档数量与AWS ES域中一致。
也可在阿里云Elasticsearch的Kibana中通过Discover页面选择movies索引核对数据。本文示例中恢复后返回3条文档(The Manchurian Candidate、Mars Attacks!、U.S. Marshals),与源端相同。
步骤四:迁移增量快照并切换
首次全量快照迁移完成后,源端在此期间新写入的数据需通过增量快照补齐。正式切换前请先停止所有会修改源端索引的服务,再执行本步骤,确保末次增量快照包含全部数据。以下以在源端新写入2条文档为例。
在 AWS ES 中创建增量快照
在AWS ES的
movies索引中写入增量数据。本文示例中新写入2条文档,写入后
movies索引共5条文档,_id分别为1~5。执行GET movies/_count可查看当前文档数量,用于后续与目标端核对。创建增量快照。
执行以下命令手动创建快照,详情请参见上文的在AWS ES中创建全量快照。
PUT _snapshot/eric-snapshot-repository/snapshot_movies_2 { "indices": "movies" }创建成功后,执行以下命令查看快照状态。
GET _snapshot/eric-snapshot-repository/snapshot_movies_2在AWS S3控制台查看新增的快照文件。
S3存储空间中会列出快照仓库的全部文件,其中与
snapshot_movies_2对应的新增文件为snap-CWhlF7ShQZaKQlJasPE70A.dat、index.latest、index-1和meta-CWhlF7ShQZaKQlJasPE70A.dat。
迁移增量快照数据至阿里云OSS
从AWS S3提取增量快照数据至阿里云OSS,仍使用OSSImport工具迁移。此时S3存储空间中已包含首次快照的文件,建议在配置文件local_job.cfg中将isSkipExistFile设置为true,仅迁移新增的快照文件。
isSkipExistFile为布尔类型,默认值为false,表示覆盖已有对象;设置为true时,根据对象的size和LastModifiedTime跳过已迁移的对象。当jobType为audit时该配置无效。
迁移完成后,OSS中会出现本次新增的快照文件。
增量文件迁移到OSS后,阿里云Elasticsearch会沿用已缓存的仓库内容,此时执行GET _snapshot/eric-snapshot-repository/_all可能仍然只能看到首次快照。请在阿里云Elasticsearch的Kibana控制台重新注册同名OSS仓库(先执行DELETE _snapshot/eric-snapshot-repository,再按步骤三中的PUT命令重新创建),确认新快照已可见后,再继续恢复增量快照。
新增文件为index-1、index.latest、meta-CWhIF7ShQZaKQUasPE70A.dat和snap-CWhIF7ShQZaKQUasPE70A.dat。
恢复增量快照并切换业务流量
恢复增量快照的命令与步骤三:首次迁移全量快照中相同,但需先关闭movies索引,恢复完成后再重新打开movies索引。
关闭
movies索引POST /movies/_close查看
movies索引状态,确认已变为close。索引关闭后不能使用GET movies/_stats查看(会返回index_closed_exception),请使用如下命令。GET _cat/indices/movies?v恢复增量快照
POST _snapshot/eric-snapshot-repository/snapshot_movies_2/_restore { "indices": "movies" }打开
movies索引POST /movies/_open
恢复完成后,执行GET movies/_count核对文档数量。本文示例中目标端返回5,与源端AWS ES一致,此时可将业务流量切换至阿里云Elasticsearch实例。
常见问题
为什么需要仓库唯一性?
当多个Elasticsearch实例(包括源端和目标端实例)同时使用同一个快照仓库时,会产生以下问题:
元数据冲突:Elasticsearch快照机制依赖于仓库中的元数据文件来管理快照信息。多个实例同时操作同一仓库会导致元数据被覆盖或修改,使快照索引无法正确识别。
数据覆盖风险:不同实例创建的快照可能会覆盖彼此的数据文件,导致部分快照数据丢失或损坏。
恢复失败:当尝试从共享仓库恢复数据时,Elasticsearch无法确定哪些数据属于哪个实例,导致恢复操作失败或恢复错误数据。
因此,请为每个Elasticsearch实例使用独立的快照仓库,或在同一存储空间中通过base_path划分独立路径。如果确实需要多个集群访问同一仓库,请只让其中一个集群拥有写入权限,其余集群在注册仓库时设置"readonly": true,以只读方式接入。
阿里云ES从OSS上做快照恢复索引数据时报错,为什么?
可能是因为快照数据在OSS上的路径中包含以正斜线(/)结尾的空目录名或其他特殊符号,例如在OSS控制台中可以看到名称为“/”的异常层级。
阿里云ES从OSS上做快照恢复索引数据时,不支持快照文件路径中包含此类符号。解决方案为通过用图形化管理工具ossbrowser 2.0快速入门,将OSS的快照数据移到正常的文件夹下。