Category: 存储


Amazon S3 深度实践系列之一:S3 CLI深度解析及性能测试

背景

作者在实际的工作当中遇到越来越多关于S3的实践问题,其中被问的最多的也是使用最广泛的工具就是AWS S3 CLI命令行;AWS S3 CLI命令行工具对大文件提供了默认的分段上传下载的能力,同时支持并发上传下载多个文件;AWS S3 CLI 命令行不仅仅提供了高级抽象的cp、sync等操作同时还提供了相对底层的s3api相关的操作以帮助客户应对各种高度定制化的应用场景。

本文通过实验帮助大家更好地理解AWS S3 CLI常用命令的底层原理及在AWS EC2上使用该命令行工具与AMAZON S3交互场景下,影响性能的几个关键要素及几个常见EC2实例类型上的上传下载测试性能情况。

本文是AMAZON S3深度实践系列之一,接着作者会带着大家从AWS CLI探索到Python boto3 S3多线程应用开发实践,再到如何利用前面学到的知识,基于AWS平台利用托管服务构建一个实用的跨区域迁移S3数据的解决方案架构探讨及实践。

基本概念

并发上传vs 分段上传

刚刚使用AWS S3命令行工具的时候,总是混淆分段上传和并发上传的含义;分段上传是指将单个大文件切分成多个小数据块进行上传,而并发上传特指有多个待上传文件或小数据块的情况下,利用多线程同时并发上传多个文件或小数据块。

如下图所示,分段上传首先将文件切分成固定数量的小数据块,再利用多线程并发上传这些小数据块,等 S3收到该文件所有的数据块之后再将它们合并成原始的文件存放在存储桶里。分段上传功能默认会帮你实现并发上传;这样做的好处,显而易见,既可以充分利用网络带宽进行文件处理,同时还可以在网络带宽有限的情况下,减小因网络抖动导致的整个大文件需要重传的问题,即当分段上传中的某个数据块因各种异常没能上传成功时,只需要重新尝试上传该数据块即可。

分段上传vs 断点续传

AWS CLI S3命令行工具默认并没有帮大家实现断点续传的功能,也就是说哪怕我们用cp或sync命令上传一个文件的时候,默认后台会做文件分片进行分段并发上传,但如果由于网络抖动导致其中某些数据块传输失败,那么整个文件又得需要重头开始上传。

但同时我们可以利用 AWS CLI s3api底层接口非常容易地实现断点续传,后面章节我们再展开探讨。

AWS CLI S3 cp命令是如何工作的?

AWS S3 cp 命令是最常用的单文件和多文件复制方法,很多人使用过该命令,但大家知道该命令是如何帮我们执行文件复制的吗?

  • 该命令有帮我们自动做分段上传和下载吗?
  • 分段上传切分文件的依据是什么?每个数据块大小是多大?
  • 这么多数据块,有多线程并发上传吗?我们可以指定线程数量吗?
  • 多个文件的上传下载是如何工作的?

下面我们通过实验来观察和研究下这些问题,整个测试环境基于如下Amazon Linux上如下版本的AWS CLI命令行:

aws-cli/1.11.132 Python/2.7.12 Linux/4.9.51-10.52.amzn1.x86_64 botocore/1.5.95

AWS EC2机型是R4.2xlarge,挂载了一个500GB的gp2测试盘

本地单文件上传场景

第一步,我们首先生成一个48MB的本地测试文件,并通过cp命令上传到S3存储桶,并通过debug开关把详细的日志记录到本地的upload.log文件中,详细命令如下:

$ dd if=/dev/zero of=48Mfile bs=1M count=48
$ aws --debug s3 cp 48Mfile s3://bjslabs/s3/ > upload.log 2>&1
$ ls -lh
总用量 49M
-rw-rw-r-- 1 ec2-user ec2-user 48M 10月 18 00:26 48Mfile
-rw-rw-r-- 1 ec2-user ec2-user 13K 10月 18 00:31 upload.log

第二步,我们通过底层的s3api命令来了解存储到S3上的对象的基本情况,如下所示,通过head-object命令我们可以了解该文件的最后修改时间,对象大小以及一个用于完整性校验的ETag值,那我们如何知道该文件是否是分段上传的呢?

$ aws s3api head-object --bucket bjslabs --key s3/48Mfile
{
    "AcceptRanges": "bytes",
    "ContentType": "binary/octet-stream",
    "LastModified": "Wed, 18 Oct 2017 00:32:56 GMT",
    "ContentLength": 50331648,
    "ETag": "\"64db0c827ecffa128fa9440d3b04ff18-6\"",
    "Metadata": {}
}

要知道该文件是否是利用了分段上传,我们只需要在以上命令中加一个参数就可以判断,如下所示,如果该文件是利用分段上传的功能,通过head-object查询第一个数据块的基本信息就可以得到该文件一共包含多少个数据块,测试文件48Mfile一共包含6个数据块(PartsCount)。

$ aws s3api head-object --part-number 1 --bucket bjslabs --key s3/48Mfile
{
    "AcceptRanges": "bytes",
    "ContentType": "binary/octet-stream",
    "LastModified": "Wed, 18 Oct 2017 00:32:56 GMT",
    "ContentLength": 8388608,
    "ETag": "\"64db0c827ecffa128fa9440d3b04ff18-6\"",
    "PartsCount": 6,
    "Metadata": {}
}

这里我们可以得知,默认情况下cp命令就会采用分段上传功能。而且从以上命令返回信息我们可以看出来,该文件第一个数据块分片大小是8388608 bytes(ContentLength)即8MB,48MB大小的文件一共被分了6个数据块,所以,可以大胆猜测默认的AWS CLI S3命令行工具默认的文件分片大小就是8MB。

第三步,我们已经判断出cp命令的默认是分段上传,接下来我们通过第一步保存的详细日志(该日志文件比较大,可以点击下载)来分析下,cp命令基本的工作流及它采用的多线程并发上传的具体情况:

通过该实验的日志,我们基本了解了cp命令的基本内部流程,因此,这里面有些参数肯定是可以通过配置来进行修改的,接下来我们来根据官方文档:http://docs.aws.amazon.com/cli/latest/topic/s3-config.html 的说明来试验下,修改相应配置,是否如我们所理解的那样运行,这几个参数是:

接下来我们修改参数并对比下,实验内容为同样大小的本地文件在不同参数条件下,通过cp上传到s3,两次运行的结果对比:

在AWS Configure配置文件中,指定S3的配置参数:

$ cat ~/.aws/config
[default]
region = cn-north-1
[profile dev]
region = cn-north-1
s3 =
  max_concurrent_requests = 5
  multipart_threshold = 10MB
  multipart_chunksize = 6MB

执行profile 为dev的上传测试命令:

$ aws --debug s3 cp 48Mfile s3://bjslabs/s3/ --profile dev > 2>&1

对比upload.log和upload2.log,我们可以看出,multipart_threshold和multipart_chunksize参数是对分段上传的影响是很好理解的,但 max_concurrent_requests参数与单个文件的分段上传的并发线程总数的关系,从日志中只能看出单文件的分段上传的并发线程总数受max_concurrent_requests参数影响,但并发线程的总数上限值还取决于文件分片后进入队列被消费者线程消耗的速度。

感兴趣的读者可以在以上实验的基础上,保持其他参数不变,只修改max_concurrent_requests参数,观察并发线程数的情况,作者在max_concurrent_requests参数值分别为8、15、20、30的情况下观察cp同样的文件的线程数情况如下:

$ aws --debug s3 cp 48Mfile s3://bjslabs/s3/ --profile dev > upload2.log 2>&1

对于单文件上传,我们经过前面的实验有了基本的认识,那我们接下来再看看cp命令在分段上传中途发生网络故障,能否实现类似断点续传的功能效果呢?

整个实验思路如下:

  •  利用dd命令产生一个26GB大小的文件
  • 在cp传送中途强行断开
  • 检查此时在S3桶里面的分片情况
  • 尝试再次上传并观察结果
$ dd if=/dev/zero of=26Gfile bs=1G count=26
$ aws --debug s3 cp 26Gfile s3://bjslabs/s3/ > upload.log 2>&1
$ Ctrl-Z(强行中止)

AWS CLI s3api提供了list-parts和list-multipart-uploads两个命令分别可以查看已经完成的分片上传及正在进行的分片上传:

$ aws s3api list-multipart-uploads --bucket bjslabs

list-multipart-uploads 命令会列出指定的bucket桶里面所有的正在进行上的分片信息,如上所示,对我们有帮助的是其中的UploadId的值,在执行list-parts命令时需要传入:

$ aws s3api list-parts --bucket bjslabs --key s3/26Gfile --upload-id OwKKv3NOfXiOq7WwdBt0vYpKGVIXxzrGkxnSwSFGv8Lpwa94xzwj4IDgPvpw9Bp1FBjqUeRf2tEtL.SMCgLPhp23nw4Ilagv7UJDhPWQ0AalwwAC0ar4jBzfJ08ee4DKLd8LroSm0R7U_6Lc8y3HgA-- > parts.info 2>&1

打开parts.info文件可以看到所有的已经上传好的分片信息,包含每个分片的最后修改时间,大小,ETag以及PartNumber:

接下来,我们看看如果再次运行同样的cp命令,会帮我们进行断点续传吗?判断逻辑有两点(1)两次的UploadId是否一致(2)同一个PartNumber的数据块的最后修改时间是否一致。先记录好目前的这两个值:

UploadId:

OwKKv3NOfXiOq7WwdBt0vYpKGVIXxzrGkxnSwSFGv8Lpwa94xzwj4IDgPvpw9Bp1FBjqUeRf2tEtL.SMCgLPhp23nw4Ilagv7UJDhPWQ0AalwwAC0ar4jBzfJ08ee4DKLd8LroSm0R7U_6Lc8y3HgA—

选取PartNumber=1的数据块,该数据块最后修改时间是:

"2017-10-18T14:43:54.000Z"

重新执行一边cp命令并记录结果:

$ aws --debug s3 cp 26Gfile s3://bjslabs/s3/ > upload2.log 2>&1
$ Ctrl-Z(强行中止)
$ aws s3api list-multipart-uploads --bucket bjslabs > processing.info 2>&1

从结果我们发现,有两个正在上传的数据分片,一个是我们前一次命令产生的,一个是最近一次cp命令被中断产生的。

$ aws s3api list-parts --bucket bjslabs --key s3/26Gfile --upload-id OwKKv3NOfXiOq7WwdBt0vYpKGVIXxzrGkxnSwSFGv8Lpwa94xzwj4IDgPvpw9Bp1FBjqUeRf2tEtL.SMCgLPhp23nw4Ilagv7UJDhPWQ0AalwwAC0ar4jBzfJ08ee4DKLd8LroSm0R7U_6Lc8y3HgA-- > parts2.info 2>&1
$ aws s3api list-parts --bucket bjslabs --key s3/26Gfile --upload-id 7P10pMiJ.Tj.xsogV7JeG99G4Ev6kV_5SqsdcEBKXzVi9Kg1SgvcWkTmay0wpB2WYsdnXtsFyofRIjOMfu9hZnh6DXmggVzSpyiKbAgw0qSyZDHVt5OdkcqpfX52uHpM5tc9BQUkIVD3dWu29xUeyg-- > parts3.info 2>&1

我们会发现执行两次cp命令对同一个文件,会帮我们保留两个UploadId及其对应的已经上传的分段数据,根据complete-multipart-upload的文档说明,我们知道,分段上传在合并分段数据的时候,是根据UploadId进行合并的,两个不同的UploadId说明AWS CLI cp命令不会智能帮我们判断已经上传的分段之后开始续传我们的文件分片即没有直接支持断点续传。

