写点什么

AWS 系列:S3 不仅仅是存储

  • 2015-12-21
  • 本文字数:5195 字

    阅读完需:约 17 分钟

编者按:本文系 InfoQ 中文站向陈天的约稿,这是 AWS 系列文章的第二篇。以后会有更多文章刊出,但并无前后依赖的关系,每篇都自成一体。读者若要跟随文章来学习 AWS,应该至少注册了一个 AWS 账号,事先阅读过当期所介绍服务的简介,并在 AWS management console 中尝试使用过该服务。否则,阅读的效果不会太好。在这篇文章里,介绍了尝试用 S3 创建公司内部的文件服务器,保存员工私人 / 共享文件,并以类似 Dropbox 的方式双向同步。

S3 介绍

S3 是 AWS 最早发布的诸多服务之一,用作可信存储。所谓可信,AWS 给出的概念是:「在指定年度内为对象提供 99.999999999% 的持久性和高达 99.99% 的可用性」,换句话说就是任何存储于 S3 的数据基本不可能丢失,在一个年度内,不超过 1 小时(3153.6s)的宕机时间。除此之外,S3 还提供如下特性:

  • 跨区域复制:只需要简单的配置,存储于 S3 中的数据会自动复制到选定的不同区域中。当你的数据对象的收集分散在不同的区域,而处理集中在某些区域时非常有用。
  • 事件通知:当数据对象上传到 Amazon S3 中或从中删除的时候会发送事件通知。事件通知可使用 SQS 或 SNS 进行传送,也可以直接发送到 AWS Lambda 进行处理。比如说,上传到 S3 的图片的 resize。
  • 版本控制:数据对象可以启用版本控制,这样你就可以很方便地进行回滚。对于应用开发者来说,这是个特别有用的特性。
  • 加密:S3 的访问本身是支持 SSL(HTTPS)的,保证传输的安全,对于数据本身,你可以通过 Server side encryption(AES256)来加密存储在 S3 的数据。
  • 访问管理:通过 IAM/VPC 可以控制 S3 的访问粒度,你甚至可以控制一个 bucket(S3 对数据的管理单元,一个 bucket 类似于一组数据的根目录)里面的每个 folder,甚至每个文件的访问权限。
  • 可编程:可以使用 AWS SDK 进行客户端或者服务端的开发。
  • 成本监控和控制:S3 有几项管理和控制成本的功能,包括管理成本分配的添加存储桶标签和接收账单警报的 Amazon Cloud Watch 集成。
  • 灵活的存储选项:除了 S3 Standard,还有低成本的 Standard – Infrequent Access 选项可用于非频繁访问数据,存储的价格大概是 Standard 的 2/5。至于那些访问不了多少次的冷数据(如 1 年前的 Log),可以存储在 Glacier 中,价格在 Standard 的 1/4(1T $7/ 月),缺点是需要几个小时来恢复数据(估计是存放于离线的磁带中)。

基本用法

S3 的用户可以使用 AWS management console 来创建 bucket(类比文件系统的根目录),以及 bucket 内部的目录树,并上传文件,但这不是使用 S3 的最佳方式。日常的主要操作应该使用 AWS CLI 和 AWS SDK 完成。

AWS CLI

安装 AWS CLI 可以使用 pip / brew 等安装工具,不再详述。AWS CLI 是 AWS 官方提供的 CLI 工具,简单好用,我会另行撰文深度介绍 AWS CLI。AWS CLI 目前不支持命令和参数的自动补全,从 AWS re:invent 2015 透露出来的信息,其团队在做一些自动补全的尝试,未来会变得更加人性化。如果你想现在就用得更舒服一些,可以使用 sAws

使用 AWS CLI 操作 S3 非常简单,创建 / 删除 bucket 可以使用 aws s3api

复制代码
$ aws s3api create-bucket --bucket <name>
$ aws s3api delete-bucket --bucket <name>

如果要像一般的文件系统一样操作 S3,可以使用 aws s3 命令:

复制代码
$ aws s3 ls
$ aws s3 cp
$ aws s3 rm

