亚马逊AWS官方博客

使用新的声道 SSML 功能修改 Amazon Polly 语音的音品

今天,Amazon Polly 团队很高兴地宣布推出一项新的语音合成标记语言 (SSML) 功能,该功能使得开发人员可以修改任意文本到语音转换 (TTS) 声音的音品。这是一项极具吸引力的功能,适合希望在 Amazon Polly 产品组合中自定义现有语音的客户,使得声音更加贴近在其使用案例中所塑造的特定角色。客户在场景中需要使用多个不同的声音时,该功能尤为有用,因为音品功能使得客户可以轻松地从可用的各个 Amazon Polly 语音自定义多个声音形象。

什么是音品?

音品 描述了人们所感受到的音色或音质,这与音高或音量无关。它经常用于音乐中,例如用于区分铜管乐器和弦乐器,或者用于描述中提琴与小提琴的细微差别。音品是一种可用于区分各种乐器的感知属性,即使这些乐器都在以相同的音量演奏相同的调子。与此类似,在具体的语音场景中,音品是一个声音与另一个声音的区别,即使这些声音具有相同的音高 (即其基本频率) 和音量 (振幅)。

每个人的声音都是独一无二的,这是由于多种因素造成的,包括人的生理机能以及发出声音的方式。每个人的声带、声道的大小和形状甚至整个身体的大小和形状,在决定其正常的语音品质方面都起到了重要的作用。有一些方法,例如个人控制舌头的位置、收紧或松弛肌肉或者施加气压,都可以改变语音的音高、音量和音品。经过专业训练的演员可以学习控制这些动作,甚至能够改变自己的声音来模仿他人的声音。

声道与音高

影响到语音音品的一项重要生理特征是声道,这是从声带顶部直到嘴唇边缘的一个空气腔体。有多块肌肉可以用于改变声道腔体的形状,可以让它变长、变短、变宽或变窄。这些改变的效果是导致放大或过滤掉语音。

音高 是一项听觉属性,影响感受到的声音是高还是低。在发出语音的具体过程中,音高由声带振动的频率决定。相比男性,女性通常具有较短的声带,振动频率较高 (每秒约 180 到 200 个周期)。平均而言,男性具有较长的声带,振动更慢 (每秒约 110 个周期)。与此类似,女性的平均声道长度比男性要短 (分别为约 14 厘米与约 17 厘米)。

声带长度和声道长度具有内在的关联,也就是说,其中一个更长,另一个也倾向于随之更长。利用音品功能,开发人员可以在保留控制音高能力的同时更改声道的大小。

声道和语音合成

使用 vocal-tract-length SSML 标记,您可以通过更改发言者的声道来控制输入语音的音品。这听上去像是更改了发言者的身体大小。当您增加 vocal-tract-length 时,发言者的声音听上去像是他们的个子更大。减小时,听上去像是个子更小。此标记可用于 Amazon Polly 文本到语音转换产品组合中的任何语音。

下面说明了如何修改发言者声道的长度:

  • +n% 或 -n%:按当前语音的相对百分比进行更改,来调整声道长度。例如,+4% 或 -2%。
  • n%:按当前语音的绝对百分比值来调整声道长度。例如,104% 或 98%。
  • 声道长度最多可以增加 100% 和减少 50%。
  • 要将声道长度重置为当前语音的默认值,请使用 <amazon:effect vocal-tract-length=“100%”>

下面的示例说明如何修改声道长度,使用的是 Joanna 的语音:

<speak>
This is my original voice, without any modifications. <amazon:effect vocal-tract-length="+15%"> Now, imagine that I am much bigger. </amazon:effect> <amazon:effect vocal-tract-length="-15%"> 
Or, perhaps you prefer my voice when I'm very small? </amazon:effect> You can also control the 
timbre of my voice by making more minor adjustments. <amazon:effect vocal-tract-length="+10%"> For example, by making me sound just a little bigger. </amazon:effect> <amazon:effect vocal-tract-length="-10%"> Or instead, making me sound only somewhat smaller. </amazon:effect> 
</speak> 
立即收听

语音由 Amazon Polly 提供

(more…)

Amazon ElastiCache 更新 – 在线调整 Redis 集群大小

使用 Amazon ElastiCache,您可以轻松设置快速的内存数据存储和缓存。由于支持两款最流行的开源产品 (Redis 和 Memcached),ElastiCache 能够满足游戏排行榜、内存分析和大规模消息收发的严格要求。

今天,我准备为大家介绍 Amazon ElastiCache for Redis 的一项重要补充。您已经可以创建拥有多达 15 个分片的集群,每个分片负责为一组特定的槽存储键和值 (每个集群拥有整整 16,384 个槽)。一个集群可扩展至存储 3.55 TB 的内存数据,同时每秒支持多达 2,000 万次读取和 450 万次写入。

现在可以在线调整大小
您现在可以调整正在运行的 ElastiCache for Redis 集群中的分片数量,而该集群仍可保持在线状态并响应请求。这样一来,您便可对流量和数据量的变更作出反应,而无需使集群脱机或从空缓存开始。您也可以重新平衡正在运行的集群,以便均匀地重新分配槽空间,而不更改分片数量。

启动重新分片或重新平衡操作时,ElastiCache for Redis 首先会准备一个计划,确保槽在集群的分片中均匀分配。然后,它在分片之间转移槽,并行移动许多槽以提高效率。这都是在集群继续响应请求期间发生,对写入移动中的槽时的写入吞吐量的影响较小。迁移率取决于实例类型、网络速度、槽的读/写流量,通常约为 1 GB/分钟。

重新分片和重新平衡操作适用于在启用集群模式的情况下创建的 Redis 集群:

对集群重新分片
通常,当开始面临巨大的内存压力或各个节点日益成为瓶颈时,您就知道是时候通过重新分片来扩展集群了。您可以观察集群的 CloudWatch 指标以识别每种情况:

Memory Pressure – 可用内存、交换分区使用情况、用于缓存项目的字节数。

CPU Bottleneck – CPU 利用率、当前连接、新连接。

Network Bottleneck – 网络输入字节数、网络输出字节数。

您可以使用 CloudWatch 控制面板来监控这些指标,并使用 CloudWatch 警报来自动执行重新分片流程。

要从 ElastiCache 控制面板对 Redis 集群执行重新分片,请单击该集群以访问详细信息页面,然后单击 Add shards 按钮:

输入要添加的分片数量和 (可选) 所需的可用区数量,然后单击 Add

集群的状态将变为正在修改,且重新分片流程将启动。时间从几分钟到几小时不等,如上文所述。您可以在详细信息页面上跟踪该集群的进度:

您可以看到槽在分片之间移动:

您还可以观察该集群的事件:

重新分片期间,您应避免使用 KEYSSMEMBERS 命令,以及计算密集型 Lua 脚本,以便减轻集群分片上的负载。您应完全避免 FLUSHDBFLUSHALL 命令;使用这些命令会中断然后中止重新分片流程。

当该流程完成时,每个分片的状态都将返回至 available

删除分片时会发生同样的流程。

槽重新平衡
您可以通过转至集群的详细信息页面并单击 Rebalance Slot Distribution 来执行此操作:

需知信息
下面是需要牢记的关于此新功能的一些事项:

Engine Version – 您的集群必须运行 3.2.10 版 Redis 引擎。

Migration Size – 不会迁移序列化后包含大于 256 MB 的项目的槽。

Cluster Endpoint – 集群终端节点不会因为重新分片或重新平衡而更改。

现已推出
此功能现已推出,您可以立即开始使用。

