AWS已在中国落地!详情请猛击此处


S3是AWS中的存储服务,为用户随时随地存储和访问大量数据提供了Web service接口,为开发者提供了一种可以快速低廉访问数据存储的服务。并且,开发者可以利用s3实现ec2访问大量的数据资源。其价格低廉,受到了广泛开发者的青睐。


s3中均是以bucket,key来区分数据,类似与文件系统中的文件夹,文件的概念。有所不同的是,s3中没有文件系统中的层级关系,只有bucket-key两层,key保存在指定的bucket中。当然key的名称可以自己定义,你可以将‘/'添加在key名字中(如'dir1/dir2/file'),以作为子文件夹,但s3并不会将其视为文件夹的层级结构,在查看bucket的key时,返回的结果也不会考虑。


既然是Web service,那么其使用方式就是set_contents_from_file非常简单的,不外乎两种形式,一种是用AWS的command line工具(cli),另一种是aws利用各种开发语言的sdk进行数据的存储、访问、修改。下面分别简单介绍cli和aws在python中的sdk boto中,s3的使用方法。


1. cli

在这里我们假设已经配置好cli的key,关于配置可以参看此文

与shell风格类似地,cli提供了以下几种对s3的方法:

单个文件操作:
cp, mv, rm (single local file and s3 object operations)
文件夹相关操作:

sync, mb, rb, ls (directory and s3 prefix operations)

其中,对于文件夹操作,可以利用--recursive和--exclude实现文件夹的递归操作以及过滤操作。

查看当前帐户中的所有buckets

$ aws s3 ls
$ aws s3 ls s3://mybucket


When you may need to specify the region of the bucket

$ aws s3 rm s3://mybucket --recursive --region us-east-1


# Uploading local files onto s3

$ aws s3 cp myfolder s3://mybucket/myfolder --recursive


# A sync command makes it easy to synchronize the contents of a local folder with a copy in an S3 bucket.

$ aws s3 sync myfolder s3://mybucket/myfolder --exclude *.tmp


You can also get help with the command:

$ aws s3 help


2.boto

在这里我们假设已经配置好boto的key,关于配置可以参看此文

1)创建s3的连接:

conn=S3Connection(access_key_id, secret_key)

2)创建bucket:

bucket=conn.create_bucket(bucket_name, headers=None, location='', policy=None)

你需要注意你的bucket_name的设置,可以将其考虑成域名的格式,使用period(.)进行层级划分,关于bucket_name设置的规则请猛击这里


你可以通过设置location来安排你上传的位置,默认是us-east-1,其他位置如下:

class boto.s3.connection.LocationAPNortheast = 'ap-northeast-1'
APSoutheast = 'ap-southeast-1'
APSoutheast2 = 'ap-southeast-2'
CNNorth1 = 'cn-north-1'
DEFAULT = ''
EU = 'EU'
SAEast = 'sa-east-1'
USWest = 'us-west-1'
USWest2 = 'us-west-2'

       需要注意的是,在创建bucket你有可能遇到

       创建bucket时你有可能会遇到S3CreateError的异常,返回BucketAlreadExists的错误,这是由于在s3中所有用户的bucket都放在同一层,如果你创建的bucket名称比较常见,如test,则很有可能已被其他用户使用,从而出现该问题。

       在boto的reference文档中提到了这一点,原文如下

"Well, the thing you have to know aboutbuckets is that they are kind of like domain names.  It’s one flat namespace that everyone who uses S3 shares.  So, someone has already createa bucket called “mybucket” in S3 and that means no one else can grab that bucket name.  So, you have to come up with a name that hasn’t been taken yet.For example, something that uses a unique string as a prefix.  YourAWS_ACCESS_KEY (NOT YOUR SECRET KEY!) could work but I’ll leave it toyour imagination to come up with something.  I’ll just assume that youfound an acceptable name."


3)设置bucket的访问控制规则:

bucket.set_acl('public-read')

4)写入key:

key=bucket.new_key(file_path)
key.set_contents_from_filename(os.path.join(dir_path, file_path))

或者使用set_contents_from_file


5)读取所有的key

for bucket in conn.get_all_buckets():
    for key in bucket.get_all_keys():
        print bucket, key.key, key.md5


需要注意的是get_all_buckets()函數是一个底层的实现,其一次最多返回1000个key(one paging of results),因此在实际中可以使用以下方式

for key in [key for key in bucket]:
    key.get_contents_to_filename(local_file_path)


更多关于boto操作s3,可以参看boto的reference

http://boto.readthedocs.org/en/latest/ref/s3.html


后面我还会介绍如何使用boto操作ec2,并在ec2上构建、配置自己的hadoop平台,敬请关注!