OSSC(Aliyun Open Storage Service C SDK)是我和实验室@王维同学在2012首届阿里云开发者大赛中的参赛项目(http://2012.aliyun.com),我们作品提交是在10月2号,但是11月8号才揭晓最终结果,所以剩下的半个月还要慢慢等吧。
从GIT的提交记录来看开发时间应该是2012-09-03 21:08:02首次提交,最终提交记录是在2012-10-02 23:14:46,刚好整整一个月时间,除了实验室导师的活需要完成,就只能零零散散的利用空余时间来完成OSSC。虽然时间很紧,不过还好完成了此次比赛的项目,从中也学到了很多东西。
下图是OSSC代码演进,总的代码(在GIT统计中包括第三方库,如压缩库LZ4,miniLZO,MD5等)大概接近4.6W行,除开第三发库,我们自己的代码大概在3.0W行左右。
下图是每个作者代码统计:
下图是活动统计:
下图是文件类型统计:
下图是代码提交时刻统计:
关于OSS
阿里云存储服务(Open Storage Service,简称 OSS),是阿里云对外提供的海量,安全,低成本,高可靠的云存储服务。 用户可以通过简单的 REST 接口,在任何时间、任何地点、任何互联网设备上进行上传和下载数据, 也可以使用WEB 页面对数据进行管理。同时,OSS 提供 Java、Python、PHP SDK,简化用户的编程。 基于 OSS,用户可以搭建出各种多媒体分享网站、网盘、个人企业数据备份等基于大规模数据的服务。 【摘自《OSS API 开放接口规范文档》】。
我们为OSS做了什么?
目前 OSSC 提供了 OSS 开放接口中所描述的所有功能, 特点包括:
- Bucket 所有操作,如创建 Bucket、删除 Bucket、获取某个 Bucket 访问权限、设置 Bucket 访问权限、获取所有 Bucket 信息、 获取 Bucket 中所有 Object 的信息。
- Object 所有操作,创建 Object(PUT),获取 Object,删除 Object,获取 Object 元信息,拷贝 Object,一次性删除多个 Object,另外,还在此基础上
实现了从文件上传 Object、从内存缓冲区上传 Object、下载 Object 至文件、下载 Object 至内存缓冲区、多线程断点续传上传大文件。 - Multipart Upload 操作,初始化 Multipart Upload、上传 Part、完成 Multipart 上传、终止 Multipart Upload、查看 Multipart Upload,查看正在上传的 Part。
- Object Group 操作,创建 Object Group,获取 Object Group,获取 Object Group 中的 Object List 信息、获取 Object Group 元信息,删除 Object Group。
OSS 文件压缩格式
我们为OSS设计了一种可支持多种实时压缩算法(如LZO, LZ4,LZF)的文件存储格式,并实现了LZO,LZ4两种压缩算法(今后可能支持更多)的文件和内存块的实时压缩上传和下载解压缩功能,用户在压缩上 传文件时需要指定压缩算法(目前只能指定OSS_LZ4, OSS_LZO),但是在下载解压缩时并不需要指定解压缩算法,OSSC会自动根据文件格式选择适当的解压缩算法对文件或内存块进行解压缩。
该压缩存储格式文件名称以.ossz结尾,但是不强制使用.ossz后缀,事实上,你可以使用任意文件名和后缀,OSSC会自动检查文件是否为合法 的压缩格式。 另外,我们为文件和内存块的实时压缩上传和下载解压缩分别提供了相应的API,我们建议压缩上传和下载API成对使用,即上传时如果采用压缩上传,下载最 好采用压缩下载的API进行文件下载,以免在下载解压缩时不必要的文件格式检查,更详细的原理可以参考《OSSC 实现原理》一节,或源码 src/util/oss_compression.c, src/util/oss_decompress 或 src/core/client_object_operation.c。
OSSC亮点
目前 OSSC 除了提供 OSS 开放接口中所描述的所有功能以外,还包括以下亮点:
- 多线程断点上传功能;
- 文件实时压缩上传和实时解压缩下载;
- 内存块实时压缩上传和实时解压缩下载;
- 简易的文件夹同步上传和同步下载功能。
- 注解:
- 由于在Get Object操作设置HTTP的Range请求参数时会出现:"connection reset by peer",无法进行测试,所以多线程断点下载功能未经过测试,没有集成到代码库中。
OSSC安装细节
操作系统
OSSC 在 Ubuntu 12.04 上开发,我们测试了OSSC在不同Linux操作系统发行版的稳定性,以下是OSSC经过测试操作系统:
- Ubuntu 12.04, 11.10, 11.04, 10.10, 10.04
- CentOS 5.5
- Fedora 15, 16, 17
- openSUSE 12.2
- 注意:
- 目前我们没有在Windows上经过严格测试,虽然 OSSC 是标准C (C99) 写的,理论上也可以在 Windows 上编译运行,但是目前不建议在Windows系统下使用 OSSC,我们以后会对此改进。
OSSC依赖库
OSSC 采用 CURL 库处理 HTTP 请求,因此在编译 OSSC 之前你需要安装 CURL,CURL 源码中包含了C调用API,最新版 CURL下载地址:http://curl.haxx.se/libcurl/。 除此之外,OSSC 不依赖任何其他程序库。
CURL安装
本节介绍如何编译 CURL
- 下载 CURL,http://curl.haxx.se/download.html
- 安装 CURL,在Unix/Linux按照如下步骤,
$ ./configure $ make $ make test (optional) $ make install(需root用户权限)
- 完成依赖库安装后执行 ldconfig(需root用户权限)
OSSC编译步骤
本节介绍如何编译OSSC。
OSSC采用 CMake 管理构建过程,应该先安装CMake,
- 安装CMake。
- 创建 build 目录,进入到该目录,mkdir build && cd build
- 执行 cmake ../.
- 编译和安装 make && make install
- 注解:
- 如果需要设置编译选项,可以参考CMake文档,目前默认的编译模式为 Release,如果需要调试OSSC, 请将编译模式设置为Debug。
cmake -DCMAKE_INSTALL_PREFIX=/your-path ../.
在你的程序中使用OSSC
OSSC以程序库的形式提供给上层开发者使用,因此如果你想基于OSSC开发上层应用,必须链接OSSC程序库,OSSC大部分都集中到了 osscore 中,
只是支持多线程调用模式的API单独放在 ossextra库中(目前多线程只支持 pthread 线程库,后期会考虑在 Windows 下也支持多线程)
以下是你的程序需要连接OSSC,链接参数为:-L/path-to-your-ossc-installation -losscore.
另外需要注意的是,OSSC支持多线程断点续传模式下上传文件,如果你想体验该功能,你需要链接如下库: -L/path-to-your-ossc-installation -lossextra.
OSSC编码规范
一个优秀的项目必须遵循良好的编码规范,良好的编码风格可以促进团队协作,减少 BUG 产生几率,有助于开发后的代码审查,降低后期维护成本。
OSSC虽然只是我们在业余时间完成的小项目,但是也注重了编码风格的一致性,我们强烈建议那些希望基于OSSC做二次开发的编码人员阅读本规范, 相信本规范能够让你快速熟悉 OSSC 的整体结构和OSSC API 的使用方法。
OSSC实现原理
OSSC详细的实现原理请参考: OSSC实现原理
概括
OSSC(OSS-C-SDK)完全采用C语言开发,并实现了类似面向对象的调用方式,即“对象(struct
结构)”的“成员函数(函数指针)“采用函数指针形式实现,
我们尽量和OSS-JAVA的使用方式切合,每个对象都有相关的头文件和实现文件,并存放在modules目录下,其中与oss功能相关的所有的文件名均
以oss_为前缀,
每个文件实现了一个对象(即模块),另外,为了方便开发人员记忆,OSSC中的所有结构和函数我们采用如下命名;
- 类名(本文指代struct 结构)以 “oss_” 为前缀,并以 “_t” 为后缀,名字中间的单词用来标识该结构的用途,单词以下划线“_”连接,比如:包含终止一个Multipart上传事件的请求参数被命名为
oss_abort_multipart_upload_request_t,或者包含访问阿里云开放存储服务的入口“类”被命名为 oss_client_t,其他以此类推。 - 与各个类(struct 结构指针,以下均以“类”指代)对应的函数均以函数指针的形式调用(除了oss_client_t),比如oss_abort_multipart_upload_request_t中设置 Bucket 名称可以按照如下方式调用,
request->set_bucket_name(request,"bucket-name-001");
- 所有类对外均提供初始化函数和析构函数,其它与该类相关的操作均通过该类的函数指针调用,其中初始化函数命名规则为:该类的(BARE)类名(即 类名去掉“oss_”前缀和“_t”后缀)+initialize, 析构函数为该类的(BARE)类名(即类名去掉“oss_”前缀和“_t”后缀)+finalize。
- 访问阿里云开放存储服务(Open Storage Service, OSS)的入口“类”是 oss_client_t,与此对应的所有函数均以client_前缀开头,并且第一个参数都是指向client结构的指针。
比如上传一个对象,你需要定义标识上传对象的请求结构(oss_put_object_request_t *request)和
上传对象之后返回信息的结构(oss_put_object_result_t *result),然后将request作为参数传递给上传对象函数中(client_put_object_from_file()
或者client_put_object()中),最后返回值会保存在result指针所指向的结构中。
下面的代码概括了使用 OSSC 的步骤(单线程上传文件示例):
const char *access_id = "ACSGmv9fkV1TDO9L";// Access ID const char *access_key = "BedoWbsje2"; // Access key const char *bucket_name = "bucketname001"; //Bucket 名称 const char *key = "put-test.data"; // Key, Object 名称 FILE *file = fopen("proactor.pdf", "r"); //打开需要上传的文件 unsigned short retcode = 0; //设置返回码,关于返回码的定义将在后文中详细介绍 oss_client_t *client = client_initialize(access_id, access_key); // 初始化 oss_client_t *clien oss_object_metadata_t *metadata = object_metadata_initialize(); // 初始化 oss_object_metadata_t *metadata metadata->set_content_length(metadata, file_len); // 设置 metadata 元信息 metadata->set_content_type(metadata, "application/octet-stream"); // 设置 metadata 元信息 client_put_object_from_file(client, bucket_name, key, file, metadata, &retcode);// 核心操作:调用上传对象API client_finalize(client); //使用以后程序退出时需要释放 oss_client_t *client 分配的空间
OSSC高级模块Extra库
OSSC 高级模块中包含了多线程上传大文件的 API,并支持断点续传,由于时间和精力有限,我们目前并没有实现 Windows 平台的多线程上传下载功能, 希望今后会有其他开发者实现这一功能。
另外 Extra 库还支持简单的文件夹上传同步和下载同步的功能,希望该API对其他开发者有用。
OSSC 采用了POSIX多线程标准库 pthread,理论上只要你的操作系统支持 pthread都可以使用 OSSC 的 extra 库中的 API。
API使用示例
关于OSSC授权
OSSC 使用的开源程序:
- GNUlib 中的 base64, sha1, hmac-sha1等模块,并进行了适当改造。
- CCAN 的 ttxml,一个极简单的 xml 文件只读库
- Glib 的 GString,进行了适当的改造,在此基础上实现了 tstring_t,一个类似 C++ 的 std::string实现
- UThash, A hash table for C structure, http://uthash.sourceforge.net/
- LZ4: http://code.google.com/p/lz4/
- miniLZO: http://www.oberhumer.com/opensource/lzo/
OSSC 采用 LGPL(GNU Lesser General Public License:GNU 宽通用公共许可证)授权形式发布,有关 LGPL 可以查阅 GNU 官方文档: http://www.gnu.org/licenses/lgpl.html
关于作者
傅海平:中国科学院计算技术研究所网络数据中心(haipingf@gmail.com)
王 维:中国科院学计算技术研究所网络数据中心(wangwei881116@gmail.com)