一个文件如果经过分段上传了一部分数据但没有传完的情况下,已经传完的数据块和正在进行上传的数据块占用的存储是需要收费的,因此,我们需要清除掉这些无用的数据块,一种办法是通过命令,另外一种方式可以利用AMAZON S3的生命周期管理定期自动删除掉这样的数据块。

$ aws s3api abort-multipart-upload --bucket bjslabs --key s3/26Gfile --upload-id OwKKv3NOfXiOq7WwdBt0vYpKGVIXxzrGkxnSwSFGv8Lpwa94xzwj4IDgPvpw9Bp1FBjqUeRf2tEtL.SMCgLPhp23nw4Ilagv7UJDhPWQ0AalwwAC0ar4jBzfJ08ee4DKLd8LroSm0R7U_6Lc8y3HgA--
$ aws s3api abort-multipart-upload --bucket bjslabs --key s3/26Gfile --upload-id 7P10pMiJ.Tj.xsogV7JeG99G4Ev6kV_5SqsdcEBKXzVi9Kg1SgvcWkTmay0wpB2WYsdnXtsFyofRIjOMfu9hZnh6DXmggVzSpyiKbAgw0qSyZDHVt5OdkcqpfX52uHpM5tc9BQUkIVD3dWu29xUeyg--

S3下载到本地单文件场景

该场景下,我们关注的点主要是,对于在S3桶里面的对象,cp命令都会自动帮我分段分片下载吗?

首先尝试通cp直接下载上一个章节通过cp命令上传到S3桶里面的对象:

$ aws --debug s3 cp s3://bjslabs/s3/ . > download.log 2>&1

从日志文件里面可以看出,cp命令确实是默认采用了分段下载,调用GetObject接口,在Header里面设置range值并通过多线程并发下载;似乎非常完美,但等等,我们还忘了一个场景,假如文件上传到S3桶的时候没有使用分段上传呢?我们试验一下:

  • 还是利用本地dd出来的48Mfile的文件
  • 修改AWS CLI S3的参数,将multipart_threshold改到50MB,这样对于小于50MB的文件上传就不会采用分段上传
  • cp上传该文件并确认该文件没有被分段上传
  • cp 下载,看看是否是分段下载

第一步,修改aws configure配置文件:

第二步,通过cp上传该文件,并通过head-object命令发现该文件没PartsCount 信息即没有被分片分段上传(因为前面我们设置了自动分片的最小文件大小是50MB,该文件48MB小于50MB)

$ aws s3 cp ./48Mfile s3://bjslabs/s3/48Mfile_nonparts --profile dev
upload: ./48Mfile to s3://bjslabs/s3/48Mfile_nonparts
$ aws s3api head-object --part-number 1 --bucket bjslabs --key s3/48Mfile_nonparts
{
"AcceptRanges": "bytes",
"ContentType": "binary/octet-stream",
"LastModified": "Wed, 18 Oct 2017 15:52:34 GMT",
"ContentLength": 50331648,
"ETag": "\"f6a7b2f72130b8e4033094cb3b4ab80c\"",
"Metadata": {}
}

第三步,通过cp下载该文件,并分析日志文件

$ aws --debug s3 cp s3://bjslabs/s3/48Mfile_nonparts . > download2.log 2&>1

$ aws s3api head-object --part-number 1 --bucket bjslabs --key s3/48Mfile_nonparts
{
"AcceptRanges": "bytes",
"ContentType": "binary/octet-stream",
"LastModified": "Wed, 18 Oct 2017 15:52:34 GMT",
"ContentLength": 50331648,
"ETag": "\"f6a7b2f72130b8e4033094cb3b4ab80c\"",
"Metadata": {}
}

透过日志,我们可以看到,虽然我们上传该文件是没有使用多文件上传,但利用cp命令在默认的S3参数的情况下也会自动分片分段下载我们的对象。

本地目录与S3批量上传下载场景

前面两个小节,我们通过实验深度探索了,单文件通cp操作的一些细节;本小节我们一起来看看,在本地批量上传文件到S3及从S3批量下载文件的场景。对于性能这块我们放到后面章节,本小节主要探讨:

1.    max_concurrent_requests参数对于文件并发上传下载的影响

2.    cp命令中的一些高级特性

第一步,随机生成20个100MB的测试数据文件,并准备aws configure 配置文件,修改最大并发数的参数值,保持其它参数默认,并通过不同的profile指定不同的max_concurrent_requests的参数值:

$ seq 20 | xargs -i dd if=/dev/zero of={}.data bs=1M count=100
$ vi ~/.aws/config

第二步,跑测试命令,记录详细日志:

顺序分析dev1.log到dev30.log日志文件,可以观察到Thread数量变化,最大编号分别为Thread-7,Thread-9,Thread-14,Thread-18,Thread-26,Thread-36; 为了观察最大的线程数量,作者增加测试了max_concurrent_requests分别为100,1000的结果:

由上表可见,当我们逐渐增大max_concurrent_requests参数值的时候,实际的并发线程数是随着线性增长的,直到一个合理的线程数量,此案例里面256个8MB的数据分片,AWS CLI cp命令使用到309个线程就足够速度消费添加到队列里面的上传任务。

同理,我们从S3批量下载的情况,执行如下命令:

$ aws --debug s3 cp s3://bjslabs/s3/data1000/ ./data1000 --recursive --profile dev1000 > dev1000.log 2>&1
$ aws --debug s3 cp s3://bjslabs/s3/data100/ ./data100 --recursive --profile dev100 > dev100.log 2>&1

从日志文件中分析出,max_concurrent_requests为100或1000时,cp命令并发下载的线程数最大编号为107和275。


对于批量操作,不可避免有时会有选择的上传和下载某些特征的文件,cp 命令可以通过include和exclude参数进行文件模式匹配,看以下几个例子:

通过以下命令仅仅下载所有 ”.data” 结尾的文件:

$ aws s3 cp s3://bjslabs/s3/data1000/ ./data1000 --recursive --profile dev1000 --exclude “*” --include “*.data”

通过以下命令上传当前目录中,除子目录 “data100” 之外的所有文件到存储桶:

$ aws s3 cp ./ s3://bjslabs/s3/data1000/ --recursive --profile dev1000 --exclude “data100/*”

S3到S3的复制场景

首先,我们先来看一个同区域的文件复制案例,执行如下命令并记录详细日志:

$ aws --debug s3 cp --source-region cn-north-1 s3://bjslabs/s3/data100/1.data s3://bjslabs/s3_2/ --profile dev100 > sameregion100.log 2>&1

查看日志文件,可以了解两点(1)默认也是支持分段并发的(2)每个分段是调用的upload-part-copy 接口执行复制操作的:

而如果不是S3到S3的复制的话,比如前面两个场景,源是本地目标地址是S3的话则cp命令最终会调用upload-part 方法进行上传,这两个命令有什么区别吗?

参见upload-part-copyupload-part在线文档,仔细对比如下两个命令最终的REST请求,可以看到,UploadPartCopy请求只需要将源数据指向源的对象(x-amz-copy-source)以及相应的数据范围(x-amz-copy-source-range);但UploadPart请求中必须要讲该分段的数据包含进去;也就是可以推断,S3到S3的复制不需要经过我们执行该命令的机器进行数据中转;

样例请求(UploadPartCopy):

样例请求(UploadPart):

本章小结

本章节,我们深度解析了cp命令在不同场景下的数据传输行为,基本的一些结论见下表;其中,S3到S3的复制,从底层API可以分析出不需要经过运行命令的机器进行中转,这样节约进出执行cp命令的机器流量;同时我们s3api提供了很多底层S3底层接口,基于这些接口,可以方便地在分段上传的基础上实现断点续传。

AWS S3 CLI上传下载性能测试

本章继续和大家一起来探讨下影响AWS S3 CLI进行数据传输的性能的基本因素以及实际场景下基于AWS EC2的一些数据传输性能测试情况。

同区域不同S3桶数据的复制性能测试

测试环境:

  • BJS区域
  • R4.2xlarge 跑cp命令
  • AWS CLI S3参数max_concurrent_requests为1000
  • 测试方法,脚本跑10次取平均时间

测试结果如下,时间单位是秒:

总体平均时间:(29+29+28+6+29+5+6+6+6+29)/10=17.3秒,root.img的大小为8.0GB,AWS北京区域不同桶之间的数据平均传输速度为473.52MB/s,最高速度可以达到1.6GB/s,最低282.48MB/s。

为了验证该场景下对网络的影响,我们截取了这阶段的网络方面的监控,我们观察到这段时间,该测试机的网络输出和网络输入有几个波峰,但峰值最高没超过12MB,从侧面验证了我们的前面的判断,即cp在S3到S3复制的场景下,数据不会经过命令行运行的机器转发,而是直接由S3服务直接完成:

S3桶数据到AWS EC2下载性能测试

测试环境(针对下面表格的场景一):

  • BJS区域
  • R4.2xlarge 跑cp命令,
  • EC2挂500GB的gp2 ssd磁盘
  • AWS CLI S3参数max_concurrent_requests为1000
  • 测试方法,脚本跑10次取平均时间

测试结果如下,时间单位是秒:

总体平均时间:(67+64+66+65+65+65+66+65+64+65)/10=65.2秒,root.img的大小为8.0GB,该测试场景的数据平均传输速度为125.64MB/s,下载速率比较平稳。

在继续试验之前,我们总结下,影响EC2虚机下载S3数据的速度的几个因素:

  • 磁盘的吞吐率(SSD还是实例存储还是HDD)
  • EBS带宽,是否EBS优化(EBS本身也是通过网络访问,是否有EBS优化为EBS I/O提供额外的专用吞吐带宽,否则和EC2网络共享带宽性能)
  • S3服务的带宽(通常我们认为S3服务不是性能瓶颈)

我们已经测试了R4.2xlarge的下载性能,接下来我们选择几个典型的虚机类型分别进行测试,由于测试时间跨度比较大,测试场景中的EC2操作系统层没有任何调优,测试结果仅供参考。所有场景测试都针对一块盘,进行同一个8GB的文件下载,下载10次,根据时间算平均下载速率。

通过简单的测试我们发现,

1.    虽然随着机型增大比如从R4.xlarge 到R4.4xlarge,同样是单块SSD磁盘的情况,磁盘就成为整个下载速度的瓶颈,因为R4.4xlarge EBS优化的专用吞吐量理论值可以达到437MB/s,而简单测试下来的下载速度最高到130MB/s左右;

2.    SSD磁盘在整个测试场景中,是最优的选择,而且SSD盘的大小无需到3TB就可以有很好的性能表现

3.    实例存储在没有预热(dd整个盘)的情况下表现很一般

4.    st1盘6TB左右的测试盘,下载测试性能不如500GB的SSD盘

5.    3334GB的SSD盘的表现跟比预期要差很多

6.    测试场景中EC2下载S3的平均速度没有超过150MB/s

以上表格中的虽然我们测试了不同系列的不同规格的机型,但是我们可以通过修改实例类型非常方便地切换,因此监控上我们可以看出测试时间跨度中,我们的机器资源使用情况。

整个测试过程中R4系列机器的CPU的利用率总体还算正常,在15%到60%之间浮动:

整个测试过程中500GB的gp2磁盘的写入带宽变化如下图所示:

整个测试过程中3334GB的gp2磁盘的写入带宽变化如下图所示:

整个测试过程中6134GB的st1磁盘的写入带宽变化如下图所示:

AWS S3 CLI的一些限制

S3 CLI提供的分段上传算法有些限制在我们实际使用的时候,特别要关注比如分段总大小不能超过10000,每个分段的数据块最小为5MB,分段上传最大的对象为5TB等等。详细情况请参考AWS官方文档

下一篇将要探讨和解决的问题

在了解AWS S3 CLI命令底层原理和影响基本性能的基本因素之后,我们接下来会继续来探讨,如何利用S3的底层API实现S3中的数据的跨区域可靠、低成本、高效传输。

总结