此外,aws s3 还提供了 sync,方便本地文件和 S3 上的文件互相 sync,比如我本地用 pandoc 编译出了 markdown 撰写的 reveal.js 的 slides,可以这样同步到 S3:

$ aws s3 sync ./output s3://eng-assets/slides### AWS SDK

AWS SDK 提供了对几乎所有主流语言的支持,在程序里使用 S3,一般的流程是:

  • 创建 AWS connection(这一步需要用到你的 access key)。
  • 使用 connection 创建 S3 对象。
  • 使用 S3 API 进行各种 API 操作,比如创建 bucket,上传文件等。

这里列一个 JavaScript 的例子:

复制代码
const aws = require('aws-sdk');
const Promise = require("bluebird");
const s3 = Promise.promisifyAll(new aws.S3());
s3.createBucketAsync({Bucket: 'test-myBucket'}).then(function() {
var params = {Bucket: 'test-myBucket', Key: 'myKey', Body: 'Hello!'};
s3.putObjectAsync(params).then(function(data) {
console.log('successfully uploaded data');
}).error(function(err) {
console.log(err);
})
});

使用 S3 的典型场景

S3 的一些典型使用场景如下:

  • 存储用户上传的文件,如头像,照片,视频等静态内容。
  • 当作一个的 key value store,承担简单的数据库服务功能。
  • 数据备份。
  • 静态网站的托管:你可以对一个 bucket 使能 Web Hosting。

我们简单介绍一下 S3 实现静态网站托管,然后以一个例子讲述如何使用 S3 实现一个能最大程度保证数据安全同时又价格低廉的团队内部的文件服务器。

使用 S3 实现安全的静态网站托管

经常使用 GitHub 的朋友对 GitHub pages 服务一定不会陌生,你只要把各种静态网站生成工具的生成的目标放入 gh-pages 的 branch,GitHub pages 就会帮你做静态网站的托管。得益于如今越来越强大的 JavaScript 和各种 API,静态网站其实早已脱离了展示 HTML 的基本范畴。

GitHub pages 有一个缺点就是,只要你使用,它就是开放的,无法变成一个私有网站,存放公司内部的私密文件。公司内部的一些私有内容,比如:

  • 使用 reveal.js 生成的 slides。
  • 使用 new relic 生成的各种嵌入式报表和图表。
  • 使用 JavaScript + AWS SDK 做的各种内部工具(由于 AWS SDK 提供了 JavaScript SDK,所以你可以用静态网站的方式访问数据库等服务,实现 server less 的效果)。

你无论如何都不会想将其暴露给外界。这个时候,GitHub pages 就不适用,我们可以使用 S3 Web Hosting + IAM policy 来完成。

使能 S3 Web Hosting 是件很简单的事情,只需在 AWS console 中,为对应的 bucket 打开这个选项即可,然后添加如下 IAM policy:

复制代码
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:AWS:s3:::team-assets/*"
}
]
}

S3 Web Hosting 会告诉你一个用于访问的域名,你也可将你自己的私有域名指定一个 CNAME 指向该域。这样配置下来,只要域名和要访问的文件夹没有暴露,文件内容就是安全的。适用于安全等级不高的内容。

如果需要更高的安全级别,可以配合 VPC + IAM policy。一般而言,使用 VPC 的用户,都会将 VPC 设置成私有网络(比如 10.0.0.x 的网络),然后在网络边界配置一台 VPN 服务器,用于内外网的交互。任何用户要访问内网,必须先接入 VPN。我们可以设置用于 Web Hosting 的 S3 的 bucket 的 IAM 仅允许 VPN 服务器的 IP 访问,如下:

复制代码
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:AWS:s3:::team-assets/*",
"Condition" : {
"IpAddress" : {
"aws:SourceIp" : ["5.5.5.5/32"]
}
}
}
]
}

那么,只用当用户接入 VPN 之后,才能访问 Web Hosting 的域名下的文件,进一步提高了安全性。当然,由于不是在路由层面控制访问,所以没办法防止 ip spoofing,还是有一些潜在风险的,不过风险不大(攻击者需要知道要访问的文件所在的域名和路径,并且知道仅允许哪个源 IP 访问,进而进行 IP spoofing,而公网上 IP spoofing 的难度很大,基本上所有的路由器都会做 reverse route check)。

使用 S3 实现文件服务器

很多公司都会为员工提供私人和共享的文件存储。比如作为一个用户,我可以把我的私人文件存放在:fileserver://home/tyrchen/* 下,把一些共享文件存放在 fileserver://public/tyrchen/* 下。为了能够安全的存储这些文件,公司的 IT 部门一般会使用昂贵的 SAN(Storage Area Network)来保证一定程度的 SLA(Service Level Agreement),同时,还要做各种各样的备份(和恢复)。如果我们使用 S3 来实现类似的文件服务器,其代价和未来的维护成本会小得多。此外,我们还可以做一些额外的开发,使得文件服务器的使用体验类似于 Dropbox。

大致的想法是这样的:

  • 新员工入职后会为其在 S3 上建立 home folder,用来保存重要的私人文件和共享文件。
  • 员工电脑的本地文件中会有一个目录 corp-fs-box,里面包含三个子目录:
    • private:存放任意文件,私有,会自动 sync 到私人目录,别人无法访问。
    • photos:存放各种媒体文件,公开,会自动 sync 到共享目录,并生成合适的尺寸放在供 Web 访问的 S3 bucket 中。
  • 员工只要在本地目录中存放文件,就会按照上述规则自动同步,类似 Dropbox。

解决思路:

  • 创建两个 S3 bucket:corp-fs-team 和 corp-fs-web。corp-fs-web 打开 Web Hosting 功能。
  • 使用 IAM policy 来设置 home folder 的权限。
  • 使用 aws s3sync 来同步文件夹:
    • 对本地 corp-fs-box/private 里的文件,同步到 S3://corp-fs-team/home/{AWS:username}/ 中。这个目录只有当前用户可以访问,其他用户不能访问。
    • 对本地 corp-fs-box/pub/photos 里的文件,同步到 S3:web//corp-fs-team/pub/photos 中。这个目录任何用户都可以访问并修改。
  • S3 配置 Events,使得对于 S3://corp-fs-team/pub/photos/{AWS:username}/ 的任何更新行为(添加 / 删除)都会触发 lambda 函数。
  • lambda 函数扫描上传的文件,如果是 *.jpg 或者 *.mp4 / *.mov,则将其进行 resize / transcoding 等处理,并将编译的结果放在 S3://corp-fs-web/pub/photos/{AWS:username}/* 下,供内网的用户浏览。

涉及的 IAM policy 如下:

复制代码
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowGroupToSeeBucketList",
"Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
"Effect": "Allow",
"Resource": ["arn:AWS:s3:::*"]
}, {
"Sid": "AllowRootLevelList",
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:AWS:s3:::corp-fs-team"],
"Condition": {
"StringEquals": {
"s3:prefix": ["", "home/"],
"s3:delimiter": ["/"]
}
}
}, {
"Sid": "AllowListForUserPrefix",
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:AWS:s3:::corp-fs-team"],
"Condition": {
"StringLike": {
"s3:prefix": ["home/${AWS:username}/*"]
}
}
}, {
"Sid": "AllowUserFullAccessToUserPrefix",
"Action": ["s3:*"],
"Effect": "Allow",
"Resource": [
"arn:AWS:s3:::corp-fs-team/home/${AWS:username}",
"arn:AWS:s3:::corp-fs-team/home/${AWS:username}/*"
]
}
]
}

以及访问 pub 目录的 IAM policy:

复制代码
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowPublicLevelList",
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:AWS:s3:::corp-fs-team-bucket"],
"Condition": {
"StringLike": {
"s3:prefix": ["pub/*"]
}
}
}, {
"Sid": "AllowUserFullAccessToPublicPrefix",
"Action": ["s3:*"],
"Effect": "Allow",
"Resource": [
"arn:AWS:s3:::corp-fs-team-bucket/pub",
"arn:AWS:s3:::corp-fs-team-bucket/pub/*"
]
}
]
}

具体的 lambda 函数不在本文讨论的范围之内。

除此之外,我们还需要一个类似于 Dropbox 的客户端软件来监控本地目录(S3 目录)的更改,以便在合适的时候进行同步。思路如下:

  • 客户端软件做成一个开机启动的 daemon。
  • 随时监控本地目录 corp-fs-box/* 和 S3 bucket 的修改,并按上述规则同步。

由于涉及的目录都是个人目录,不太会产生冲突(除非同一用户在多个 device 下载没有 sync 的前提下修改同一文件。所以在这里,为简单起见,我们可以不涉及到 diff / merge,简单遵循 last writer wins 进行处理就可以了。另外 S3 自带 versioning,也可以使能这一功能,保存历史版本,在冲突发生的时候,让用户选择。

小结

S3 是一个非常强大的文件服务,如果使用得当,可以带来非常大的收益,建议大家多多深入研究。AWS 的很多服务,如 Elastic Beanstalk,Elastic Transcoder,CloudFormation 实际上都在使用 S3 作为服务的关键一环。


感谢魏星对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群(已满),InfoQ 读者交流群(#2))。

2015-12-21 17:1718926

评论

发布
暂无评论
发现更多内容

NetCore配置文件使用全过程

happlyfox

520单身福利

hive交互的几种方式

五分钟学大数据

大数据 hive 5月日更

打破固有思维(十四)

Changing Lin

博睿数据多点开花,数据链DNA加速走进金融、医疗、政企行业

博睿数据

数据链DNA

并发王者课 - 青铜 2:峡谷笔记 - 简单认识Java中的线程

MetaThoughts

Java 后端 多线程 并发 王者并发课

IPFS与 Filecoin的区别是什么?

meio

IPFS Filecoin

SWOT分析模型

石云升

创业 战略 职场经验 5月日更

ArrayList vs LinkedList

ltc

ArrayList linkedlist

一款开源小工具,提升K8S资源管理幸福感!

Rancher

Flutter 混合开发基础

网易云信

flutter

指挥中心可视化研判分析系统搭建解决方案

一款优秀数据库中间件的不完全解析

Coder的技术之路

源码阅读 源码刨析 数据库中间件

从外包跳槽到大厂,我用了55天成功逆袭。

Java 程序员 架构 面试

亚马逊云科技宣布在上海设立生命健康行业数字化赋能中心

亚马逊云科技 (Amazon Web Services)

4月热搜:揭秘金融级人脸实名认证解决方案背后的技术硬货

百度大脑

百度

指挥中心可视化研判分析系统搭建解决方案

数字货币与加密货币、虚拟货币的区别

meio

比特币 数字货币 加密货币 虚拟货币

Flink的广播变量

大数据技术指南

大数据 flink 5月日更

BOE(京东方)亮相世界智能大会 创新科技强势发力智慧物联新赛道

DT极客

发布两小时,Github访问量破百万,阿里内部首次公布的 Java10W 字面经有多强?

Java 程序员 架构 面试

API网关才是大势所趋?SpringCloud Gateway保姆级入门教程

Zhendong

Java spring API 网关

区块链技术在数字农业领域的应用挑战

CECBC

5分钟速读之Rust权威指南(六)

wzx

rust

架构训练营模块 4 作业 - 江哲

江哲

HarmonyOS 的分布式技术,让小朋友爱上涂鸦

科技汇

【签约计划】试用期规则

InfoQ写作社区官方

签约计划 热门活动

夺魁!亚马逊云科技荣膺中国数据管理解决方案领导者!

亚马逊云科技 (Amazon Web Services)

2021年4月券商App行情刷新及交易体验评测报告

博睿数据

全面隔绝虚拟货币暴涨暴跌风险

CECBC

医疗数字化:区块链或成最强辅助

CECBC

医疗

比特币披萨节由来:11年前BTC首次在现实世界使用

meio

比特币

AWS系列:S3不仅仅是存储_服务革新_陈天_InfoQ精选文章