Jeff

Matrix Analytics 在 AWS 上使用深度学习来改善早期癌症检测

Matrix Analytics 致力于帮助拯救生命。这家位于科罗拉多州的创业公司使用 Amazon Web Services (AWS) 上的深度学习,跟踪诊断患有肺结节的患者的疾病发展情况。虽然肺结节通常为良性,但是密切监视并采取后续治疗,对于确诊结节是否会转变以及何时转变为恶性肿瘤非常关键。

公司创始人 Aki Alzubaidi 博士最初就职于 Glenwood Springs 医院,他发现有些患者由于未进行检查而情况恶化。用于跟踪患者的系统非常繁琐且杂乱,使得许多患者未能接受推荐的后续治疗,造成了本可避免的不良后果。

预测癌症风险和管理医疗

该公司的旗舰软件应用程序 LungDirect 使用双管齐下的方法进行早期癌症介入治疗:预测恶性肿瘤风险和自动化后续治疗。

首先,采用深度学习算法构建的先进计算机成像功能根据下列因素评估肺结节的恶性肿瘤风险:结节大小、形状、密度、体积以及患者个人情况,例如烟龄、年龄、性别和种族。“我们希望能够获取所有的临床信息,例如放射科测试、实验室测试或个人临床病理因素,然后获得病情发展的可能性,在实用工具上提供结果并管理接下来的步骤,这就是我们采用深度学习的目标,”Alzubaidi 博士说到。

为了发现可能隐藏在数据之下的不同非线性关系类别,采用了五种不同的机器学习模型类别。使用一组计算机成像算法,直接从图像中自动提取四种不同的特征类别。

开发一种工具,来“不可思议地自动”读取患者扫描图像来预测和诊断癌症,这不是一件易事。不过,Matrix Analytics 非常快地开发出了验证概念的原型。然后,该公司实施深度学习模型并与现有文献中的基准进行比较。

(more…)

Apache MXNet 版本 0.12 扩展了 Gluon 功能以支持前沿的研究

上周,Apache MXNet 社区发布了 MXNet 版本 0.12。主要功能是支持 NVIDIA Volta GPU 和 sparse tensor。该版本还包括一些新的 Gluon 编程接口功能。特别是,可以通过这些功能在您的深度学习模型中轻松开展前沿的研究:

  • 变分丢弃;可用于有效地应用丢弃技术以减轻递归神经网络 (RNN) 中的过拟合问题
  • 卷积 RNN、长短期记忆 (LSTM) 和门控循环单元 (GRU) 单元;可用于对具有基于时间的序列和空间维度的数据集进行建模
  • 七个新的损失函数、导出功能和训练器函数增强功能

变分丢弃 (VariationalDropoutCell) 根据最新的研究提供一种新的工具以减轻 RNN 中的过拟合问题。本文参考了“A Theoretically Grounded Application of Recurrent Neural Networks”“RNNDrop: A Novel Approach for RNNs in ASR”。过拟合是一种建模错误,其中拟合的模型与训练数据集非常接近,以至于在查看新数据或测试数据集时,将会降低其预测精度。丢弃是一种建模技术,它随机地将模型参数归零,以便模型在训练过程中不会过度依赖于任何单个输入或参数。不过,这种技术尚未成功应用于 RNN。迄今为止的研究侧重于仅将丢弃完全随机地应用于输入和输出,即,在 RNN 的所有时间步长中将其归零。变分丢弃消除了这种涵盖所有时间步长的随机性,并在每个时间步长将相同的随机丢弃数组 (或掩码) 应用于 RNN 的输入、输出和隐藏状态。

(more…)

新增 – 适用于 AWS 服务的 AWS PrivateLink:在您的 VPC 中的 Kinesis、Service Catalog、EC2 Systems Manager、Amazon EC2 API 和 ELB API

这篇客座文章是由 Amazon Virtual Private Cloud 高级工程师 Colm MacCárthaigh 撰写的。


自 2015 年推出 VPC 终端节点以来,创建终端节点已成为从 Amazon Virtual Private Cloud (VPC) 中安全地访问 S3 和 DynamoDB 的一种常见方法,而无需使用 Internet 网关、NAT 网关或防火墙代理。在使用 VPC 终端节点时,VPC 和 AWS 服务之间的路由是由 AWS 网络处理的,并且可以使用 IAM 策略控制对服务资源的访问。

今天,我们宣布推出 AWS PrivateLink,这是最新一代的 VPC 终端节点,旨在使客户以高度可用且可扩展的方式访问 AWS 服务,同时将所有流量保持在 AWS 网络内。现在,可以在您的 VPC 中使用 KinesisService CatalogAmazon EC2EC2 Systems Manager (SSM) 和 Elastic Load Balancing (ELB) API 并支持即将推出的更多服务,如 Key Management Service (KMS) 和 Amazon Cloudwatch

在使用传统终端节点时,就像在您的 VPC 和 AWS 服务之间连接一条虚拟电缆一样。连接到 AWS 服务不需要使用 Internet 或 NAT 网关,但终端节点保留在您的 VPC 外部。在使用 PrivateLink 时,将使用弹性网络接口 (ENI) 和您的 VPC 子网中的 IP 地址直接在您的 VPC 中创建终端节点。该服务现在位于您的 VPC 中,从而可以通过私有 IP 地址连接到 AWS 服务。这意味着,可以使用 VPC 安全组管理对终端节点的访问,并且还可以通过 AWS Direct Connect 从本地访问 PrivateLink 终端节点。

通过使用由 PrivateLink 提供支持的服务,客户现在可以管理实例队列,创建和管理 IT 服务目录以及存储和处理数据,而不要求流量通过 Internet。

创建 PrivateLink 终端节点
为了创建 PrivateLink 终端节点,我导航到 VPC 控制台,选择终端节点,然后选择创建终端节点

然后,我选择要访问的服务。新的 PrivateLink 终端节点具有“接口”类型。在这种情况下,我希望直接从我的 VPC 中使用 Kinesis 服务,因而我选择 kinesis-streams 服务。

此时,我可以选择要在其中启动我的新终端节点的 VPC,然后选择 ENI 和 IP 地址所在的子网。我还可以将终端节点与新的或现有的安全组相关联,以使我能够控制哪些实例可以访问终端节点。

由于 PrivateLink 终端节点将使用我的 VPC 中的 IP 地址,因此,我可以选择使用 VPC 私有 DNS 覆盖 AWS 服务 DNS 名称的 DNS。通过选中启用私有 DNS 名称,从我的 VPC 中查找“kinesis.us-east-1.amazonaws.com”将会解析为我正在创建的终端节点的 IP 地址。这样,就可以无缝地转换到终端节点,而无需对我的应用程序进行任何更改。默认情况下,如果我希望在处理流量之前测试或配置终端节点,我可以将其禁用,并随时编辑终端节点以对其进行更改。

在我准备就绪并对 VPC、子网和 DNS 设置感到满意后,我单击创建终端节点以完成该过程。

使用 PrivateLink 终端节点

默认情况下,如果启用了私有 DNS 名称,使用 PrivateLink 终端节点与使用 SDK、AWS CLI 或从您的 VPC 中访问服务 API 的其他软件一样简单。无需更改任何代码或配置。

为了支持测试和高级配置,每个终端节点还会获得一组专用于您的终端节点的唯一 DNS 名称。终端节点和区域名称具有一个主名称。