本文和大家一起深度研究了AWS S3 cp命令在各种场景中的底层实现原理,同时利用实验,总结了关于AWS EC2下载S3数据的基本性能测试结果,期待更多读者可以实践出更多的性能优化方法。随着大数据分析的蓬勃发展,存放在S3上的数据越来越多,本系列主要会和大家一起深度探讨S3数据复制迁移的最佳实践。

作者介绍:

薛军

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

新功能 – EC2 实例和 EBS 卷的每秒计费功能

在过去,如果您需要使用计算能力,则需要购买或租用服务器。当我们在 2006 年推出 EC2 时,使用一个实例一个小时只需支付一小时的费用是头条新闻。即付即用模式激励我们的客户思考开发、测试和运行所有类型的应用程序的新方法。

如今,AWS Lambda 等服务证明我们可以在短时间内完成大量有用的工作。我们的许多客户都在设计适用于 EC2 的应用程序,以便能够在更短的时间内 (有时仅为几分钟) 充分利用大量实例。

EC2 和 EBS 的每秒计费
于 10 月 2 日开始生效,以按需、预留和竞价形式发布的 Linux 实例的使用将按 1 秒的增量计费。同样,EBS 卷的预置存储也将按 1 秒的增量计费。

每秒计费功能也适用于 Amazon EMRAWS Batch

Amazon EMR – 我们的客户增加了其 EMR 群集的容量以更快地获得结果。借助适用于群集中的 EC2 实例的每秒计费功能,添加节点要比以往任何时候都更经济高效。

AWS Batch – 我们的客户运行的许多批处理作业在 1 小时内即可完成。AWS Batch 已启动和终止竞价型实例;利用每秒计费功能,批处理将变得更划算。

Elastic GPUsElastic GPUs 的使用按秒计费,最少1分钟。

Provisioned IOPS – io1 EBS 卷的 Provisioned IOPS 按秒计费。

我们的一些更精明的客户已构建系统,通过在管理其游戏、广告技术或 3D 渲染队列时战略性地选择最有利的目标实例来从 EC2 中获得最大价值。每秒计费功能消除了这种额外的实例管理层的需要,并实现了所有客户和所有工作负载的成本节省。

虽然这将导致许多工作负载的价格降低(您知道我们喜欢降价),但我认为这并不是此改变的最重要方面。我相信,这种改变将激励您进行创新并以新的方式思考您的受计算限制的问题。您如何利用这一点来增强对持续集成的支持?这是否能改变您为开发和测试工作负载预置瞬态环境的方式?您的分析、批处理和 3D 渲染将会怎么样?

云计算的许多优势之一是,在您需要时预置或取消预置资源的弹性特性。通过对使用量每秒计费,我们使客户能够提高其弹性、节省资金,并且客户将被定位以利用计算中的持续改进。

需知信息
此更改在所有 AWS 区域中都是有效的,并且将于 10 月 2 日开始生效,适用于新发布的或已经运行的所有 Linux 实例。每秒计费功能目前不适用于运行 Microsoft Windows 或 Linux 发行版的实例,后者已按小时单独计费。每个实例均最少有 1 分钟计费。

列表价格和竞价市场价格仍按每小时列出,但计费单位下调至秒,预留实例使用量也按秒计算(您可以在 1 个小时内启动、使用和终止多个实例并获得所有实例的预留实例优势)。此外,账单将以十进制格式显示次数,如下所示:

AWS Marketplace 中的区域专用费、EBS 快照和产品仍按小时计费。

Jeff

如何使用Amazon Macie 进行安全数据自动分类和用户行为监控

概述

当我们在Amazon S3中存储大量内容时,识别和分类其中潜在敏感数据可能会有点像在一个非常大的干草堆中找绣花针针,整个的过程是非常低效。那么能否有一种工具可以在数据加入到S3后就自动的识别敏感信息并自动进行分类?

同时在我们日常的工作中,访问数据的时间间隔及物理位置相对的固定。如果发生异常的事件,例如原来某个用户一天访问一到两个文件,但如果突然在某天访问超过一百个文件,能否由系统发出告警事件提醒相关人员进行相关检查,确保安全?

本文从如下几部分介绍Amazon Macie服务及主要功能,同时还列出常见使用场景,以及如何配置的简要步骤。希望能给大家带来帮助。

什么是Macie

Amazon Macie 是一种支持人工智能技术的安全服务,可以帮助您通过自动发现、分类和保护存储在 AWS 中的敏感数据来防止数据丢失。Amazon Macie 使用机器学习来识别敏感数据 (例如,个人身份信息 [PII] 或知识产权),分配业务价值,提供此数据的存储位置信息及其在组织中的使用方式信息。

Amazon Macie 可持续监控数据访问活动异常,并在检测到未经授权的访问或意外数据泄漏风险时发出警报。

为什么要使用Macie

对现存的海量文件进行自动的分类并且根据不同的分类制定不同的监控策略,一旦发生异常的访问需要得到及时的告警,是每个组织面临的挑战。

Amazon Macie提供了简单高效并且安全的方案,Macie通过使用机器学习来了解存储的内容和用户行为,同时提供可视化界面,展示安全分类,从而使客户能够专注于保护敏感信息,而不是浪费时间手工的处理。

Amazon Macie内置检测个人身份信息(PII)或敏感个人信息(SP)的常见敏感信息的引擎,可以自动识别出S3存储文件是否包含例如个人身份信息(PII)或其他公司财报等敏感信息,在没有Macie之前,这样的工作都需要手工的处理或者使用第三方平台。而现在可使用Macie很容易解决上述问题。

Amazon Macie持续监控数据和账户凭证 。 在发现可疑行为或对实体或第三方应用程序进行未经授权的数据访问时撤销访问或触发密码重置策略,来防范安全威胁。当Amazon Macie发出警报时,您可以使用预先在Amazon CloudWatch设置的规则发送告警,以便迅速采取行动,保护数据。

Macie主要功能

Amazon Macie首先功能分为两部分,一方面是使用自然语言处理(NLP)来理解数据,Macie可以自动对您的S3桶中的数据进行分类。另外一个是使用机器学习理解用户访问数据的行为,同时利用动态分析数据访问模式的预测分析算法,并使用日常访问的用户行为数据不断的训练并优化模型。

Macie 主要功能

  • 自动化处理数据:分析,分类和自动处理数据,从现有的数据和访问日志分析出有规律的历史模式,用户认证数据,用户位置信息及时间信息。
  • 数据安全和监控: 主动监控 日志数据,检测到的异常情况,转发告警信息到CloudWatch 事件或和Lambda以进行后续处理,例如自动修复安全漏洞或者发送邮件通知。
  • 主动预防的数据的丢失,提供即时保护,无需手动干预。
  • 可视化分析:提供存储数据的可视化详细信息。
  • 数据研究与报告:允许用户管理配置报告。

Macie如何运作

在数据分类过程中,Amazon Macie 识别 S3 存储桶中的对象,并将对象内容流式传输到内存中进行分析。

当需要对复杂文件格式进行更深入的分析时,Amazon Macie 将下载对象的完整副本,并在短时间内保存,直到完成对象的全面分析。Amazon Macie 对数据分类的文件内容分析完毕后,它将立即删除存储内容,仅保留未来分析所需的元数据。

Amazon Macie持续监控分析当前的用户行为习惯并以基础形成基线,例如敏感数据在哪个IP地址以及何时以什么样的频率被进行访问。随后Macie持续监控CloudTrail日志并训练机器学习所使用的模型,,一旦发现可疑的访问活动,Macie可以及时发出告警。

示意图如下:

信息分类

Amazon Macie已经定义好信息分类标准:

  • 配置合规性 – 与合规性内容策略,配置设置,数据日志记录以及补丁级别相关​。
  • 数据合规性 – 与合规性或安全控制内容的发现相关,例如存在个人身份信息或访问密钥。
  • 文件托管 – 与恶意软件,不安全的软件或攻击者的命令和控制基础架构相关的托管主机或存储服务。
  • 服务中断 – 可能导致无法访问资源的配置更改。
  • 恶意软件或活动- 潜在的恶意软件或活动。
  • 可疑访问 – 从风险异常的IP地址,用户或系统访问您的资源 。
  • 身份枚举 – 一系列API调用或访问,枚举系统的访问级别,可能指示攻击的早期阶段或受到破坏的凭据。
  • 特权升级 – 成功或不成功的尝试,以获得对通常受应用程序或用户保护的资源的高级访问,或尝试长时间访问系统或网络。
  • 匿名访问 – 尝试从IP地址,用户或服务访问资源,以隐藏用户的真实身份。 例如包括使用代理服务器,虚拟专用网络和其他匿名服务,如Tor。
  • 开放许可 – 识别受潜在过度允许访问控制机制保护的敏感资源。
  • 位置异常 – 访问尝试敏感数据的异常和危险的位置。
  • 信息丢失 – 敏感数据的异常和冒险访问。
  • 凭证丢失 – 可能损害您的凭据。

告警严重级别

Macie 内置了5种告警信息级别

  • 严重(Critical) – 该级别可能导致信息机密性,完整性和可用性受到损害的安全问题。建议将此安全问题视为紧急情况,并实施立即的补救或加固措施。
  • 高 –该级别可能导致信息机密性,完整性和可用性受到损害的安全问题。建议将此安全问题视为紧急情况,并实施立即的补救或加固措施。
  • 中等(Medium) – 该级别可能导致信息机密性,完整性和可用性受到中等性损害。建议在下次更新服务期间修复此问题。
  • 低(Low) -该级别可能导致信息机密性,完整性和可用性受到低等性损害。建议您将此问题作为未来服务更新的一部分。
  • 信息(Informational) – 该级别警告只描述基础架构的特定安全配置详细信息。根据相关业务和组织目标,可以简单地记录这些信息或使用它来提高系统和资源的安全性。

注:严重(Critical) 和高(High)之间的主要区别:

产生严重(Critical)警报的事件可能导致大量资源或系统受到损害。

产生高(High)警报的事件可能导致一个或多个资源或系统受到损害。

开始使用Macie

需要配置的IAM 角色

创建身份访问管理(IAM)角色,为Macie提供对您的AWS帐户的访问权限。这些角色只需要创建一次,以便在所有地区使用。

我们以Oregon区域作为例子 ,可以通过启动下面列出的URL中找到的AWS CloudFormation堆栈模板来创建这些角色和所需的策略。

https://s3-us-west-2.amazonaws.com/us-west-2.macie-redirection/cfntemplates/MacieServiceRolesMaster.template

配置Cloud Trail服务

首先需要建立相应IAM Role, 确保Amazon Macie能够访问S3及 CloudTrail,另外是要启动CloudTrail服务以对相关的AWS API操作进行分析。

开始使用Macie服务

添加需要管理的S3 存储桶

需要在Macie中添加需要访问S3存储桶并对其中的文件进行统计分类。

步骤如下:

1.     进入Macie Console 页面,点击 Integrations 页面后,选择SERVIES 标签页面,点击 Select an account 下拉框

2.     选择 Amazon S3 Detail

3.     选择Selected S3 buckets and prefixes

4.     选择Macie分析的S3 bucket

文件分类

在Macie中添加需要分析的S3 存储桶后,Macie会自动开始分析其中的文件,稍等一段时间后,进入Macie的Dashboard 页面。

在Dashboard中共提供10种视图,为了演示本文章仅仅展示其中的两个。

S3文件分类统计结果

S3文件分类统计详细结果

用户行为分析

根据CloudTrail的日志,Macie自动分析所有IAM user的相关操作。根据Macie预先定义的规则,把IAM用户分为如下四类:

  • 白金:这类IAM用户或角色曾有管理员或root用户的高风险API调用的历史,例如创建用户,授权安全组入口或更新策略。 应对这类帐户进行重点监控。
  • 黄金:这类IAM用户或角色曾有创建与基础设施相关的API调用的历史,这些API调用标志其具有高级权限,例如创建实例或拥有向Amazon S3写入数据的权限。 这些帐户应密切监控。
  • 白银:这类IAM用户或角色曾大量中等风险的API调用的历史,例如Describe和 List操作或对Amazon S3的只读访问请求。
  • 青铜:这些IAM用户或角色通常在AWS环境中执行较少量的Describe 和List  API调用。

