使用流量回放器
本指南介绍如何在迁移过程中使用流量重放器(Traffic Replayer)将捕获的流量从源集群重放至目标集群。流量重放器允许您验证目标集群是否能以与源集群相同的方式处理请求,并赶上实时流量,以实现平滑迁移。
何时运行流量重放器
部署迁移助手后,流量重放器默认不运行。它应在所有元数据和文档迁移完成后才启动,以确保源集群的最新更改正确反映在目标集群中。
例如,如果快照拍摄后删除了某个文档,在文档迁移完成前启动流量重放器可能导致删除请求在文档添加到目标之前执行。在所有其他迁移过程完成后运行流量重放器,可确保目标集群与源集群保持一致。
配置选项
流量重放器设置在部署迁移助手时配置。请务必为流量重放器设置身份验证模式,以便它能正确地与目标集群通信。
使用流量回放器
要管理流量重放器,请使用 console replay
命令。以下示例展示了可用的命令。
启动流量重放器
以下命令使用部署时指定的选项启动流量重放器
console replay start
启动流量重放器时,您应该收到类似于以下的输出
root@ip-10-0-2-66:~# console replay start
Replayer started successfully.
Service migration-dev-traffic-replayer-default set to 1 desired count. Currently 0 running and 0 pending.
检查流量重放器的状态
使用以下命令显示流量重放器的状态
console replay status
重放将返回以下状态之一
Running
显示有多少容器实例正在活动运行。Pending
指示有多少实例正在被预置。Desired
显示应运行的实例总数。
您应该收到类似于以下的输出
root@ip-10-0-2-66:~# console replay status
(<ReplayStatus.STOPPED: 4>, 'Running=0\nPending=0\nDesired=0')
停止流量重放器
以下命令停止流量重放器
console replay stop
您应该收到类似于以下的输出
root@ip-10-0-2-66:~# console replay stop
Replayer stopped successfully.
Service migration-dev-traffic-replayer-default set to 0 desired count. Currently 0 running and 0 pending.
交付保证
流量重放器从 Kafka 检索流量,并在向目标集群发送请求后更新其提交游标。这提供了“至少一次”的交付保证;然而,成功并不总是能得到保证。因此,您应该监控指标和元组输出,或执行外部验证,以确保目标集群按预期运行。
时间缩放
流量重放器以从源头每个连接接收到的相同顺序发送请求。然而,不同连接之间的相对时间不作保证。例如
- 场景:存在两个连接:一个每分钟发送一次 PUT 请求,另一个每秒发送一次 GET 请求。
- 行为:流量重放器将保持每个连接内的序列,但不保留连接之间(PUT 和 GET)的相对时间。
假设源集群在 100 毫秒内响应请求(GET 和 PUT)
- 在加速因子为 1 的情况下,目标将体验与源相同的请求速率和空闲周期。
- 在加速因子为 2 的情况下,请求将以两倍的速度发送,GET 请求每 500 毫秒发送一次,PUT 请求每 30 秒发送一次。
- 在加速因子为 10 的情况下,请求将以 10 倍的速度发送,只要目标响应迅速,流量重放器就能保持这个速度。
如果目标无法足够快地响应,流量重放器将等待前一个请求完成后再发送下一个请求。这可能导致延迟并影响全局相对顺序。
转换
在迁移过程中,某些请求可能需要在版本之间进行转换。例如,Elasticsearch 以前支持索引中的多个类型映射,但 OpenSearch 中不再支持。客户端可能需要相应地进行调整,例如将文档拆分为多个索引或转换请求数据。
流量重放器会自动重写主机和身份验证头,但对于更复杂的转换,可以使用 --transformer-config
选项指定自定义转换规则。有关更多信息,请参阅流量重放器 README。
转换示例
假设源请求包含一个需要删除并提升其子元素的 tagToExcise
元素,并且 URI 路径包含 extraThingToRemove
,也应将其删除。以下 Jolt 脚本处理此转换
[{ "JsonJoltTransformerProvider":
[
{
"script": {
"operation": "shift",
"spec": {
"payload": {
"inlinedJsonBody": {
"top": {
"tagToExcise": {
"*": "payload.inlinedJsonBody.top.&"
},
"*": "payload.inlinedJsonBody.top.&"
},
"*": "payload.inlinedJsonBody.&"
},
"*": "payload.&"
},
"*": "&"
}
}
},
{
"script": {
"operation": "modify-overwrite-beta",
"spec": {
"URI": "=split('/extraThingToRemove',@(1,&))"
}
}
},
{
"script": {
"operation": "modify-overwrite-beta",
"spec": {
"URI": "=join('',@(1,&))"
}
}
}
]
}]
发送到目标集群的最终请求将类似于以下内容
PUT /oldStyleIndex/moreStuff HTTP/1.0
host: testhostname
{"top":{"properties":{"field1":{"type":"text"},"field2":{"type":"keyword"}}}}
您可以使用 --transformer-config-base64
传递 Base64 编码的转换脚本。
结果日志
源捕获的 HTTP 事务以及重新发送到目标集群的 HTTP 事务都记录在 /shared-logs-output/traffic-replayer-default/*/tuples/tuples.log
文件中。/shared-logs-output
目录在包括迁移控制台在内的所有容器之间共享。您可以从迁移控制台使用相同的路径访问这些文件。之前的运行记录也以 gzipped
格式提供。
每个日志条目都是一个以换行符分隔的 JSON 对象,包含有关源请求/响应和目标请求/响应的信息以及其他事务详细信息,例如响应时间。
这些日志包含所有请求的内容,包括授权头和所有 HTTP 消息的内容。请确保对迁移环境的访问受到限制,因为这些日志是确定源集群和目标集群中发生事件的真相来源。源的响应时间是指代理发送请求结束到接收到响应之间的时间量。虽然目标的响应时间以相同方式记录,但请记住捕获代理、流量重放器和目标的位置可能不同,并且这些日志不考虑客户端的位置。
日志条目示例
以下示例日志条目显示了发送到源集群和目标集群的 /_cat/indices?v
请求
{
"sourceRequest": {
"Request-URI": "/_cat/indices?v",
"Method": "GET",
"HTTP-Version": "HTTP/1.1",
"Host": "capture-proxy:9200",
"Authorization": "Basic YWRtaW46YWRtaW4=",
"User-Agent": "curl/8.5.0",
"Accept": "*/*",
"body": ""
},
"sourceResponse": {
"HTTP-Version": {"keepAliveDefault": true},
"Status-Code": 200,
"Reason-Phrase": "OK",
"response_time_ms": 59,
"content-type": "text/plain; charset=UTF-8",
"content-length": "214",
"body": "aGVhbHRoIHN0YXR1cyBpbmRleCAgICAgICB..."
},
"targetRequest": {
"Request-URI": "/_cat/indices?v",
"Method": "GET",
"HTTP-Version": "HTTP/1.1",
"Host": "opensearchtarget",
"Authorization": "Basic YWRtaW46bXlTdHJvbmdQYXNzd29yZDEyMyE=",
"User-Agent": "curl/8.5.0",
"Accept": "*/*",
"body": ""
},
"targetResponses": [{
"HTTP-Version": {"keepAliveDefault": true},
"Status-Code": 200,
"Reason-Phrase": "OK",
"response_time_ms": 721,
"content-type": "text/plain; charset=UTF-8",
"content-length": "484",
"body": "aGVhbHRoIHN0YXR1cyBpbmRleCAgICAgICB..."
}],
"connectionId": "0242acfffe13000a-0000000a-00000005-1eb087a9beb83f3e-a32794b4.0",
"numRequests": 1,
"numErrors": 0
}
解码日志内容
HTTP 消息正文的内容经过 Base64 编码,以处理各种类型的流量,包括压缩数据。要以更易读的格式查看日志,请使用控制台库 tuples show
。按如下方式运行脚本将在主目录中生成一个 readable-tuples.log
文件
console tuples show --in /shared-logs-output/traffic-replayer-default/d3a4b31e1af4/tuples/tuples.log > readable-tuples.log
readable-tuples.log
应该类似于以下内容
{
"sourceRequest": {
"Request-URI": "/_cat/indices?v",
"Method": "GET",
"HTTP-Version": "HTTP/1.1",
"Host": "capture-proxy:9200",
"Authorization": "Basic YWRtaW46YWRtaW4=",
"User-Agent": "curl/8.5.0",
"Accept": "*/*",
"body": ""
},
"sourceResponse": {
"HTTP-Version": {"keepAliveDefault": true},
"Status-Code": 200,
"Reason-Phrase": "OK",
"response_time_ms": 59,
"content-type": "text/plain; charset=UTF-8",
"content-length": "214",
"body": "health status index uuid ..."
},
"targetRequest": {
"Request-URI": "/_cat/indices?v",
"Method": "GET",
"HTTP-Version": "HTTP/1.1",
"Host": "opensearchtarget",
"Authorization": "Basic YWRtaW46bXlTdHJvbmdQYXNzd29yZDEyMyE=",
"User-Agent": "curl/8.5.0",
"Accept": "*/*",
"body": ""
},
"targetResponses": [{
"HTTP-Version": {"keepAliveDefault": true},
"Status-Code": 200,
"Reason-Phrase": "OK",
"response_time_ms": 721,
"content-type": "text/plain; charset=UTF-8",
"content-length": "484",
"body": "health status index uuid ..."
}],
"connectionId": "0242acfffe13000a-0000000a-00000005-1eb087a9beb83f3e-a32794b4.0",
"numRequests": 1,
"numErrors": 0
}
Amazon CloudWatch 指标和仪表盘
迁移助手会创建一个名为 MigrationAssistant_ReindexFromSnapshot_Dashboard
的 Amazon CloudWatch 仪表盘,以可视化回填过程的健康状况和性能。此仪表盘结合了回填工作器和迁移到 Amazon OpenSearch Service 的指标,提供了对捕获代理和流量重放器组件的性能和健康状况的洞察,包括以下指标:
- 读取和写入的字节数。
- 活动连接数。
- 重放速度乘数。
您可以在部署迁移助手的 AWS 区域的 AWS 管理控制台的 CloudWatch 仪表盘中找到捕获和重放仪表盘。
流量重放器向 Amazon CloudWatch 发送各种 OpenTelemetry 指标,并通过 AWS X-Ray 发送追踪。以下是一些有助于评估迁移性能的有用指标。
sourceStatusCode
此指标跟踪源集群和目标集群的 HTTP 状态代码,并具有 HTTP 动词(例如 GET
或 POST
)和状态代码系列(200-299)的维度。这些维度可以帮助快速识别源和目标之间的差异,例如当 DELETE 200s
变为 4xx
或 GET 4xx
错误变为 5xx
错误时。
lagBetweenSourceAndTargetRequests
此指标显示请求到达源集群和目标集群之间的延迟。当加速因子大于 1 且目标集群能够高效处理请求时,该值应随着重放的进行而减小,表明重放延迟减少。
其他指标
还会报告以下指标:
- 吞吐量:
bytesWrittenToTarget
和bytesReadFromTarget
指示到集群和从集群的吞吐量。 - 重试次数:
numRetriedRequests
跟踪由于源和目标之间的状态代码不匹配而重试的请求数量。 - 事件计数:各种
(*)Count
指标跟踪已完成事件的数量。 - 持续时间:
(*)Duration
指标衡量过程中每个步骤的持续时间。 - 异常:
(*)ExceptionCount
显示在每个处理阶段遇到的异常数量。
CloudWatch 考量
推送到 CloudWatch 的指标和仪表盘可能会经历大约 5 分钟的可见性延迟。CloudWatch 还会保留更高分辨率的数据,但时间比低分辨率数据短。有关更多信息,请参阅Amazon CloudWatch 概念。