主名称对于通过 Direct Connect 访问您的终端节点特别有用,而无需在本地使用任何 DNS 覆盖。当然,也可以在您的 VPC 中使用主名称。
主名称和主服务名称 (由于我选择覆盖该名称) 包括区域容错,并平衡可用区之间的流量。如果我采用的架构使用区域隔离技术以实现故障遏制和分隔并降低延迟,或是用来最大限度减少区域数据传输,我也可以使用区域名称明确控制我的流量是在区域之间流动,还是保留在区域内。

定价和可用性
目前,在中国 (北京) 以外的所有 AWS 商业区域中都提供了 AWS PrivateLink。有关各个服务的区域可用性,请参阅我们的文档

起价为每小时 0.01 美元,外加每 GB 0.01 美元的数据处理费用。在可用区之间或通过 Direct Connect 在您的终端节点和本地之间传输的数据也会产生常见的 EC2 区域和 Direct Connect 数据传输费用。有关更多信息,请参阅 VPC 定价

Colm MacCárthaigh

新增 Amazon S3 加密和安全功能

早在 2006 年,当我宣布 S3 时,我写道:“此外,每个块都受 ACL (访问控制列表) 的保护,从而允许开发人员根据需要保持数据私有、共享以供读取或共享以供读写。”

起点是那个具有私有存储桶和用于授予访问权限的 ACL 的初始模型,此后我们添加了对存储桶策略服务器访问日志记录版本控制API 日志记录跨区域复制以及多个客户端服务器端加密选项的支持,所有这些都是为了给您提供所需的工具,保护您的数据,同时允许您根据需要与客户和合作伙伴共享数据。我们还加入了人工智能和机器学习作为演绎元素,并推出了 Amazon Macie,这一工具可帮助您发现、分类和保护海量的内容

今天,我们将要向 S3 中添加五个新的加密和安全功能:

默认加密 – 现在,您可以强制存储桶中的所有对象都必须以加密形式保存,而不必构造一个拒绝未加密对象的存储桶策略。

权限检查 – S3 控制台现在在每个可公开访问的 S3 存储桶旁边显示一个显眼的指示器。

跨区域复制 ACL 覆盖 – 当您跨 AWS 账户复制对象时,您现在可以指定对象获取一个新的 ACL,以便对目标账户进行完全访问。

涉及 KMS 的跨区域复制 – 您现在可以复制使用由 AWS Key Management Service (KMS) 管理的密钥进行加密的对象。

详细清单报告 – S3 清单报告现在包括每个对象的加密状态。该报告本身也可以加密。

让我们了解一下每个功能…

默认加密
您的 S3 对象有三个服务器端加密选项:SSE-S3 (使用由 S3 管理的密钥)、SSE-KMS (使用由 AWS KMS 管理的密钥) 以及 SSE-C (使用您管理的密钥)。我们的一些客户,特别是那些需要满足规定在静态时使用加密的合规性要求的用户,已使用存储桶策略来确保每个新存储的对象都被加密。虽然这有助于他们满足要求,但仅仅拒绝存储未加密对象是一个不完善的解决方案。

现在,您可以通过安装存储桶加密配置,强制存储桶中的所有对象都必须以加密形式保存。如果将未加密对象提交给 S3,并且配置指明必须使用加密,则该对象将使用为该存储桶指定的加密选项进行加密 (PUT 请求还可以指定不同的选项)。

下面是在您创建新存储桶时,如何使用 S3 控制台来启用此功能。像往常一样输入存储桶的名称,然后单击下一步。然后向下滚动并单击默认加密

选择所需的选项,然后单击保存 (如果您选择 AWS-KMS,则还需要指定 KMS 密钥):

您还可以通过调用 PUT 存储桶加密函数来进行此更改。它必须指定 SSE 算法 (SSE-S3 或 SSE-KMS),并且可以选择引用 KMS 密钥。

实施此功能时,请牢记以下几点:

SigV4 – 通过 S3 REST API 对存储桶策略进行的访问必须使用 SigV4 签名,并且通过 SSL 连接完成。

更新存储桶策略 – 您应该检查并仔细修改当前拒绝未加密对象的现有存储桶策略。

高容量使用 – 如果您使用的是 SSE-KMS,并且每秒上传成百上千个对象,则可能会在执行加密和解密操作时碰到 KMS 限制。只需提交一个支持案例并申请更高的限制:

跨区域复制 – 未加密的对象将根据目标存储桶的配置进行加密。加密的对象将保持不变。

权限检查
存储桶策略、存储桶 ACL 和对象 ACL 的组合使您能够非常精细地控制对您的存储桶及其内部对象的访问。为了确保您的策略和 ACL 结合起来以创造所需的效果,我们最近推出了一组托管配置规则来保护您的 S3 存储桶。正如我在文章中提到的,这些规则利用了我们的一些工作来应用自动形式推理

我们现在使用相同的基础技术来帮助您在对存储桶策略和 ACL 进行更改时便可看到更改的影响。如果您打开一个存储桶供公开访问,您立刻就会知道,这能让您充满信心地进行更改。

下面是它在 S3 控制台主页上的显示情况 (为方便查看,我按访问权限列进行了排序):

当您在单个存储桶中查看时,还会显示公共指示器:

您还可以查看哪些权限元素 (ACL 和/或存储桶策略) 在启用公开访问:

跨区域复制 ACL 覆盖
我们的客户经常使用 S3 的跨区域复制,在一个单独的 AWS 账户中将其任务关键型对象和数据复制到目标存储桶中。除了复制对象外,复制过程还会复制对象 ACL 以及任何与该对象关联的标签

我们使此功能更加有用,具体来说就是能让您在传输过程中启用 ACL 替换,以便它向目标存储桶的所有者授予完全访问权限。通过此更改,源和目标数据的所有权将跨 AWS 账户进行拆分,从而使您能够为原始对象及其副本维护单独且不同的所有权堆栈。

要在设置复制时启用此功能,请通过指定账户 ID 和存储桶名称并单击保存,在不同的账户和区域中选择目标存储桶:

然后单击更改对象所有权…

我们还使您更容易为目标账户中的目标存储桶设置密钥策略。只需登录到该账户并找到该存储桶,然后单击管理复制,然后从更多菜单中选择接收对象…

输入源账户 ID,启用版本控制,检查策略,应用策略,然后单击完成

涉及 KMS 的跨区域复制
跨区域复制使用 SSE-KMS 加密的对象是我们今天要解决的一个有趣的挑战。由于 KMS 密钥特定于特定区域,因此仅复制加密的对象将不起作用。

现在,您可以在设置跨区域复制时选择目标键。在复制过程中,加密的对象通过 SSL 连接复制到目标。在目标位置,数据键使用在复制配置中指定的 KMS 主密钥进行加密。对象始终保持原来的加密形式;只有包含密钥的信封才会实际发生更改。

下面是在设置复制规则时如何启用此功能:

正如我前面提到的,在开始大量使用此功能之前,您可能需要请求增大 KMS 限制。

详细清单报告
最后但同样重要的是,您现在可以请求每日或每周 S3 清单报告包含有关每个对象的加密状态的信息:

正如您所看到的,您还可以为该报告请求 SSE-S3 或 SSE-KMS 加密。

现在提供
这些功能现已全部提供,您可以立即开始使用!这些功能没有收费,但会对 KMS 调用S3 存储S3 请求以及区域间数据传输按通常费率收费。

Jeff

现已推出 – Amazon EC2 的计算密集型 C5 实例

我很高兴地宣布,新的计算密集型 C5 实例今天在三个 AWS 区域推出,有六种大小规格!