Macie使用如下的界面展示用户行为分析。

告警管理

Macie内置了40种告警规则,我们可以根据实际情况选择启用或者禁用该规则。

下面我们选择级别为 严重(Critical) 的告警规则进行分析。

从上图可知该告警的规则是 “如果 IAM Policy 设置 S3存储桶可以被任何人可读,那么触发告警”, 告警样例如下:

添加自定义告警

Macie不仅仅支持内置的告警规则设置,同时也支持自定义规则的定义。

场景:

根据 Macie 定义的规则,如果文档中包含 “merger, acquisition, divestiture, reorganization, consolidation, demerger, restructuring, rebranding, takeover, subsidiary” 关键字,那么该文档会被分类为 “Corporate Growth Keywords”的类别。

现在假设用户往S3上传了具有上述关键字文档,可能存在信息泄漏的风险,需要发送告警严重级别为 “Medium”的告警。

下面演示如何添加自定义告警

1.     进入Macie Console

2.     点击 Setting-> Protect data –> Basic alerts

3.     点击 Add New 按钮

4.     按照如下样例填写

Alert Title: Test Customer Alert

Description: Test Customer Alert

Category: 选择 Information Loss

Query: themes:” Corporate Growth Keywords ”

Index: 选择S3 objects

Min number of matches:1

Severity:Medium

Whitelisted Users: 不选

5.     点击 Save 按钮.

6.     往S3上传如下内容的word文件

7.     上传成功(存储桶名字暴露了)

8.     回到DASHBOARD界面,收到告警

注:在Alert中定义最关键的部分是Query, Macie会把Query中的内容使用JavaCC转换成Lucene Query。有关查询语法的更多信息,请参阅Apache Lucene – Query Parser Syntax

如下是常见搜索的示例:

  • 搜索任何不是源自Amazon IP地址的控制台登录:

eventNameIsp.compound:/ConsoleLogin:~(Amazon.*)/

  • 公共S3存储中的PII(Personally Identifiable Information)

filesystem_metadata.bucket:”my-public-bucket” AND (pii_impact:”moderate” OR pii_impact:”high”)

同AWS其他服务集成

Amazon Macie 可以同其他AWS服务集成。如下示例如何使用CloudWatch和SNS集成。具体演示如下:

1.     创建SNS并使用相应的邮箱确认

2.     在CloudWatch 创建Rule

3.     收到告警邮件

更改S3元数据(Metadata)的保存周期

缺省条件下,Macie保存S3 元数据的周期是一个月,但可以系统支持该周期最长为12个月。更改步骤如下:

  1. 进入Macie Console
  2. 点击 Integrations -> Choose retention duration for S3 metadata –> Select a range

总结

Macie使用机器学习算法自然语言处理S3中存储的数据,并且使用上下文信息对信息进行分类,并给数据分配相应的业务价值标签。自动发现分类和保护存储在AWS中的敏感数据,同时持续检查S3桶中PUT请求的CloudTrail事件,并几乎实时自动对新对象进行分类。同时监控CloudTrail的API日志,识别出日常的用户行为模式,一旦Macie发现异常的行为,可以及时的发出告警。

通过Macie,可以方便的实现数据安全自动化,及数据可视化和数据丢失防护。

 

作者介绍
刘春华,AWS 解决方案架构师,AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内和全球的应用和推广,在大规模并发应用架构、无服务器架构,人工智能与安全等方面有丰富的实践经验。 曾任IBM云架构师,对企业应用迁移到云及应用系统改造有深入的研究。

 

 

基于S3的图片处理服务

作者:高寅敬 徐榆

1.背景介绍

随着移动互联网的快速发展,各种移动终端设备爆发式的增长,社交类APP 或者电商网站为了提升访问速度、提高用户体验,必须根据客户端的不同性能,不同屏幕尺寸和分辨率提供适当尺寸的图片。这样一来开发者通常需要预先提供非常多种不同分辨率的图片组合,而这往往导致管理难度的提升和成本的增加。

在这篇博客中,我们将探讨一种基于S3的图片处理服务,客户端根据基于HTTP URL API 请求实时生成不同分辨率的图片。

2.解决方案架构

为了保证图片服务的高可用,我们会把所有的图片(包括原图和缩率图)储存于AWS 的对象储存服务S3中,把图片处理程序部署于AWS EC2 中。大部分的图片请求都会直接由AWS S3返回,只有当S3中不存在所需缩率图时才会去请求部署于EC2 上的图片处理服务来生成对应分辨率图片。

业务流程:

  1. 用户客户端(通常是浏览器或者APP)发起请求200×200像素的图片
  2. S3中未存在该尺寸缩率图,于是返回HTTP 302 Redirect到客户端
  3. 客户端根据 HTTP 302响应,继续请求部署于 EC2 上的图片处理服务
  4. 部署于EC2的图片处理服务,会从 S3 获取源图
  5. 图片处理服务,根据请求参数生成对应尺寸图片缩率图
  6. 图片处理服务将对应的图片返回给客户端
  7. 图片处理服务把缩率图存回到S3中,加速下一次客户访问

3.架构特点

相较于预先生成所有所需分辨率图片和传统的基于独立图片处理服务器,这种新的处理方式包含以下优点:

更高的灵活性:

当我们的前端开发人员对界面进行改版时,时常会涉及到修改图片尺寸。对所有原始图片进行缩放的批处理是十分耗时,高成本且易出错的。利用这种基于URL API的实时处理方式,前端开发者指定新的尺寸后,立即就能生成符合客户访问新的网页和应用对应的图片,提高了前端开发人员的开发效率。

更低的储存成本:

对于传统图片处理方式,在未使用之前预先批量生成所需分辨率图片,占用大量的储存空间,而且利用率并不高。

以按需方式生成图片,能减少不必要的储存空间,降低储存成本。

相对于独立图片处理服务器把图片完全储存于EC2的EBS卷,储存于S3 的成本也更低。

我们知道缩率图是属于可再生数据,所以我们在程序上 会把缩率图储存为 S3的去冗余储存类型,再次降低约13% 的存储成本。

更高的服务可用性:

我们可以看到,独立地部署单台图片服务器,无法支持大并发负载。同时存在单点故障 无法保证服务的高可用性,高可扩展性。

而基于S3的解决方案,大量的图片请求,由AWS S3 来完成,S3 会自动扩展性能,因此应用程序的运行速度在数据增加时不会减慢。

只有少量的未生成的图片尺寸才会用到部署于EC2 的图片服务器,并且我们图片逻辑服务器与图片储存S3是解耦合关系,我们还可以针对 基于EC2的图片处理服务 进行横向扩展,比如把图片服务程序 加入到 Web服务器层,配合 负载均衡器 ELB、自动伸缩组 AutoScaling 来实现自动伸缩。

4.服务部署

为了服务部署能更接近生产环境,我们以下所有步骤将以创建一个以域名为 images.awser.me 的图片服务为例,来详细介绍如何基于AWS 来部署。

 

在EC2上部署图片处理服务

1.创建一台EC2服务器,并赋予 具有S3 访问权限的IAM 角色,配置正确的安全组开启 HTTP 80端口访问权限。

2.  示例程序基于PHP,所以需要确保服务器安装了 Apache 2.4 和PHP 7.0 以上。以及PHP 图片处理的相关的组件:ImageMagick、ImageMagick-devel 。

参考 基于Amazon Linux 的安装命令:

yum -y install httpd24 php70 ImageMagick  ImageMagick-devel php70-pecl-imagick php70-pecl-imagick-devel

3.  从 github 或者 从S3 下载图片处理程序,修改 根目录 resize.php 文件,bucketName 变量为你的域名或者是你的储存桶名称,例如:$bucketName=’images.awser.me’。

将程序部署于你的 web 目录底下,并且确保 能通过EC2 公网IP  进行访问。

例如:http://52.80.80.80/resize.php?src=test_200x200.jpg

最好为你的图片服务器设置一个域名,我们这里设置了 imgpro.awser.me。

例如: http://imgpro.awser.me/resize.php?src=test_200x200.jpg

这里记录下你的 EC2 Web 访问地址,在下一步的 S3 储存桶配置中会用到。

创建和配置S3储存桶

1.  创建储存桶

由于我们在生产环境中,需要使用指定的域名来访问S3资源。所以我们需要在S3 控制台 创建储存桶时,把储存桶名称设置为我们的域名,如: images.awser.me。

2.  储存桶权限控制

在刚刚创建的S3 储存桶,权限选项卡中 选择储存桶策略填写如下内容(注意修改 images.awser.me 为你的域名 或者 储存桶名称) 开启匿名访问

{

  "Version":"2012-10-17",

  "Statement":[

    {

      "Sid":"AddPerm",

      "Effect":"Allow",

      "Principal": "*",

      "Action":["s3:GetObject"],

      "Resource":["arn:aws-cn:s3:::images.awser.me/*"]

    }

  ]

}

3.  开启静态网站托管

在刚刚创建的S3储存桶,属性选项卡中 开启 静态网站托管 ,并配置 重定向规则 为以下示例内容(请修改HostName 为上一步骤 所创建的EC2 Web访问地址):

<RoutingRules>

  <RoutingRule>

    <Condition>

      <KeyPrefixEquals/>

      <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>

    </Condition>

    <Redirect>

      <Protocol>http</Protocol>

      <HostName>imgpro.awser.me</HostName>

      <ReplaceKeyPrefixWith>resize.php?src=</ReplaceKeyPrefixWith>

      <HttpRedirectCode>302</HttpRedirectCode>

    </Redirect>

  </RoutingRule>

</RoutingRules>

记录终端节点名称 例如:images.awser.me.s3-website.cn-north-1.amazonaws.com.cn

在DNS 服务商 添加一个CNAME记录 ,把你的自定义域名 如images.awser.me 解析到 该终端节点上。

4.  配置S3 存储桶生命周期,自动清理缩率图

随时时间推移,我们会发现我们保存着在大量过时的缩率图,造成储存空间的浪费。其实我们可以利用S3存储桶的生命周期功能,来实现一定时间范围以外的缩率图自动清理。

在S3储存桶管理选项卡中,选择 添加生命周期规则

由于我们在图片缩放程序中,产生缩率图的过程,已经给所有缩率图打上了一个特殊标签 thumbnail = yes,那么我们就可以在生命周期规则中,把该标签作为过滤条件,这样才不会影响储存桶中的其他资源(如原图)。

然后在过期选项中设置,过期时间为30天。

这样配置完以后,所有缩率图生成三十天后会自动清理,来节省储存和管理成本。

5.测试图片缩放

首先上传一张测试图片至S3存储桶,我们选择一张经典的地球图片作为测试 命名为earth.jpg。

1.测试使用 S3 终端节点访问,测试储存桶 权限是否配置正确:

http://images.awser.me.s3-website.cn-north-1.amazonaws.com.cn/earth.jpg

2.测试使用 自定义域名访问,测试储存桶命名以及DNS 配置是否正确

http://images.awser.me/earth.jpg

3.测试图片缩放功能是否正常,尝试请求一张 200×200 像素的图片:

http://images.awser.me/earth_200x200.jpg    

如果一切正常,我们可以看到浏览器 会自动跳转访问

http://imgpro.awser.me/resize.php?src=earth_200x200.jpg

并返回200×200 像素的图片。

4.测试S3 缓存是否生效,当我们第二次访问

http://images.awser.me/earth_200x200.jpg                                                                                                                     如果一切正常,我们可以观察到 浏览器 没有做跳转。

6.总结

以上内容是对基于S3的图片处理服务解决方案的一个简单实现,也提到一部分生产环境可能遇到的问题,比如图片服务器的自定义域名、使用S3 低冗余储存类型来降低成本、缩率图的自动清理等。

其实实际生产环境还可以对成本进行进一步优化,比如可以分析S3 产生的访问日志,找出访问记录比较久远的对象 、调用S3 API 对长久未使用的缩率图进行定时清理,甚至可以根据日志做分析 找出热门的图片格式需求,提前针对热门图片生产缩率图,提高用户体验。

另外通过以上的架构描述可以看出,由于AWS 所提供的所有云服务都有丰富的API 接口 和详细的配置选项,它就像一个乐高玩具一般,开发人员或者架构师可以脑洞大开随意去组合它成为自己想要的产品。

 

作者介绍:

高寅敬,AWS解决方案架构师,负责基于AWS云计算方案架构的咨询和设计,在国内推广AWS云平台技术和各种解决方案。在加入AWS之前就职于美国虚拟运营商Seawolf海狼通讯,超过7年的互联网通信应用系统开发和架构经验。
超过5年的AWS实践经验, 精通基于AWS全球分布式VoIP系统的开发、运营及部署,深度理解AWS核心的计算、网络、存储以及云计算的弹性伸缩。

徐榆,AWS实习架构师,研究生一年级对云计算/大数据和人工智能有一定研究。

搭建基于S3的HBase读备份集群

作者:刘磊

当前aws的很多客户已经从将s3作为HBase的存储中获益,这当中包括更低的存储花费、更好的数据可靠性、更容易的扩展操作等待。比如FINRA就通过将HBase迁移到s3上将在存储上的花费降低了60%,此外还带来了运维上的便利,以及架构上的重大优化:将s3作为统一的存储层,实现了更彻底的存储和计算分离。在s3上部署HBase集群,可以让你在集群启动后立即进行数据查询操作,而不用等待漫长的快照恢复过程。

随着Amazon EMR 5.7.0的发布,现在你可以在集群层面进一步提升数据的高可用性和高可靠性,方法是基于同一个s3存储桶建立多个HBase的读备份集群。这会让你的数据通过读备份集群及时地被用户访问,即使在主集群遇到问题关闭的时候,当然你还可以通过在多个可用区中部署读备份集群来进一步增加数据访问服务的可靠性。

接下来的文章将告诉你如何在s3上建立HBase的读备份集群。

HBase 简介

Apache HBase是Apache Hadoop生态体系中的大规模、可扩展、分布式的数据存储服务。同时它还是开源的,非关系型的版本数据库,默认情况下运行在HDFS之上。它的设计初衷是为包含了数百万个列的数十亿行记录提供随机的、强一致性的、实时访问。同时它还和Apache Hadoop、Apache Hive和Apache Pig等大数据服务紧密结合,所以你可以轻易地为并行数据处理提供快速的数据访问。HBase数据模型、吞吐量、和容错机制能很好地为广告、web分析、金融服务和基于时间序列数据的应用等工作负载提供支持。

和其他很多Nosql数据库类似,HBase中的表设计直接影响着数据的查询和访问模式,根据这些模式的不同,查询的性能表现也会有非常大的差异。

HBase on S3

在建立基于S3的HBase读备份集群之前,你必须先学会HBase on S3的部署方法,本段为那些不熟悉HBase on S3架构的人提供了一些基本信息。

你可以通过将S3作为HBase的存储层,来分离集群的存储和计算节点。这使得你可以根据计算需求来规划集群,从而削减开支,毕竟你不再需要为HDFS上存储的3备份数据支付费用了。

HBase on S3架构中的默认EMR配置使用内存和本地磁盘来缓存数据,以此来提升基于S3的读性能。你可以在不影响底层存储的情况下任意地对计算节点进行伸缩,或者你还可以关闭集群来节省开支,然后快速地在另一个AZ中重新进行部署。

HBase on S3读备份集群应用案例

使用HBase on S3架构使得你的数据被安全、可靠地存储起来。它将数据和集群隔离进行存储,消除了因为集群异常终止带来数据丢失的可能性。尽管如此,在一些特殊情况下,你还是会希望数据能获得更高的可用性,比如集群异常终止或者整个AZ失效。另外一个情况是,通过多个集群访问一个S3上的根目录,你可以隔离HBase集群的读写操作,从而来降低集群的压力,提供更高SLA的查询服务。尤其是在主集群因为bulk load、heavy write、compaction等操作变得异常繁忙的时候。

下图展示了没有读备份的HBase on S3架构,在这个场景下,诸如集群终止和AZ失效等异常情况会使得用户无法访问数据。

S3上的HBase根目录,包含了HFile和表的原数据信息。

EMR 5.7.0之前的版本,无法将多个HBase集群指向同一个S3上的根目录,为了获得更高的可用性,你需要在S3上创建多个数据副本,并管理它们之间的一致性。

随着EMR 5.7.0的发布,现在你可以启动多个读备份集群并指向S3桶上同一个根目录,保证了你的数据通过读备份集群它们总是可达的。

下面是一些使用HBase读备份集群的例子,展示了启用前后的一些对比情况。

处于同一个AZ的HBase读备份集群:

处于不同AZ的HBase读备份集群:

基于S3的HBase读备份集群的另一个好处是可以更加灵活地根据具体的工作负载来规划你的集群。比如,虽然你的读负载很低,但还是想要获得更高的可用性,那么就可以启动一个由较小实例组成的规模较小的集群。另一个例子是当你遭遇bulk load时,在高峰期集群需要扩张到很大以满足计算需求,在bulk load结束后,集群可以立即缩减以节省开支。在主集群伸缩的时候,读备份集群可以维持一个固定的规模以对外提供稳定的查询服务。

步骤

使用下列的步骤来启动基于S3 的HBase读备份集群,这项功能只针对EMR 5.7.0之后的版本。

创建使用HBase on S3的EMR集群:

aws emr create-cluster --termination-protected --applications Name=Hadoop Name=Hive Name=HBase Name=Spark Name=Phoenix --ec2-attributes '{"KeyName":""}' --release-label emr-5.7.0 --instance-groups '[{"InstanceCount":1,"InstanceGroupType":"MASTER","InstanceType":"m3.xlarge","Name":"Master - 1"},{"InstanceCount":20,"BidPrice":"0.15","InstanceGroupType":"CORE","InstanceType":"m3.2xlarge","Name":"Core - 2"}]' --configurations '[{"Classification":"emrfs-site","Properties":{"fs.s3.consistent.retryPeriodSeconds":"1","fs.s3.consistent":"true","fs.s3.consistent.retryCount":"5","fs.s3.consistent.metadata.tableName":"YOUR_CONSISTENT_VIEW_TABLE_NAME"},"Configurations":[]},{"Classification":"hbase","Properties":{"hbase.emr.storageMode":"s3","hbase.emr.readreplica.enabled":"true"},"Configurations":[]},{"Classification":"hbase-site","Properties":{"hbase.rootdir":"s3:///"},"Configurations":[]}]' --service-role EMR_DefaultRole --name 'HBase Read Replica'

配置文件示例JSON

[ 
   { 
      "Classification":"hbase-site",
      "Properties":{ 
         "hbase.rootdir":"s3://{S3_LOCATION}",
      }
   },
   { 
      "Classification":"hbase",
      "Properties":{ 
         "hbase.emr.storageMode":"s3",
         "hbase.emr.readreplica.enabled":"true"
      }
   }
]

向主集群添加数据

需要特别注意的是,在使用HBase读备份集群时,你必须要确保主集群上所有的写操作都被刷新到S3桶的HFile中。读备份集群会读取这些HFile中的数据,任何没有从Memstore刷新到S3的数据都不能通过读备份集群访问。为了确保读备份集群总是读到最新的数据,请参考以下步骤:

  • 写入数据到主集群(大批量写入请使用Bulkload)
  • 确保数据被刷新到S3桶中(使用Flush命令)
  • 等待region 分割以及合并操作完成以确保HBase表的元数据信息保持一致性状态
  • 如果任何region发生了分割、合并操作,或者表的元数据信息发生了变化(表的增加和删减),请在从集群上运行refresh_meta命令
  • 当HBase表发生更新操作后,请在从集群上运行refresh_hfiles命令

从备份集群读区数据

你可以像往常一样从备份集群检索任何数据。

从主集群读取数据的截图:

从备份集群读取数据的截图:

可以看出,两个集群返回了同样的数据。

保持备份集群和主集群的一致性
为了保持备份集群数据和主集群的一致性,请参考以下建议:

在备份集群上:

1.运行refresh_hfiles命令:

  • HBase表中的数据发生变化时(增、删、改)

2.运行refresh_meta:

  • Region发生变化时(splits,compacts)或者集群中增加、删除了HBase表

在主集群上:

1.如果启用了compaction,运行compaction命令以避免Major Compation被触发引起数据的不一致性。

相关的属性和命令:
HBase属性:

Config Default Ex planation
hbase.meta.table.suffix “” Adds a suffix to the meta table name: value=’test’ -> ‘hbase:meta_test’
hbase.global.readonly.enabled False Puts the entire cluster into read-only mode
Hbase.meta.startup.refresh False Syncs the meta table with the backing storage. Used to pick up new tables or regions.

如果hbase.emr.readreplica.enabled被设置为true,那么上述属性会被自动设置好。

HBase命令:

Command Description
refresh_hfiles <Tablename Refreshes HFiles from disk. Used to pick up new edits on a read replica.
clear_block_cache <tablename> Clears the cache for the specified table.
refresh_meta Syncs the meta table with the backing storage. Used to pick up new tables/regions.

总结

现在你可以为HBase建立高可用的读备份集群,通过它,在主集群发生异常情况时,你仍然可以获取稳定的数据查询服务。

 

作者介绍

刘磊,AWS大数据顾问,曾供职于中国银联电子支付研究院,期间获得上海市科技进步一等奖,并申请7项国家发明专利。现任职于AWS中国专家服务团队,致力于为客户提供基于AWS服务的专业大数据解决方案、项目实施以及咨询服务。

挖掘EB级别数据的价值 – Redshift Spectrum介绍及最佳实践

随着数据存储技术的快速发展,众多企业客户可以以低成本存储PB级别甚者EB级别的数据。这使得大数据分析在近几年来不但成为现实而且愈发火热。然而真正实现海量数据的分析既要有存储海量数据的资源,又要有足够强大的分析能力。近年来我们看到数据分析能力的发展并没有追赶上存储技术的发展速度 。现实中企业客户虽然有了可以收集并存储大量数据的能力,但很多数据并不能被有效的分析甚至根本未作任何分析,形成了所谓的暗数据。这使得数据分析能力成为实现大数据分析的真正瓶颈。

作为一个托管的数据仓库服务,Amazon Redshift从它发布至今已经帮助全球成千上万的客户解决了PB级别数据的分析能力,实现了复杂SQL的快速查询。但随着数据的飞速增长,我们看到越来越多的客户数据开始逼近EB级别。对于这样体量的大数据,虽然Redshift也可以支持快速的复杂SQL查询,但毕竟我们需要启动更多的Redshift集群,消耗更多的CPU和存储成本,同时还要付出更多的数据加载时间。相反如果我们为了节省资源和成本把数据放在S3上,通过EMR集群也可以实现快速低成本的数据清理,但针对复杂的(诸如Join类)的查询速度会很慢,不能很好支持。这形成了一个鱼与熊掌不可兼得的选择题。

为了真正摆脱数据分析的瓶颈、消灭暗数据,我们的客户需要既能高效执行复杂的查询,又能享受高度可扩展的数据并行处理,也能利用近乎无限的低成本的S3存储资源,还要可以支持多种常用的数据格式。满足这种”既又也还”的任性就是我们的新服务Redshift Spectrum的使命。