这些实例专用于计算密集型应用程序,例如批处理、分布式分析、高性能计算 (HPC)、广告服务、高度可扩展的多人游戏和视频编码。新实例提供了比 C4 实例高 25% 的价格/性能改进,对于某些工作负载可超过 50%。它们还有额外的每 vCPU 内存,而且 (对于可以利用新 AVX-512 指令的代码) 对于向量和浮点工作负载有两倍的性能。

多年来,我们一直在不停地工作,为客户提供可能的最佳网络、存储和计算性能,长期专注于将许多类型的工作分流到由 AWS 设计和建造的专用硬件上。C5 实例类型包含了我们的最新一代硬件分流,另外还在添加一个与我们的硬件密不可分地一起运行的新管理程序方面又迈出了一大步。新的管理程序允许我们让您访问主机硬件提供的所有处理能力,同时也使性能更加一致,并进一步提高了安全性的门槛。我们将在 AWS re:Invent 分享很多关于它的技术细节。

新实例
C5 实例有六种大小:

实例名称 vCPU
RAM
EBS 带宽 网络带宽
c5.large 2 4 GiB 最高 2.25 Gbps 最高 10 Gbps
c5.xlarge 4 8 GiB 最高 2.25 Gbps 最高 10 Gbps
c5.2xlarge 8 16 GiB 最高 2.25 Gbps 最高 10 Gbps
c5.4xlarge 16 32 GiB 2.25 Gbps 最高 10 Gbps
c5.9xlarge 36 72 GiB 4.5 Gbps 10 Gbps
c5.18xlarge 72 144 GiB 9 Gbps 25 Gbps

每个 vCPU 都是 3.0 GHz Intel Xeon Platinum 8000 系列处理器上的硬件超线程。此自定义处理器针对 EC2 进行了优化,能让您在两个最大大小上完全控制 C 状态,从而能让您使用 Intel 睿频加速技术以最高 3.5 GHz 的速度运行单个内核。

从表中可以看出,四个最小实例大小提供的 EBS 和网络带宽比前一代计算密集型实例大得多。

由于所有网络和存储功能都是在硬件中实现的,因此 C5 实例需要包括 Elastic Network Adapter (ENA) 和 NVMe 的驱动程序的 HVM AMI。最新的 Amazon Linux、Microsoft Windows、Ubuntu、RHEL、CentOS、SLES、Debian 和 FreeBSD AMI 都支持 C5 实例。如果您正在进行机器学习推理或其他计算密集型工作,请务必检查最新版本的 Intel Math Kernel Library。它已针对 Intel® Xeon® Platinum 处理器进行了优化,并有可能大大加快您的工作。

为了与使用 Xen 管理程序的实例保持兼容,EBS 卷的设备名称将继续使用现有的 /dev/sd/dev/xvd 前缀。不使用在将卷附加到实例时提供的设备名称,因为 NVMe 驱动程序会分配其自己的设备名称 (阅读 Amazon EBS 和 NVMe 以了解更多信息):

nvme 命令显示有关每个卷的其他信息 (如果需要,可使用 sudo yum -y install nvme-cli 安装它):

输出中的 SN 字段可以通过在“vol”前缀后面插入“-”映射到 EBS 卷 ID (可惜,NVMe SN 字段的长度不足以存储整个 ID)。下面是一个使用此信息创建每个附加卷的 EBS 快照的简单脚本:

$ sudo nvme list | \
  awk '/dev/ {print(gensub("vol", "vol-", 1, $2))}' | \
  xargs -n 1 aws ec2 create-snapshot --volume-id

只需多做一点工作 (以及大量的测试),您可以创建一个脚本来扩展将要变满的 EBS 卷。

到达 C5
正如我前面提到的,我们将工作分流到硬件加速器的工作已经进行了相当长一段时间。概括如下:

CC1 – 在 2010 年推出,CC1 专用于支持横向扩展的 HPC 应用程序。它是第一个支持 10 Gbps 网络的 EC2 实例,也是第一个支持 HVM 虚拟化的实例之一。我们为 CC1 设计的网络结构 (基于我们自己的交换机硬件) 已成为所有 AWS 数据中心的标准。

C3 – 在 2013 年推出,C3 引入了增强型联网,并使用专用硬件加速器来支持每个 Virtual Private Cloud (VPC) 内部的软件定义网络。硬件虚拟化从管理程序中删除 I/O 堆栈,从而有利于来宾操作系统进行直接访问,因此提高性能并减少可变性。

C4 – 在 2015 年推出,C4 实例是在默认情况下通过专用网络连接优化的 EBS,并且还将 EBS 处理 (包括加密 EBS 卷的 CPU 密集型加密操作) 分流到硬件加速器。

C5 – 今天推出,驱动 C5 实例的管理程序允许将主机 CPU 的所有资源几乎专用于客户实例。ENA 网络和与 EBS 连接的 NVMe 接口都是由硬件加速器驱动的。这些实例不需要 (或支持) Xen 半虚拟化网络或块设备驱动程序 (两者都已被删除,以提高效率)。

展望未来,我们将使用此管理程序来驱动其他实例类型,并计划在一组 AWS re:Invent 会话中共享其他技术细节。

今天启动 C5
您可以今天在美国东部 (弗吉尼亚北部)美国西部 (俄勒冈)欧洲 (爱尔兰) 区域以按需和竞价形式 (预留实例也可用) 启动 C5 实例,其它区域则在准备中。

我离开之前的一个快速说明:当前的 NVMe 驱动程序没有针对高性能顺序工作负载进行优化,我们不建议将 C5 实例与 sc1st1 卷结合使用。我们知道这个问题,并一直在努力优化这个重要使用案例的驱动程序。

Jeff

EC2 可转换预留实例更新 – 新的 1 年 CRI,合并和拆分

我们在大约一年前推出了 EC2 的可转换预留实例。可转换 RI 为您提供了大幅折扣 (与按需相比通常为 54%),并允许您更改与 RI 相关联的实例系列和其他参数 (如果需要更改)。

今天,我们推出具有 1 年期的可转换 RI,这是对现有的 3 年期的补充。我们还允许您交换部分 RI 以及执行批量交换,从而使可转换预留实例模型更加灵活。

新的 1 年期可转换 RI
具有 1 年期的可转换预留实例现已推出。这将给您更多选项和更多灵活性;您现在可以根据需要购买 1 年期和 3 年期可转换预留实例 (CRI) 的组合。有财政约束的初创公司将会发现这一选项颇具吸引力,而其他可能无法做出运行超过一年的承诺的企业也会觉得有吸引力。

合并和拆分可转换 RI
假设您开始在 M4 实例上运行 Web 和应用程序服务器并使用可转换 RI 来节约资金。稍后,在有了优化实践后,您可以将应用程序服务器迁移到 C4 实例。随着今天的推出,您可以用您的部分 M4 可转换 RI 来交换 C4 可转换 RI。您还可以合并两个或更多 CRI (可能用于较小的实例),获得一个 CRI 以用于较大的实例。

可转换预留实例的交换模型基于拆分、交换和合并。比方说,我拥有一个 3 年预付部分费用 CRI 用于四个t2.micro 实例:

我的应用程序已更改,现在我想要使用一对 t2.micro 实例和单个 r4.xlarge。第一步是将此 CRI 拆分为我想要保留的部分和我想要交换的部分。我选择它并单击修改预留实例。然后我创建所需的配置,并单击“继续”:

我审核请求并单击提交修改

CRI 的状态发生变化,以表明它正被修改。过一会儿,它将被标记为停用,被已激活的一对替换:

现在我可以交换一个 2 实例 CRI。我选择它,并单击交换预留实例,然后为我的新 CRI 输入所需配置:

我单击查找产品以查看我的选项,并选择所需的选项,即 r4.xlarge 预付部分费用。正如您所看到的,在计算预付款时,控制台“进行数学运算”考虑了不必要 CRI 的剩余预付价值 (在本例中为 139.995 美元):

当我做好继续准备后,我单击交换。这将启动交换过程,并让我知道可能需要数分钟才能完成。

我还可以将两个或更多可转换预留实例合并到一起,然后将它们用作交换的起始点。为此,我仅需选择现有 CRI,单击操作,选择交换预留实例。我可以看到所选 CRI 的总剩余预付价值,并相应地继续操作:

您可以合并具有不同开始日期和/或期限长度的 CRI。合并后的 CRI 将具有离交换日期最远的 RI 的过期日期。将不同期限长度的 CRI 合并在一起,总是会产生 3 年 CRI。

您还可以使用 AWS 命令行界面 (CLI) 和 EC2 API 执行拆分、交换和合并操作。

现已推出
本文描述的所有功能和 1 年 CRI 现已推出,您可以立即开始使用它们。

Jeff

AWS 价目表 API 更新 – 新增查询和元数据函数

原始 AWS 价目表 API (如新增 – AWS 价目表 API中所述) 使您可以通过结构化 URL 访问 JSON 和 CSV 形式的价格。虽然这对某些类型的成本管理工具很有效,但文件的大小和复杂性使得它们难以下载,而且难以解析。今天,我们将要通过添加新函数来更新 API,使您可以执行精细价格查询,从而仅返回您需要的价格。这将使您能够在移动应用程序和基于浏览器的应用程序中使用这些价格。

新增函数
下面是新增函数:

DescribeServices – 返回用于定义服务中的产品的属性键集合。例如,为 EC2 返回的键将包括 physicalProcessormemoryoperatingSystemlocationtenancy

GetAttributeValues – 返回给定属性键的所有允许值。例如,operatingSystem 键的值包括 WindowsRHELLinuxSUSElocation 键的值包括 US East (N. Virginia)Asia Pacific (Mumbai)

GetProducts – 返回与基于服务名称和属性值的筛选条件表达式匹配的所有产品及其公开价格。

您可以从 AWS 开发工具包中访问这些函数。为了试用它们,我使用了 Python 和适用于 Python 的 AWS 开发工具包。我首先导入开发工具包并创建客户端:

import boto3
import json
import pprint

pricing = boto3.client('pricing')

下面是我如何列出所有服务和属性:

print("All Services")
print("============")
response = pricing.describe_services()
for service in response['Services']:
    print(service['ServiceCode'] + ": " + ", ".join(service['AttributeNames']))
print()

输出的开头部分如下所示:

All Services
============
SnowballExtraDays: productFamily, termType, usagetype, locationType, snowballType, feeDescription, servicecode, feeCode, location, operation
OpsWorks: productFamily, servicecode, termType, usagetype, locationType, location, operation, serverLocation, group
mobileanalytics: productFamily, servicecode, includedEvents, termType, usagetype, description, locationType, location, operation
IngestionServiceSnowball: productFamily, fromLocationType, termType, usagetype, locationType, toLocationType, toLocation, snowballType, servicecode, groupDescription, transferType, location, fromLocation, operation, group
IngestionService: productFamily, termType, usagetype, locationType, servicecode, groupDescription, dataAction, location, operation, group
ElasticMapReduce: productFamily, softwareType, instanceType, termType, usagetype, locationType, instanceFamily, servicecode, location, servicename, operation
datapipeline: productFamily, frequencyMode, termType, usagetype, locationType, description, executionFrequency, servicecode, location, operation, group, executionLocation
...

下面是我如何获取所有 EC2 定价属性的所有值:

print("Selected EC2 Attributes & Values")
print("================================")
response = pricing.describe_services(ServiceCode='AmazonEC2')
attrs = response['Services'][0]['AttributeNames']

for attr in attrs:
    response = pricing.get_attribute_values(ServiceCode='AmazonEC2', AttributeName=attr)

    values = []
    for attr_value in response['AttributeValues']:
        values.append(attr_value['Value'])

    print("  " + attr + ": " + ", ".join(values))

输出的开头部分如下所示:

Selected EC2 Attributes & Values
================================
  volumeType: Throughput Optimized HDD, Provisioned IOPS, Magnetic, General Purpose, Cold HDD
  maxIopsvolume: 500 - based on 1 MiB I/O size, 40 - 200, 250 - based on 1 MiB I/O size, 20000, 10000
  instanceCapacity10xlarge: 1
  locationType: AWS Region
  instanceFamily: Storage optimized, Micro instances, Memory optimized, GPU instance, General purpose, Compute optimized
  operatingSystem: Windows, SUSE, RHEL, NA, Linux
...

下面是我如何使用服务名称和属性值来获取在亚太 (孟买) 区域具有 64 vCPU、256 GiB 内存、预装 SQL Server Enterprise 的 EC2 实例的价格列表。每个价格都是一个 JSON 字符串:

print("Selected EC2 Products")
print("=====================")

response = pricing.get_products(
     ServiceCode='AmazonEC2',
     Filters = [
         {'Type' :'TERM_MATCH', 'Field':'operatingSystem', 'Value':'Windows'              },
         {'Type' :'TERM_MATCH', 'Field':'vcpu',            'Value':'64'                   },
         {'Type' :'TERM_MATCH', 'Field':'memory',          'Value':'256 GiB'              },
         {'Type' :'TERM_MATCH', 'Field':'preInstalledSw',  'Value':'SQL Ent'              },
         {'Type' :'TERM_MATCH', 'Field':'location',        'Value':'Asia Pacific (Mumbai)'}
     ],
     MaxResults=100
)

for price in response['PriceList']:
 pp = pprint.PrettyPrinter(indent=1. width=300)
 pp.pprint(json.loads(price))
 print()

输出的开头部分如下所示 (还有很多):

Selected EC2 Products
=====================
{'product': {'attributes': {'clockSpeed': '2.3 GHz',
                            'currentGeneration': 'Yes',
                            'dedicatedEbsThroughput': '10000 Mbps',
                            'ecu': '188',
                            'enhancedNetworkingSupported': 'Yes',
                            'instanceFamily': 'General purpose',
                            'instanceType': 'm4.16xlarge',
                            'licenseModel': 'No License required',
                            'location': 'Asia Pacific (Mumbai)',
                            'locationType': 'AWS Region',
                            'memory': '256 GiB',
                            'networkPerformance': '20 Gigabit',
                            'normalizationSizeFactor': '128',
                            'operatingSystem': 'Windows',
                            'operation': 'RunInstances:0102',
                            'physicalProcessor': 'Intel Xeon E5-2686 v4 (Broadwell)',
                            'preInstalledSw': 'SQL Ent',
                            'processorArchitecture': '64-bit',
                            'processorFeatures': 'Intel AVX, Intel AVX2, Intel Turbo',
                            'servicecode': 'AmazonEC2',
                            'servicename': 'Amazon Elastic Compute Cloud',
                            'storage': 'EBS only',
                            'tenancy': 'Shared',
                            'usagetype': 'APS3-BoxUsage:m4.16xlarge',
                            'vcpu': '64'},
             'productFamily': 'Compute Instance',
             'sku': '24GRA8RB2KZ9NPCS'},
 'publicationDate': '2017-10-07T00:26:55Z',
 'serviceCode': 'AmazonEC2',
...

响应的下一部分包含一组条款,每个条款都描述了购买实例的特定方式 (按需或多种类型的预留实例):

 'terms': {'OnDemand': {'24GRA8RB2KZ9NPCS.JRTCKXETXF': {'effectiveDate': '2017-09-01T00:00:00Z',
                                                        'offerTermCode': 'JRTCKXETXF',
                                                        'priceDimensions': {'24GRA8RB2KZ9NPCS.JRTCKXETXF.6YS6EN2CT7': {'appliesTo': [],
                                                                                                                       'beginRange': '0',
                                                                                                                       'description': '$30.88 per On Demand Windows with SQL Server Enterprise m4.16xlarge Instance Hour',
                                                                                                                       'endRange': 'Inf',
                                                                                                                       'pricePerUnit': {'USD': '30.8800000000'},
                                                                                                                       'rateCode': '24GRA8RB2KZ9NPCS.JRTCKXETXF.6YS6EN2CT7',
                                                                                                                       'unit': 'Hrs'}},
                                                        'sku': '24GRA8RB2KZ9NPCS',
                                                        'termAttributes': {}}},
           'Reserved': {'24GRA8RB2KZ9NPCS.38NPMPTW36': {'effectiveDate': '2017-04-30T23:59:59Z',
                                                        'offerTermCode': '38NPMPTW36',
                                                        'priceDimensions': {'24GRA8RB2KZ9NPCS.38NPMPTW36.2TG2D8R56U': {'appliesTo': [], 'description': 'Upfront Fee', 'pricePerUnit': {'USD': '374227'}, 'rateCode': '24GRA8RB2KZ9NPCS.38NPMPTW36.2TG2D8R56U', 'unit': 'Quantity'},
                                                                            '24GRA8RB2KZ9NPCS.38NPMPTW36.6YS6EN2CT7': {'appliesTo': [],
                                                                                                                       'beginRange': '0',
                                                                                                                       'description': 'Windows with SQL Server Enterprise (Amazon VPC), m4.16xlarge reserved instance applied',
                                                                                                                       'endRange': 'Inf',
                                                                                                                       'pricePerUnit': {'USD': '14.2400000000'},
                                                                                                                       'rateCode': '24GRA8RB2KZ9NPCS.38NPMPTW36.6YS6EN2CT7',
                                                                                                                       'unit': 'Hrs'}},
                                                        'sku': '24GRA8RB2KZ9NPCS',
                                                        'termAttributes': {'LeaseContractLength': '3yr', 'OfferingClass': 'standard', 'PurchaseOption': 'Partial Upfront'}},
...

阅读使用 AWS 价目表 API 以了解有关这些函数及其返回数据的更多信息。

现在提供
新增函数现已推出,您可以开始在美国东部 (弗吉尼亚北部)亚太 (孟买) 区域使用它们来访问所有公有 AWS 区域和 AWS GovCloud (美国) 的元数据和价格列表,它们是免费的。

要查看如何使用这些函数的真实示例,请在 AWS 管理工具博客上查看新博客文章通过月度预算策略来控制预计用户成本

Jeff

Amazon S3 深度实践系列之二:如何实现 S3 数据跨区域高效可靠传输

背景

Amazon S3 深度实践系列之一:S3 CLI深度解析及性能测试一文中,我们深度剖析了AWS CLI S3相关命令的实际工作原理及单机下载S3数据的基本性能测试情况。在实际工作场景中,很多客户会在AWS多个区域的S3桶里面存储大量数据,而且会遇到将数据批量从一个区域一次转移到另外一个区域的情形;因此,在本篇中,作者和大家一起来探讨下出现这样的需求我们如何进行架构设计及高效实现。

架构设计

存储在S3中的对象随着时间的推移,对象数量逐渐增加,而且总体的数据量也不断膨胀,如果碰到需要将数据从某一个区域的S3存储桶完全复制到另外一个S3存储桶里面,我们会遇到哪些挑战呢?

  • 网络传输带宽的限制
  • 存储桶里面所有对象的分析和列表
  • 源存储桶和目标存储桶权限的设定
  • 传输失败识别和重试的挑战
  • 如何利用并发来加速传输及降低成本
  • 如何判断目标存储桶中的对象和源存储桶中的对象差异及完整性

在通用架构设计环节,我们将复杂的问题分解成一系列的子问题进行分析,并讨论在不同场景下的具体实现时要考虑的因素。如下图所示,我们将该任务分解成独立的五个环节,从图上我们也可以看出来,如何实现大规模数据或任务的并发执行是每个环节能否高效完成的一个很关键的技术要求;而且,只有在步骤三执行数据传输任务时,才会涉及到具体场景中的技术限制,因此我们在执行数据传输任务章节来讨论,同区域不同存储桶之间,AWS海外不同区域存储桶之间,以及AWS海外和国内不同存储桶之间的具体技术考量点。

S3对象“清单”

了解源和目标存储桶里的S3 对象是非常重要的准备工作,该章节我们讨论,如何获得S3存储桶的所有对象列表,包含对象的基本的信息,比如最新版本的对象大小,ETag等等。

Amazon S3本身提供了存储桶管理功能之清单生成功能,该功能是一个异步的AWS后台定期执行,可以实现每天生成一个存储桶清单保存成Excel格式。

同时我们也看到很多用户提问,如何实现一个自定义的清单功能,满足大家对于对象变化比较频繁的存储桶对象的实时统计场景以及更多高级自定义的业务逻辑。

接下来我们来看看这两种方法的具体实现逻辑。

利用S3 CLI实现高效的清单功能

作者利用AWS S3 CLI实现高效的清单功能基于以下两个事实前提:

  1. s3api 的 list-objects-v2虽然文档中说明最多返回1000个对象,但实测可以获得所有对象列表
  2. 同样利用s3api 的 list-objects-v2的delimiter和prefix参数,我们可以实现类似文件夹目录逐级扫描功能

基于以上两个事实,我们实现桶清单的主要逻辑如下图所示:

  • 输入参数主要是:bucket,region和IAM 配置的profile名字,profile默认为default;另外depth控制扫描的“目录”层级
  • 当depth为零时,我们直接尝试利用list-objects-v2一次性获取存储桶中所有对象列表并生成一个json格式的文件(但当桶里面对象太多时,该操作会超时)
  • 当depth为零即单线程无法直接生成存储桶清单时,我们就尝试如下迭代逻辑:
    • 生成存储桶当前“目录”里面的所有对象和该目录中所有“子目录”列表
    • 遍历上一步的“子目录”列表,迭代生成该目录下的对象列表和“子目录”列表
    • 如果遍历的深度等于输入参数depth=n,或者“子目录”列表为空,那么停止遍历子目录,直接生成该层级“目录”里面所有的对象列表

以下是几个关键点实现的代码说明,首先,生成某个“目录”前缀下所有对象列表的AWS S3 CLI命令参考,如下命令将在操作系统后台执行并生成存储桶jason中“目录”前缀“qwikLabs/”下的所有对象列表(包括所有嵌套“子目录”中的所有对象):

$ nohup aws s3api list-objects-v2 --bucket "jason" --prefix "qwikLabs/" --profile bjs > 0.obj. 2>&1

其次,如下命令将仅仅生成指定“目录”前缀“qwikLabs/”下的对象列表(不包括嵌套“子目录“的对象)和所有下一层“子目录“列表,为了加强”子目录“输出格式,我们增加了query参数:

$ nohup aws s3api list-objects-v2 --bucket "jason" --prefix "qwikLabs/" --delimiter "/" --query "{Keys:Contents[].{Key: Key, Size: Size,ETag:ETag},CommonPrefixes:CommonPrefixes[].Prefix}" --profile bjs > 0.1.obj. 2>&1

另外,为了实现并发我们利用了迭代算法以及操作系统后台异步执行AWS S3 CLI命令的方法,最终程序会生成一系列的json文件结果,存储桶中所有的对象列表分布在这些文件当中。

S3自带的清单功能

在了解了我们通过AWS CLI S3命令行工具实现自定义的清单功能之后,我们再来对比下,Amazon S3自带的清单功能。

在存储桶页面,导航到“管理“标签,Amazon S3目前提供了四项S3管理功能,其中跟本文相关的是”清单“功能。该功能支持我们对某一个存储桶,定义多个清单,用户可以根据需要,定义针对不同S3对象前缀生成各自的清单列表,并可以存储在独立的存储桶中:

同时,自带清单功能还支持定义生成清单的频率及清单中包含的对象字段,检查并确定好清单选项之后,服务会帮助我们在保存清单的目标存储桶中设置好相应的IAM策略:

清单任务保存之后,后台会异步定期执行,每次都会按时间生成manifest.json 文件和一系列的清单文件,manifest.json 里面包含这次生成的所有清单文件列表:

S3对象清单小结

Amazon S3 存储桶已经内置了清单功能,基本可以满足我们的日常需求,我们不需要重复造轮子;本章节所讨论的利用AWS S3 CLI 命令行自定义实现清单功能,更多的是作者好奇的发现,AWS S3 CLI 本身非常好用,也可以帮助我们实现类似文件目录的逐级对象列表功能,提供给有特殊场景需求的用户参考。

对象清单分解成传输任务

有了存储桶中所有的对象清单,接下来,我们就看看如何设计传输任务。设计传输任务的原则如下:

  • 如果网络条件非常良好,比如同区域的不同存储桶之间,按照作者的测试,复制带宽平均可以达到xxMB/s,如此可以直接利用S3 cp命令
  • 尽可能将单进程的复制任务分解成多个子任务并发执行,任务分解后进入到Amazon SQS队列,这样将任务分解和任务执行进行解耦
  • 如果网络条件非常一般,比如平均在10KB/s并且网络抖动大的情况下,对于超过一定大小的文件需要切割成小文件,组成子任务并发执行

传输任务分解算法的设计,涉及到几个关键参数:

  • max_task_size_mb:单个任务的对象总大小上限,比如最大大小限制在100MB,那么单个任务最多有100MB的对象列表,或者该任务就一个对象,该对象本身大小就超过了100MB
  • max_task_objects:单个任务的对象数量上限,比如数量上限为50,那么单个任务中最多有50个对象需要传输
  • multipart_threshold及multipart_chunksize:对象太大时,需要分割成多个小对象传输任务,那么多大的对象需要进行分解?分段的单位大小是多少?比如阈值是10MB,单位大小是2MB,那么大于10MB的对象都需要再分解成2MB的多个子对象并发续传

Amazon SQS任务队列设计与实现

传输任务在设计时分成两大类,一种是本身对象就是小文件,我们按照max_task_size_mb 和 max_task_objects 进行分组,即每个任务总数据量大小不会超过max_task_size_mb,而且对象数量也不超过 max_task_objects ;这些任务我们会发送到自动创建的S3Task_NormalQueue开头的SQS队列中,每个队列的消息数量上限本文设为80000条;另外一类是,对象大小超过multipart_threshold 限制的,我们会进一步把该对象分解成 multipart_chunksize大小的独立对象,同样按照 max_task_size_mb 和 max_task_objects 的算法进行分组,但这些任务会保存到自动创建的以S3Task_BigSizeQueue开头的队列中。

另外遵循Amazon SQS操作的最佳实践,我们分别为这两类任务队列设定了同样的死信队列,当消息被读取10次而没被处理成功的会自动转移到S3Task_DeadQueue进行存储和后续处理。

执行数据传输任务

当任务队列产生之后,接下来,就到了如何高效执行如何多的传输任务的阶段,很多网络和客观条件的限制,我们都放到了如何分解传输任务的算法里面进行了实现,在执行数据传输任务环节,逻辑非常简单:

  • 读取一条SQS任务
  • 根据任务中的具体对象,每个对象利用独立线程进行复制或者下载再上传
  • 只有该任务中所有的对象都传输成功,才把该任务消息从SQS队列中删除

同区域S3数据复制

同区域不同S3存储桶之间数据复制,由于网络条件较好,IAM权限简单,可以尽量利用boto3的copy-object方法直接利用S3服务本身能力,进行快速数据复制,该方法数据无需经过命令执行的机器中转。因此在任务分解环节,multipart_threshold 的值需要设置一个比较大而且合理的值,避免大文件被分片之后,需要先下载后上传,这样会消耗更多的流量。

AWS海外不同区域S3数据复制

海外不同区域的S3存储桶之间复制,和同区域的不同存储桶复制场景类似,但由于跨区域传输,网络状况取决于两个区域的位置及它们之间的互联网状况。

AWS海外区域和BJS区域S3数据复制

该情况最复杂,AWS海外和国内是独立的区域,需要不同的账号权限体系,因此,对象需要先进行下载再上传,这样就需要占用执行命令的机器的内存和网络带宽;

  • 在任务分解时,需要尽量把大对象分解成小的片段比如2MB或者1MB的大小以提高单次数据传输的成功率。
  • 在任务执行时,需要尽量并发,以单任务小带宽累积成可以接受的总体平均传输速度,并充分AWS出口带宽的优势

数据跨区域迁移实践

基于我们之前的架构设计,那我们分阶段来具体动手实践一个具体场景, Amazon官网有很多公开的数据集,我们选定Next Generation Weather Radar (NEXRAD) 作为数据源,该数据源在美东(us-east-1)区域;目标存储桶我们选择在BJS区域。该实验仅仅为了验证技术可行性,完整的参考代码见s3deepdive github;代码不作为生产用途仅仅用来学习用途。

准备环境

为了简单地完成技术验证,我们所有的测试环境基于一台r4.2xlarge的Amazon Linux机型展开,系统需要准备好:

  • 在AWS Global 美东区域创建一台EC2实例
  • 关联一个IAM Role,需要有访问S3及SQS相关的管理权限
  • Python2.7.x
  • Boto3
  • 300GB gp2 EBS 磁盘

配置好目标存储桶的IAM Profile及修改默认获取IAM Role的临时Token的默认超时时间和重试次数:

[ec2-user@youserver]$ aws configure --profile bjs
AWS Access Key ID [None]: AKI***************A
AWS Secret Access Key [None]: 7j+R6*****************oDrqU
Default region name [None]: cn-north-1
Default output format [None]:
[ec2-user@youserver]$ vi ~/.aws/configure
[default]
region = us-east-1
metadata_service_timeout = 5
metadata_service_num_attempts = 5
[profile bjs]
region = cn-north-1
metadata_service_timeout = 5
metadata_service_num_attempts = 5

生成对象清单

Amazon公共数据集没有提供清单列表,因此,我们利用前文的逻辑,并尝试利用AWS S3 CLI命令生成该存储桶的对象清单。该数据集按照年月进行数据分区,我们设定对象的Prefix的迭代深度为3,后台执行以下命令,并观察执行日志:

[ec2-user@youserver]$ cd NEXRAD_Demo/inventory
[ec2-user@youserver]$ nohup python ../../s3deepdive/s3_inventory.py -b noaa-nexrad-level2 -r us-east-1 -d 3 > noaa-nexrad-level2.log 2>&1 & 

由于数据集非常大,该命令执行需要点时间,最终,3层的扫描帮助我们并发生成了2751个对象清单文件,总大小4.5GB:

[ec2-user@youserver]$ cd NEXRAD_Demo/inventory
[ec2-user@youserver]$ ls noaa-nexrad-level2.*obj* | wc –l
2751

设计并提交传输任务

由于该场景下,源存储桶和目标存储桶之间的单次传输的速度非常有限,实测该场景下大概在9KB/s左右,而且网络抖动比较厉害,因此,我们尽量缩小单个任务的总数据量大小,并设定大对象的大小阈值设置为2MB;具体参数需要在Python常量参数中修改:

由于清单文件太多,总数据量太大,因此,我们可以数据清单分成多个目录,分别进行计算,比如如下命令:

  • 我们把大小小于800000 bytes的文件放到目录./1/里面
  • 把大小小于2MB的文件放到./2/里面
  • 把大小小于6MB的文件放到./3/里面

大家可以根据自己的需要,分成不同的对象清单文件夹

[ec2-user@youserver]$ cd NEXRAD_Demo/inventory
[ec2-user@youserver]$ mkdir 1 2
[ec2-user@youserver]$ find ./ -size -800000c -print0 | xargs -0 -I {} mv {} ../1/
[ec2-user@youserver]$ find ./ -size -2M -print0 | xargs -0 -I {} mv {} ../2/
[ec2-user@youserver]$ find ./ -size -6M -print0 | xargs -0 -I {} mv {} ../3/
[ec2-user@youserver]$ cd NEXRAD_Demo/tasksubmit
[ec2-user@youserver]$ nohup python ../../s3deepdive/s3_task_submit.py -d ../inventory/1/ -r us-east-1 > noaa-nexrad-level2.task1.log 2>&1 &
[ec2-user@youserver]$ nohup python ../../s3deepdive/s3_task_submit.py -d ../inventory/2/ -r us-east-1 > noaa-nexrad-level2.task2.log 2>&1 &
[ec2-user@youserver]$ nohup python ../../s3deepdive/s3_task_submit.py -d ../inventory/3/ -r us-east-1 > noaa-nexrad-level2.task3.log 2>&1 &

为了演示,我们没有生成所有对象清单的传输任务,仅仅选取了其中某连个文件夹,生成的传输任务如下图所示,有些队列的消息数为0,表示我们后台还有传输任务消息没有发送到队列中:

我们来看看队列里面的一个任务的结构组成,S3Task_Bigsize*队列中的任务相比于普通队列中的任务多了一组分片的Range范围:

设计并执行传输任务

在并发执行数据传输任务之前,我们先看看单个任务执行情况,任务执行需要指明任务队列,源和目的存储桶以及访问目标存储桶的IAM Profile名:

[ec2-user@youserver]$ cd NEXRAD_Demo/taskexec
[ec2-user@youserver]$ nohup python ../../s3deepdive/s3_task_exec.py -q S3Task_NormalQueue15098144850121 -source_bucket noaa-nexrad-level2 -dest_bucket bjsdest -dest_profile bjs > S3Task_NormalQueue15098144850121.exec1.log 2>&1 &
[ec2-user@youserver]$ nohup python ../../s3deepdive/s3_task_exec.py -q S3Task_BigSizeQueue1 -source_bucket noaa-nexrad-level2 -dest_bucket bjsdest -dest_profile bjs > S3Task_BigSizeQueue1.exec1.log 2>&1 & 

从执行日志可以分析出,对于NormalQueue中的单个任务,由于是小对象,而且数量是10,因此我们的执行代码可以并发执行,总体执行时间是26秒;对比BigsizeQueue中的任务,虽然总体数据大小和NormalQueue差不多,但由于只有2个对象并发复制,该任务的总体执行时间是363秒。

关于并发任务执行,本质上是一个批处理的业务逻辑,假定有1000个任务列表,

  • 每个任务数据量上限20MB,如果传输速度在10KB/s那么一个任务需要大概需要2048秒即34分钟,但我们的的任务执行是多线程并发操作,按每个任务最多10个对象算,在10KB/s的速度下,一个任务最快需要执行3.4分钟左右(10个对象并发上传),最慢34分钟(一个对象的情况下)
  • 如果同时100个并发执行,完成所有任务,需要至少执行10次,总时长在34分钟到340分钟之间
  • 如果并发1000个,完成所有任务需要至少执行1次;总时长3.4分钟到34分钟之间

本实验为了学习的目的,我们在测试机r4.2xlarge的机器上,后台并发执行100个任务,并观察数据传输的实际状况,

[ec2-user@youserver]$ cd NEXRAD_Demo/taskexec
[ec2-user@youserver]$ vi parallel_run.sh
#!/bin/bash

for((i=2; i<52;i++))

do

  nohup python ../../s3deepdive/s3_task_exec.py -q S3Task_BigSizeQueue1 -source_bucket noaa-nexrad-level2 -dest_bucket bjsdest -dest_profile bjs > S3Task_BigSizeQueue1.exec_$i.log 2>&1 &

done

for((i=2; i<52;i++))

do

  nohup python ../../s3deepdive/s3_task_exec.py -q S3Task_NormalQueue15098144850121 -source_bucket noaa-nexrad-level2 -dest_bucket bjsdest -dest_profile bjs > S3Task_NormalQueue15098144850121.exec_$i.log 2>&1 &

done
[ec2-user@youserver]$ chmod +x parallel_run.sh
[ec2-user@youserver]$ ./parallel_run.sh

针对下面这两个队列,每个运行了50个并发任务,因此在SQS界面上,可以看到传输中的消息是50,也就是同时有50个消息任务正在被处理:

可以看到BigsizeQueue队列一次就成功完成的数据传输任务总数为 79949+50-79971=28;NormalQueue队列一次就成功完成的数据传输任务总数为79950+50-79958=42;我们定义任务的成功与否,为该任务中所有的对象都成功传输完成;该实验我们对于分段采取的大小是2MB,在9KB/s左右的互联网传输速度下,还是有点大,容易失败;普通队列上中的任务,对象大小都在几百KB左右,一次传输成功的概率大很多。

数据完整性检查

本文不对单个对象的完整性问题展开探讨,对于用户首先最关心的问题是,源存储桶的对象有没有完全迁移到目前存储桶中;因此,可以定期生成目标存储桶的对象清单,并比对源存储桶的对象清单,在自定义的清单程序中,我们是逐级生产对象清单文件,有一定的规律,如果两个存储桶使用同样的depth参数生成,生成的对象清单文件个数首先一致的;具体到识别出有没有遗漏的迁移对象,可以进一步对比清单中的对象列表。

总结

本文就跨区域S3数据迁移整体架构作了基本探讨,并在架构的基础上,学习和实践了利用AWS S3 CLI以及boto3库如何实现自定义的对象清单,传输任务分解及执行逻辑。现实的生产场景下,还需要更多细节的思考和实践,接下来,我们会继续在大规模批处理,大规模对象集的完整性校验方面和大家继续探讨。

 

作者介绍:

薛军

AWS 解决方案架构师,获得AWS解决方案架构师专业级认证和DevOps工程师专业级认证。负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内的应用和推广,在互联网金融、保险、企业混合IT、微服务等方面有着丰富的实践经验。在加入AWS之前已有接近10年的软件开发管理、企业IT咨询和实施工作经验。