Redshift Spectrum 介绍

Redshift Spectrum可以帮助客户通过Redshift直接查询S3中的数据。如同Amazon EMR,通过Redshift Spectrum客户可以方便的使用多种开放数据格式并享有低廉的存储成本,同时还可以轻松扩展到上千个计算节点实现数据的提取、筛选、投影、聚合、group、排序等等操作。Redshift Spectrum采用了无服务器架构,所以客户不需要额外配置或管理任何资源,而只需为Redshift Spectrum的用量付费。使用方面,Redshift Spectrum享有和Amazon Redshift一样的复杂查询的优化机制、本地数据的快速读取以及对标准SQL的支持。结合上述功能特点,Redshift Spectrum可以在几分钟内完成对EB级别的数据的复杂查询,这使它在众多大数据分析服务中脱颖而出。我们做了一个实验,在对一个EB的数据做涉及四个表的join,filter和group的查询时,1000个节点的Hive集群预估需要耗时5年,而Redshift Spectrum只用了173秒。

另外Redshift Spectrum 是Amazon Redshift的一个内置功能,所以使用Redshift Spectrum 对Redshift客户现有的查询服务和BI工具不会有任何影响。在Redshift Spectrum的底层,我们负责管理着成千上万的跨多个可用区的计算节点。这些节点根据客户查询任务的复杂度和数据量实现透明的扩展和分配,前端的客户无需做任何资源部署和配置。Redshift Spectrum也很好的支持了高并发 – 客户可以通过任何多个Amazon Redshift集群同时访问S3上的数据。

Redshift Spectrum 上一个查询任务的生命周期

一切从Redshift Spectrum的查询任务提交给Amazon Redshift集群的领导节点开始。首先,领导节点负责优化、编译、并推送查询任务给Amazon Redshift集群的计算节点。然后,计算节点从外部表获得数据目录,并基于查询任务里的join和filter动态移除不相关的数据分区。这些计算节点同时也会检测在Redshift本地是否已有部分查询数据,从而只从S3上扫描本地没有的数据以提升效率。

接下来,Amazon Redshift的计算节点会基于需要处理的数据对象生成多个查询需求,并行提交给Redshift Spectrum,Redshift Spectrum再据此启动上千个工作线程。 这些工作线程进一步从S3上扫描、筛选并聚合数据,将处理好的结果数据传回Amazon Redshift集群。最后,传回的结果数据在Redshift 集群本地作join和merge操作,然后将最终结果返回给客户。

Redshift Spectrum 的优势

Redshift Spectrum的架构设计有很多优势。第一,剥离计算与S3上的存储,使计算资源可以独立弹性扩展。第二,大幅提升了并发效率,因为客户可以用多个Redshift集群访问同一组S3上的数据。第三,Redshift Spectrum沿用了Amazon Redshift的查询优化机制,可以生成高效的查询规划,即便面对诸如多表join或者带统计函数(window function)的复杂查询也能胜任。第四,可以对多种格式的数据源直接查询 – Parquet, RCFile, CSV, TSV, Sequence, Avro, RegexSerDe等等。这意味着我们无需再做数据加载和转化,同时也消除了存储重复数据带来的成本浪费。第五,通过对开放数据格式的支持,客户的不同团队也可以借助其他的AWS服务访问同一组S3上的数据,实现协同办公。拥有上述这些优势的同时,因为Redshift Spectrum 是 Amazon Redshift的内置功能,客户同时也享受了与Amazon Redshift同级别的端到端的安全、合规、以及安全认证。

Redshift Spectrum最佳实践

使用Redshift Spectrum时,我们建议可以从数据分区,列数据结构和数据压缩这几个关键点出发实现S3上数据查询效率的提升以及降低查询成本。数据分区方面,按照日期、时间或其他客户自定义的key来对数据进行分区可以帮助Redshift Spectrum 在查询中动态的移除不相关分区以减少扫描的数据量。数据结构方面,我们推荐使用列存储,比如Parquet格式,这样Redshift Spectrum只需扫描要查询的列而不是整个数据,这可以进一步减少扫描的数据量。数据压缩方面,如果数据可以预先用Redshift Spectrum支持的压缩格式压缩,我们同样可以再次减少扫描的数据量。

另外,从数据访问频率来看,我们建议将频繁访问的数据放到Amazon Redshift集群中,以获得Redshift作为数据仓库服务带来的众多优势。同时,更多的海量数据可以以多种开放数据格式存储在S3上,比如历史数据或近期数据,利用Redshift Spectrum 将S3变成一个可随时支持SQL查询的数据湖。

下边再列举六个具体使用时的技巧:

  1. 使用多个临时Redshift 集群提升并发:Redshift Spectrum支持多个Redshift集群访问同一组S3上的数据,我们可以考虑在业务高峰期时临时开启多个Redshift集群,提升并发支持更多的查询任务。因为数据庞大的表我们可以放在S3上,所以这些临时Redshift集群本地只需存储相对少量的数据即可胜任,在高峰期过后可以关闭这些临时集群。这样客户用相对较小的几个集群就可以轻松应对高峰的大并发。
  2. 列存储文件的分区应尽量基于常用的数据列:常用来做filter、join等操作的数据列是分区的首选。另外,分区的粒度过细可能会使读取分区信息花费更多时间,但同时也会极大减少数据查询时的数据量。客户可以根据自己的实际情况权衡。最后,S3上的数据文件大小应尽量平均,例如10个256MB的文件要比1个1GB+6个256MB的文件读取更高效。
  3. 合理配置Redshift集群以优化Redshift Spectrum的性能:在Redshift Spectrum查询S3上的数据时,其并行线程取决于两个因素:(1) Query层面 – 每个slice上每个query可并行执行查询的线程数 (上限是每个slice每个query最多10个线程) (2) 节点层面 – 每个节点拥有的slice数量,不同类型节点的slice数量也不同。所以做一个简单的数学运算:当数据文件总数 ≤ (1) × (2),则在集群内部署更多的节点并不会提升性能。这个方法可以帮我们基于数据文件数量配置大小合理的Redshift 集群,从而在保证性能的同时减少资源浪费。
  4. 单表筛选、聚合类的查询在Redshift Spectrum上更有性能优势:这类没有join的查询任务通常性能瓶颈在I/O层面,比如数据扫面速度,这方面往往Redshift Spectrum可以比Redshift做的更快。
  5. 通过推送predicate类操作到Redshift Spectrum 提升对数据查询速度:Redshift Spectrum对S3上数据的扫描,投影,筛选,聚合等操作是独立于Redshift集群的。这类操作同时也不会占用Redshift集群的资源。常用的这类指令操作例如group by, like, count, sum, avg, min, max, regex_replace等等。我们可以善用这类操作减少Redshift集群的负载,提升查询效率
  6. 基于表的尺寸合理分配存储:我们建议尽量将大尺寸的表分成多个文件(诸如包含原始数据)放在S3上,而只将中小尺寸的表放入Redshift集群。这样在进行常规join查询时可以取得比较均衡的性能表现。

通过上述的介绍,希望大家对Redshift Spectrum有一个基本的了解。通过高度的并行处理,查询的优化以及对EB级别数据的复杂查询支持,相信Redshift Spectrum 能真正帮助企业客户挖掘海量数据的价值,在大数据分析上更进一步。

作者介绍

刘宁,致力于AWS数据库云服务的应用和推广。在加入AWS之前,他曾任微软中国企业服务部产品营销经理,华侨银行科技部IT产品经理,对企业应用设计及架构有着深刻了解。

原文链接:

https://aws.amazon.com/cn/blogs/big-data/amazon-redshift-spectrum-extends-data-warehousing-out-to-exabytes-no-loading-required/

https://aws.amazon.com/cn/blogs/big-data/10-best-practices-for-amazon-redshift-spectrum/

Amazon S3新版管理控制台的正确打开方式

Amazon Simple Storage Service(简称S3)是AWS在2006年发布的第一款云服务产品,S3作为对象存储具有海量存储、接口灵活、11个9持久性、价格便宜等特点,特别适合存放静态文件如图片、视频、日志以及备份文件等等,同时S3是AWS大数据解决方案中重要组成部分,以EMRFS的形式与EMR(AWS托管的Hadoop平台)结合提供计算与存储分离的灵活架构。

熟悉S3控制台的小伙伴一定发现,自从5月份开始,控制台的界面焕然一新,甚至有点无处下手,但熟悉起来后又有些爱不释手,下面我们将介绍下新版控制台带来了哪些新的功能,以及如何给你的工作带来极大效率提升。

新版控制台的操作说明,图文并茂,详见:

http://docs.amazonaws.cn/AmazonS3/latest/user-guide/what-is-s3.html

一、创建存储桶

创建存储桶的时候除了配置桶名、存储桶区域之外,还可以配置版本控制、日志、标签以及访问权限,现在用户可以在新版控制台使用“从现有存储桶复制设置”的功能,选择相同配置的存储桶即可,避免重复设置。

二、上传对象

在控制台下除了正常的通过点击上传按钮选择上传文件完成上传外,新版控制台支持在存储桶界面下,直接将待上传的对象拖放到页面上。通过新版控制台上传单个文件支持最大78GB。

对存储桶中对象的上传、删除、重命名等操作,页面底部可以看到该操作的进度及其他操作的历史记录。

三、ACL

我们可以通过配置存储桶及对象的ACL来实现存储桶和对象的访问控制,老版控制台的部分名称容易让人引起歧义,以存储桶ACL为例,如下图所示,其中查看权限是指查看该存储桶权限的权限,即查看该存储桶ACL的权限,而不是指查看存储桶的权限,编辑权限同样是指编辑权限的权限,不是编辑存储桶的权限。

在新版控制台中很好的避免了这点误区,分对象访问和权限访问,这里以存储桶的ACL举例,见下图:

其中一个新功能是我们可以在管理用户处添加其他帐号的规范ID(https://docs.aws.amazon.com/zh_cn/general/latest/gr/acct-identifiers.html )或帐号的Email向该帐号中的IAM user/role授权访问,以实现跨帐号访问,需要注意的是对方帐号的IAM user/role拥有对该存储桶的操作权限取决于此处我们设置的ACL以及对方帐号中IAM user/role本身policy设定的权限。

四、标签Tag

S3标签是随S3新版控制台一起发布的一个服务特性。标签可以帮助你对存储桶以及对象进行分类或标记,类似我们给EC2等资源添加标签一样,每个S3标签也是一个键值对,每个对象最多可添加10个标签键值对,键值对大小写敏感。通过使用标签,我们可以创建基于标签的IAM policy以实现细粒度的权限控制,比如标签为PHI的值为true时,仅供只读。同时,在使用S3数据生命周期管理、分析、指标等功能的时候,可以创建基于标签的过滤器,实现细粒度的资源管理。

S3 标签作为新服务特性,相应的API也同步发布,比如PUT Object tagging, GET Object tagging, DELETE Object tagging以及其他支持标签的API如PUT Object, GET Object, POST Object, PUT Object-Copy,详细可参考:

http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/dev/object-tagging.html 需要注意的是,标签遵循最终一致性模型。

五、生命周期管理

数据通常从创建后会经历频繁访问、低频访问、极少访问的数据热度周期,相对于热数据,冷数据适合以成本更低的方式存储,比如热数据存放在S3 standard,冷数据存放在S3-IA,归档数据存放在Glacier等,以达到成本最优的目标。我们可以使用S3数据生命周期管理通过配置相应的规则来实现数据的生命周期管理,随着S3标签的发布,现在我们可以创建基于前缀和/或基于标签的规则,以实现更细粒度的资源管理。详细操作步骤见:

http://docs.amazonaws.cn/AmazonS3/latest/user-guide/create-lifecycle.html

六、存储类分析

存储类分析是新发布的功能,通过该工具,我们可以更加直观的了解到存储桶中的数据活跃情况,帮助我们决策何时将不常访问的数据从S3 Standard转换为S3-IA,即为配置数据生命周期管理提供数据支持。

同时,可以创建筛选条件,选择对整个桶中对象或者具有某些前缀或标签的对象进行分析,即对对象进行分类分析,需要注意的是,分析是从启用该功能后一段时间后才能看到结果(通常是24~48小时),并不是可以立刻可以看到分析结果。

通过存储类分析,我们可以可视化的了解到存储桶数据在过去30天的检索量,占比,以及多个时间范围段内数据存储与检索的情况,该数据每天更新,并且可以以csv的格式导出到S3存储桶以供下载,可使用Quicksight等BI工具进行展现。

csv中字段说明见:

http://docs.amazonaws.cn/en_us/AmazonS3/latest/dev/analytics-storage-class.html#analytics-storage-class-export-to-file

配置存储类分析详细操作步骤见:

http://docs.amazonaws.cn/AmazonS3/latest/user-guide/configure-analytics-storage-class.html

七、存储指标

CloudWatch可以监控S3存储桶的使用情况,过去只有两个指标:存储桶大小和对象数量,随着新版控制台的发布,又有两类指标发布,即请求指标和数据传输指标。

请求指标(收费功能)中包含GetRequest, PutRequest, ListRequest, AllRequest, PostRequest, DeleteRequest, HeadRequest, 4xxErrors, 5xxErrors。数据传输指标(收费功能)包含TotalRequestLatency,FirstByteLatency,BytesDownloaded,BytesUploaded。这些指标均为1分钟报告1次,我们可以通过这些指标快速了解和定位S3使用过程中的一些问题,比如当前S3存储桶是否遇到性能瓶颈,是否需要提case提升限制等等。同样可以通过配置基于前缀/标签的过滤器实现细粒度的管理。

S3请求速率及性能注意事项参见:

http://docs.amazonaws.cn/AmazonS3/latest/dev/request-rate-perf-considerations.html

指标详细解释可以见:

http://docs.amazonaws.cn/en_us/AmazonS3/latest/dev/cloudwatch-monitoring.html#s3-request-cloudwatch-metrics

配置请求指标操作步骤见:

http://docs.amazonaws.cn/AmazonS3/latest/user-guide/configure-metrics.html

八、存储清单

S3存储清单是S3 提供的一项存储管理工具,S3存储清单可以每天或每周输出指定S3存储桶或存储桶中指定前缀的对象及其相关元数据信息的列表,并以CSV文件的格式存储在指定的S3存储桶中。存储清单遵循最终一致性模型,即列表中可能没有最近添加或删除的对象信息,如果需要确认某一个对象的状态,我们可以使用HEAD Object REST API(或命令行,SDK)来获取该对象的元数据。

对于存储桶中有海量文件的用户而言,存储清单可以方便的帮助用户了解当前存储桶中的文件列表而不是像过去那样需要频繁调用GET Bucket API(每次返回最多1000个对象),从而加速一些业务工作流及大数据作业等等。

配置存储清单时,我们可以指定清单筛选条件、生成频率、存储位置、清单中包含的字段等等,一个存储桶可以配置多个清单。

配置存储清单操作步骤见:

http://docs.amazonaws.cn/AmazonS3/latest/user-guide/configure-inventory.html

看完上面S3新版控制台的介绍,是不是对这个新工具又有了一些新的认识,不妨将这些新功能用起来,优化成本,提升工作效率,在AWS上面诞生更多的创新应用。

作者介绍

王世帅,AWS解决方案架构师,负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内教育、医疗行业的应用和推广。在加入AWS之前曾在国航担任系统工程师,负责存储方案的架构设计,在企业私有云方面有丰富经验。

Cloud Directory 更新 – 对类型化链接的支持

今年早些时候,我谈论了 Cloud Directory – 用于分层数据的云原生目录以及它如何存储大量强类型分层数据。由于 Cloud Directory 可扩展到数亿个对象,因此它非常适合许多云和移动应用程序。在我的原始博客文章中,我已经说明每个目录如何具有一个或多个架构,以及每个架构如何又具有一个或多个分面。每个分面为对象定义所需的和允许的属性集。

类型化链接简介

现在,我们通过增加对类型化链接的支持,来增强 Cloud Directory 模型的表现力。您可以使用这些链接在层次结构中创建对象-对象关系。可以为每个目录定义多种链接 (每种链接类型均是与目录关联的其中一个架构中的单独分面)。除了类型之外,每个链接还可具有一组属性。类型化链接可帮助确保不会无意中删除目前与其他对象有关系的对象,从而保持参考数据的完整性。假定您具有包含位置、工厂、楼层、房间、机器和传感器的目录。上述每个项均可表示为 Cloud Directory 中的一个维度,它在层次结构中具有丰富的元数据信息。您可以定义和使用类型化链接以通过各种方式将对象联系在一起,并创建导致维护要求、服务记录、担保和安全信息的类型化链接,以及链接上用于存储有关源对象和目标对象之间的关系的其他信息的属性。随后,您可以根据链接类型和链接中的属性值来运行查询。例如,您可以找到过去 45 天内未清除的所有传感器,或已超过保修期的所有电机。您可以查找指定楼层的所有传感器,也可以查找给定类型的传感器所在的所有楼层。

使用类型化链接

要使用类型化链接,您只需使用 CreateTypedLinkFacet 函数将一个或多个类型化链接分面添加到架构。然后,调用 AttachTypedLink,并传入源对象和目标对象、类型化链接分面和链接的属性。其他有用函数包括 GetTypedLinkFacetInformationListIncomingTypedLinksListOutgoingTypedLinks。要了解更多信息和查看完整函数列表,请查看 Cloud Directory API 参考。就像为对象执行的操作一样,您可以使用属性规则来约束属性值。您可以约束字符串和字节数组的长度、将字符串限定为一组指定的值并将数目限定为特定范围。我的同事分享了一些示例代码来说明如何使用类型化链接。以下是 ARN 和分面名称:

String appliedSchemaArn   = "arn:aws:clouddirectory:eu-west-2:XXXXXXXXXXXX:directory/AbF4qXxa80WSsLRiYhDB-Jo/schema/demo_organization/1.0";
String directoryArn       = "arn:aws:clouddirectory:eu-west-2:XXXXXXXXXXXX:directory/AbF4qXxa80WSsLRiYhDB-Jo";
String typedLinkFacetName = "FloorSensorAssociation";

第一个代码段按以下顺序创建名为 FloorSensorAssociation 的类型化链接分面,带有 sensor_typemaintenance_date 属性 (属性名和值是链接标识的一部分,因此顺序很重要):

client.createTypedLinkFacet(new CreateTypedLinkFacetRequest()
                                .withSchemaArn(appliedSchemaArn)
                                .withFacet(
                                      new TypedLinkFacet()
                                          .withName(typedLinkFacetName)
                                          .withAttributes(toTypedLinkAttributeDefinition("sensor_type"),
                                                          toTypedLinkAttributeDefinition("maintenance_date"))
                                          .withIdentityAttributeOrder("sensor_type", "maintenance_date")));

private TypedLinkAttributeDefinition toTypedLinkAttributeDefinition(String attributeName) {
 return new TypedLinkAttributeDefinition().withName(attributeName)
 .withRequiredBehavior(RequiredAttributeBehavior.REQUIRED_ALWAYS)
 .withType(FacetAttributeType.STRING);
}

下一个代码段创建两个对象 (sourceFloortargetSensor) 之间的链接,带有 sensor_type watermaintenance_date 2017-05-24

AttachTypedLinkResult result = 
    client.attachTypedLink(new AttachTypedLinkRequest()
                               .withDirectoryArn(directoryArn)
                               .withTypedLinkFacet(
                                   toTypedLinkFacet(appliedSchemaArn, typedLinkFacetName))
                                   .withAttributes(
                                        attributeNameAndStringValue("sensor_type", "water"),
                                        attributeNameAndStringValue("maintenance_date", "2017-05-24"))
                                   .withSourceObjectReference(sourceFloor)
                                   .withTargetObjectReference(targetSensor));

private TypedLinkSchemaAndFacetName toTypedLinkFacet(String appliedSchemaArn, String typedLinkFacetName) {
   return new TypedLinkSchemaAndFacetName()
              .withTypedLinkName(typedLinkFacetName)
              .withSchemaArn(appliedSchemaArn);
}

最后一个代码段枚举了 sensor_type watermaintenance_date 的所有传入类型化链接,范围为 2017-05-202017-05-24

client.listIncomingTypedLinks(
    new ListIncomingTypedLinksRequest()
        .withFilterTypedLink(toTypedLinkFacet(appliedSchemaArn, typedLinkFacetName))
        .withDirectoryArn(directoryArn)
        .withObjectReference(targetSensor)
        .withMaxResults(10)
        .withFilterAttributeRanges(attributeRange("sensor_type", exactRange("water")),
                                   attributeRange("maintenance_date", 
                                                  range("2017-05-20", "2017-05-24"))));

private TypedLinkAttributeRange attributeRange(String attributeName, TypedAttributeValueRange range) {
   return new TypedLinkAttributeRange().withAttributeName(attributeName).withRange(range);
}

private TypedAttributeValueRange exactRange(String value) {
   return range(value, value);
}

要了解更多信息,请参阅 Cloud Directory 管理指南中的对象和链接

现已推出

类型化链接现已提供,您可以立即开始使用!

-Jeff

客户端直连S3实现分片续传思路与实践

Amazon S3是互联网存储解决方案,能让所有开发人员访问同一个具备可扩展性、可靠性、安全性和快速价廉的数据存储基础设施。Amazon S3 提供了一个简单 Web 服务接口,可用于随时在 互联网上的任何位置存储和检索任何数量的数据。开发人员可以利用Amazon提供的REST API接口,命令行接口或者支持不同语言的SDK访问S3服务.

同时S3对于上传功能的API提供也是非常丰富的,与此同时,很多客户对于S3的断点续传也有了很深入的需求,本篇博客将会介绍如何使用S3的Javascript SDK来实现客户端浏览器到S3的断点续传功能.

安全考量

首先我们需要度量在浏览器客户端直连上传到S3这个场景下的安全问题,我们是一定不能把我们的AccessKey暴露到客户端浏览器的,但是上传到S3的API一定要提供AccessKey和SecretKey,因此这里我们将会利用生成临时的AccessKey和SecretKey(结合有效期)的方式来保证客户端的上传,这里介绍一篇关于利用TVM (Token Vending Machine)来生成临时Key并上传S3的文章,本文主要探讨关于S3的分片上传和断点续传的知识点.

Javascript SDK和S3 API简介

从整体编程语言架构的层面上来讲,AWS的各个语言的SDK都主要划分为上层和下层的API, 上层API主要是针对一些用户必要的功能利用下层API所作的一层封装,掌握了这个原则之后我们就可以合理的利用AWS的上层API看能否实现自身的需求.

Javascript SDK文档总结

在掌握SDK之前,我们应该先对SDK的文档和大致的结构有一个了解,这样才能方便我们更好的使用SDK, 下面列出了SDK的官网入门连接和API参考文档.

API参考文档: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html

S3 API参考文档: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html

构建SDK中的S3对象

首先,AWS的SDK都是先需要利用Credentials来构建对象的,这里我们构建S3的对象也是如此,但是请注意一定不能将自己的Key暴露在客户端或者提交到代码中,应该使用 TVM获取了Key之后再利用AWS.Credentials对象来构建S3的对象.

在构建S3对象时,也需要同时指定AWS的Region.

利用上层Javascript API构建简单的分片断点续传功能

接下来,我们一步一步的来创建上层API构建断点续传的实践.

1. 创建工程

这里我们以node.js平台的express来提供简单的静态服务. 本文不会涉及如何安装node.js,关于安装指南,可以参考官网nodejs.org 首先利用npm包管理器安装express模版生成器:

npm install express-generator -g

完成后我们利用命令行生成项目:

mkdir s3upload
express --view=ejs

这里的--view=ejs主要指定ejs作为express的html模版引擎,方便我们的测试. 创建好之后的工程结构如下图:

2. 编写页面UI

这里我们通过引入<script src="https://sdk.amazonaws.com/js/aws-sdk-2.45.0.min.js"></script>来在浏览器端倒入AWS SDK, 并且我们创建了一个id为progress的label来监控进度. 最后我们引入了/javascript/index.js来编写我们页面的业务逻辑.

分片上传控制

接下来我们在public/javascript文件夹中创建index.js

简单的两个静态文件就能够完成分片上传的功能了.

启动项目

由于Express已经建立好模版,只需要在控制台输入npm start就能够在3000端口监听服务,通过访问http://localhost:3000 就能够测试分片上传的功能了.
完整的项目代码可以在Github上访问.

设置CORS

由于SDK通过Ajax提交数据,需要在S3桶策略中配置跨域提交的CORS. 示例中的*建议在生产环境中改成自己的域名.

S3上层API说明

以上实践为大家简单介绍了如何使用S3点上层API自动完成分片上传的功能,并且通过事件监控的方式来了解上传的进度,这里主要有以下几点需要注意.

1). 上传api需要指定Bucket: ‘testupload’, Key: file.name让SDK识别到桶和文件的Key名称.

2). 由于是上层API, 因此上传程序将会实施自动分片,由于S3的最小分片是5M,所以当文件大于5M时此上传程序才会进行自动分片,并且每隔5M为一个切片进行上传工作.

3). SDK使用AJAX方式提交自动分片的文件,因此需要设置S3的跨域提交配置CORSRule.

4). 在整个过程中,不要在客户端暴露AccessKey和Secret,利用TVM (Token Vending Machine)一文来安全获取临时Token.

通过底层API来编写实现更多分片上传的功能.

S3的分片上传主要的原理是通过初始化一次上传的uploadId, 然后在主动取消或者完成前会一直沿用这个uploadId,如果用户使用这个uploadId持续上传分片则会一直保持该文件的上传,最后通过一个complete的操作来结束上传,并且会合并所有分片成为一个文件. 通过上述原理,我们的底层API主要会调用以下来实现自定义的分片上传:

1). 首先调用createMultipartUpload

2). 在返回了uploadId之后,将文件切片后利用uploadPart API指定在同一个uploadId下从第几段开始上传.

3). 最后调用completeMultipartUpload结束上传,同时请求成功后S3将会自动合并所有分片成为一个文件.

关于各个API的详细参数,请参考官方文档.

最后,我们需要注意的是,在整个客户端上传的过程中,难免会有分片并没有全部上传完毕,或者没有最终成功调用了completeMultipartUpload的孤儿分片存在,而且随着时间的推移,这些孤儿分片也会越来越多,并且这些没有被S3合并的分片,在S3的管理控制台中是不可见的,那么我们的最佳实践应该是怎样的呢? 首先我们可以使用abortMultipartUpload来取消分片,那么某一次上传没有完成合并的分片将会被清除, 这个可以结合API来配合使用.

其次,虽然S3控制台中并不会显示未上传完成的孤儿分片,但是我们可以通过listMultipartUploads和listParts来查看未完成的分片有哪些.

最后,也是最自动的方法是我们可以使用S3的桶生命周期Policy来设置自动清除和保留未完成合并的孤儿分片的时间周期,让我们并不需要花精力来处理这些异常的情况.

总结

S3作为轻量简易高可用的存储,结合AWS的SDK,我们在通过临时证书的交互后可以轻易的实现安全的浏览器客户端直接分片断点续传到S3的功能,无论是借助于上层的S3上传API还是利用底层的createMultipartUpload实现方式,Javascript SDK都能够在各个层面给到开发人员灵活轻便的实现这些逻辑,从而让开发人员更专注在自身业务的开发工作中.

作者介绍

李磊
AWS解决方案架构师,负责基于AWS的云计算方案的架构设计,同时致力于AWS云服务在国内和全球的应用和推广。在大规模并发后台架构,电商系统,社交网络平台、互联网领域应用,DevOps以及Serverless无服务器架构等领域有着广泛的设计与实践经验。在加入AWS之前超过十年的开发和架构设计经验, 带领团队攻克各种技术挑战,总是希望站在技术的最前沿。

Amazon EBS弹性卷修改实践

简介

在应用飞速的更新换代、数据量高速增长的今天,AWS的客户对EC2的块存储需求是随时间而改变的,很可能会多次需求增加容量或改变性能特性。在当今的24×7(全天候不间断)操作模式下,服务器没有停机的余地。因此,客户希望在应用不离线或不影响正常操作的情况下进行更改。换句话说,我们的客户希望他们的EBS卷更有弹性!

在2017年2月13日,AWS全球推出了一个新的EBS功能,称为弹性卷(Elastic Volumes),并使其适用于当前所有EC2实例可生成的EBS卷。在2017年2月17日,AWS中国区可以使用这项新功能。通过这一项功能,可以在EBS卷正在使用时增加卷的大小,调整性能或更改卷类型,并能在这些更改生效之前继续使用应用程序等运行在EC2实例上的程序功能。这一新功能的更新将大大简化企业或个人用户的许多规划管理,可以通过简单的API调用来及时更改存储基础架构,取代传统的需要几周或几个月的配置周期。

使用场景

1. 卷类型更改。在项目初期,为了更快部署应用,您初步设置块存储使用通用SSD卷(General Purpose SSD volumes),在获得一些使用经验后,发现吞吐量优化卷(Throughput Optimized volumes)是更好的选择,这时您只需要更改卷的类型就能够轻松解决问题。

2. IOPS性能调整。假设您在IOPS卷中运行一个关系型数据库,并设置它处理正常范围内的数据读写,由于每个月最后几天数据读写突增到正常水平的10倍,您只需要通过弹性卷短时间内获取更强大的读写配置来处理每月最高的数据读写,然后回调至正常配置来处理正常范围内的数据读写。

3. 卷存储增加。您获取了一个卷使用警告,提示您当前使用存储空间超过90%,这时您可以增加卷的大小,并扩展文件系统来匹配,弹性卷将以完全自动化的方式处理请求而不用停止EC2实例。

适用范围

AWS全部区域,包括海外和中国北京区域。

修改限制

所有卷大小的修改只能增加卷的大小!为了保护所有EBS卷中的数据,弹性卷修改仅允许增加卷的大小。如果您想将当前卷大小改小,可以先通过数据迁移工具将EBS卷中的数据移动到较小的卷,再将原来的卷删除。

1. 通用SSD卷:卷大小最小为1GiB,最大为16384GiB(16TiB);IOPS性能无法修改,最小为100,最大为10000,在最大最小值范围内为卷大小的3倍(卷大小单位为GiB),IOPS超频可达到3000。

2. 预配置IOPS SSD (io1):卷大小最小为4GiB,最大为16384GiB;IOPS性能可以修改,最小为100,最大为20000,在最大最小值范围内最大可调整至卷大小的50倍(卷大小单位为GiB)。

3. Cold HDD (sc1):卷大小最小为500GiB,最大为16384GiB;Cold HDD (sc1) 卷提供低成本的磁性存储,该存储以吞吐量而不是 IOPS 定义性能。此处无法做任何更改。

4. 吞吐量优化卷:卷大小最小为500GiB,最大为16384GiB;吞吐量优化卷提供低成本的磁性存储,该存储以吞吐量而不是IOPS定义性能。

5. 旧版磁介质卷:无法修改。磁介质是上一代卷。对于新应用程序,我们建议使用较新的卷类型。

数据截至至2017年2月17日,具体数据以AWS实时数据为准。更多有关EBS卷的相关信息,请查阅Amazon EBS卷类型

操作指南

您能通过AWS管理控制台、API调用或从AWS命令行界面(CLI)管理使用所有功能。下面将介绍AWS管理控制台对弹性卷修改的操作指南,获取更多API调用及命令行界面的操作方式,请访问AWS文档

修改本身不收取任何费用,您只需按实际使用量付费。更多定价信息,请访问EBS定价

一、引导卷(根分区)修改

登陆AWS中国区,并选择服务EC2,打开EC2面板后,鼠标左击点选左侧导航栏的“卷”。

打开卷面板后,选择您要调整的卷,点选“操作”打开下拉菜单,在下拉菜单中点选“Modify Volume”。

然后可以对卷类型、大小和预配置的IOPS(如果适用的话)进行任何符合需求的更改,修改检查完后,点击Modify按钮。

注意卷大小不能减小

注意预配置IOPS SSD卷的IOPS值不能大于卷大小的50倍(卷大小单位GiB)

在修改确认页面点击“Yes”按钮。

卷修改正在进行,请稍等一会儿。

卷修改完成。

卷修改验证。

二、未绑定到EC2实例卷修改

三、已绑定到EC2实例卷(未建立文件系统使用)修改

四、已绑定EC2到实例卷(建立文件系统并正在使用)修改

应用卷修改前。

应用卷修改后。

注意,卷的大小修改后,下一步是扩展文件系统,以便可以利用额外的存储空间。要了解如何执行此操作,请阅读在Linux上扩展EBS卷的存储空间或在Windows上扩展EBS卷的存储空间

注意事项

1.   在某些情况下,卷需要与EC2实例分离或停止实例才能进行修改。如果您在尝试对EBS卷应用修改时遇到错误消息,或者如果要修改附加到上一代实例类型的EBS卷,请执行以下步骤之一:

  • 对于非引导卷,先将卷从实例中分离,再应用修改,最后重新附加卷。
  • 对于引导卷,先停止实例,再应用修改,最后重新启动实例。

2.   弹性卷修改方法不支持上一代磁性卷。但是,您可以通过拍摄快照,并将快照还原到其他配置的EBS卷。

3.   不支持减小EBS卷的大小。但是,您可以通过创建较小的卷,利用应用程序级工具(如robocopy)进行数据转移。

4.   修改卷后,您需要等待至少六个小时,才能再对同一卷进一步更改,建议修改属性的时候,类型,IOPS,大小参数一次性完整设定。

5.   许多Linux AMI如今使用MBR方案,它只支持最多2047GiB的引导卷。如果您的实例未使用2TiB或更大的引导卷进行引导,则引导卷的大小被限制为2047GiB。

6.   在2016年11月1日之前附加到当前生成实例的卷需要执行以下操作之一,来初始化修改支持(这是一次性要求):

  • 停止并重新启动实例(重启前请一定备份卷数据!)。
  • 分离并重新附加卷。

7.   m3.medium实例被视为当前一代。m3.large,m3.xlarge和m3.2xl实例被视为上一代。更多有关上一代实例的内容,请参考实例类型

引导卷(根分区)操作实践:


卷修改前检查:

1.  确保最近一次卷修改在6小时之前。

2.  确认卷类型,如果为上一代磁性卷,您无法修改卷的类型及大小。您可以先将磁性卷中的数据拍摄快照并迁移至其余四种卷类型,再做更改。

3.  确认实例类型,如果为上一代实例,请先分离卷(非引导卷)或停止实例(引导卷)后再进行卷修改。

4.  确认实例上一次停止时间,如果在2016年11月1日之前,请先分离卷(非引导卷)或停止实例(引导卷)后再进行卷修改。

5.  一次性完整设定需要修改的卷类型,IOPS,大小参数,并等待卷修改完成。

参考

Amazon EBS Update–New Elastic Volumes Change Everything

作者介绍:

王元恺

AWS实习解决方案架构师,上海交通大学学生,有数年C++程序开发以及一年PHP前后端开发经验,同时致力于AWS云服务在国内的应用和推广。熟悉网站架设与网络应用开发,对于TCP/IP及网络协议有自己的理解和实践经验。