精华内容
下载资源
问答
  • 支持隐私保护的云存储框架设计,支持隐私保护的云存储框架设计
  • 针对云存储中的隐私安全问题,设计了一个支持隐私保护的、高效且安全的云存储框架.该框架采用多叉树结构构建数据索引,设计密钥推导算法EKDA(Extirpation-BasedKcyDerivationAlogrithm)实现密钥的管理和分发,构建...
  • 主要介绍了Python Web框架Flask中使用新浪SAE云存储实例,本文是对SAE云存储的简单封装,需要的朋友可以参考下
  • 主要介绍了Python Web框架Flask中使用百度云存储BCS实例,本文调用了百度云存储Python SDK中的相关类,需要的朋友可以参考下
  • 随着数据爆炸性增长,传统的存储方式已经不再满足海量数据的存储需求,云存储技术的飞速发展,使得云存储成为了一种新型的数据存储解决方案。文章在分析Hadoop分布式文件系统HDFS的基础上,提出了一种新的基于云计算...
  • ThinkCMF框架集成阿里云存储

    千次阅读 2018-01-26 09:23:53
    1:首先,需要两个关于阿里云存储的文件,Aliyun.zip,Aliyun.class.php文件,地址如下: https://pan.baidu.com/s/1eTdxuSU 密码:cpxt 将压缩包文件解压后,将两个文件上传于/simplewind/Core/Library/Think/...

    1:首先,需要两个关于阿里云存储的文件,Aliyun.zip,Aliyun.class.php文件,地址如下:

    https://pan.baidu.com/s/1eTdxuSU  密码:cpxt

    将压缩包文件解压后,将两个文件上传于/simplewind/Core/Library/Think/Upload/Driver目录下

    注意截图中 地址拼接的时候前面不要带http://  因为后台配置文件中填写的时候写上http就可以。

     

    2:后台文件存储修改:将index.html文件上传到/themes/simplebootx/Admin/Storage 中,将阿里云存储的信息配置好保存即可。

    信息填写时注意空间域名和服务器域名


    展开全文
  • 但是,当前大多数云存储系统都基于分布式哈希(DHT)构建数据索引,在该数据中,键值存储数据。 该模块不适用于多维数据索引中的范围查询。 为了解决这些问题,本文建立了基于跳过列表和八叉树结构的多维数据索引。...
  • #资源达人分享计划#
  • ROOT数据分析框架云存储扩展 概述 该软件是对 CERN 的数据分析框架的扩展。 其目的是帮助 ROOT 用户通过亚马逊的 S3 或 OpenStack 的 Swift 等云存储协议透明地读取远程(即“在云端”)存储的文件。 也就是说,...
  • 云存储是用于数据外包服务的灵活平台。 在这样的方案中,用户不再具有对其数据的物理控制。 结果,云存储服务的可靠性是用户的主要... 结果表明,该方法高效,安全,具有可支持复合云存储框架之间协同验证的显着特征。
  • 针对云计算中数据存储安全问题,构建了一种基于多Agent系统架构的安全框架,该安全框架可以为数据中心的数据带来更好的保密性、可用性、正确性以及数据操作的协调性。通过对此框架安全性能的分析和实验测试,结果...
  • 云存储简介

    千次阅读 2017-01-24 22:57:42
    这其实是一篇读书笔记,内容摘录自《大规模分布式存储系统-原理解析与架构实战》第12章讲到的云存储概念,跟自己工作的内容比较相关,也有比较强烈的认同感。 一、云存储的概念 二、云存储技术 三、云平台整体架构 ...

           这其实是一篇读书笔记,内容摘录自《大规模分布式存储系统-原理解析与架构实战》第12章讲到的云存储概念,跟自己工作的内容比较相关,也有比较强烈的认同感。


    一、云存储的概念

    云存储是通过网络将大量普通存储设备构成的存储资源池中的存储和数据服务以统一的接口按需提供给授权用户。

    云存储属于云计算的底层支撑,它通过多种云存储技术的融合,将大量普通PC服务器构成的存储集群虚拟化为易扩展、弹性、透明、具有伸缩性的存储资源池,并将存储资源池按需分配给授权用户,授权用户即可以通过网络对存储资源池进行任意的访问和管理,并按使用付费。云存储将存储资源集中起来,并通过专门的软件进行自动管理,无需人为参与。用户可以动态使用存储资源,无需考虑数据分布,扩展性,自动容错等复杂的大规模存储系统技术细节,从而可以更加专注于自己的业务,有利于提高效率,降低成本和技术创新。云存储具有如下特点:

    >超大规模:云存储具有相当的规模,单个系统存储的数据可以到达千亿级别,甚至万亿级。

    >高可扩展性:第一,系统本身可以很容易动态增加服务器资源以应对数据增长;第二,系统运维可扩展,意味着随着系统规模的增加,不需要增加太多运维人员。

    >高可用性和可用性:通过多副本复制以及节点故障自动容错等技术,云存储提供了很高的可用性和可靠性。

    >安全:云存储内部通过用户鉴权,访问权限控制,安全通信(HTTPS,TLS协议)等方式保障安全性。

    >透明服务:云存储以统一的接口,比如RESTFUL接口的形式提供服务,后端存储节点的变化,比如增加节点,节点故障对用户是透明的。

    >自动容错:云存储能够自动处理节点故障,从而实现运维可扩展,保证高可靠性和高可用性。

    >低成本:低成本是云存储的重要目标。云存储的自动容错使得可以采用普通的PC服务端来构建;云存储的通用性使得资源利用率大幅提升;云存储的自动化管理使得运维成本大幅降低;云存储所在的数据中心可以建在电力资源丰富的地区,从而大幅降低能源成本。


    二、云存储技术

    云存储包含两个部分:云端 + 终端。云端指统一的云存储服务端,终端指多样化的PC机,手机,移动多媒体设备等终端设备。云存储的发展需要云端和终端里面的多种技术的支持。

    云存储系统由多个存储设备构成,不同存储设备之间需要通过分布式存储,CDN、P2P等分布式技术,实现多个存储设备之间的协同工作,使多个存储设备可以对外提供同一种服务,并提供更好的数据访问性能。如果没有这些技术,存储系统只能是一个一个独立的系统,不能形成云状结构,也就没有云存储。另外,CDN(Content Delivery Network)以及P2P等技术保证云中的图片视频等文件能够被快速访问,并且节约云存储服务提供商的带宽成本。


    三、云平台整体架构

    云存储是云计算的存储部分,理解云存储架构的前提是理解云平台整体架构。云计算按照服务类型大致可以分为三类:基础设施即服务(Iaas)、平台即服务(PasS)以及软件即服务(SaaS):

    IaaS将硬件设备等基础资源以虚拟机的形式封装成服务供用户使用,如Amazon云计算AWS(Amazon Web Service)的弹性计算云EC2,PaaS进一步抽象硬件资源,提供用户应用程序的运行环境,开发者只需要将应用程序提交给PaaS平台,PaaS平台会自动完成程序部署,处理服务器故障,扩容等问题,典型的如(Google App Engine)GAE。SaaS的针对性更强,它将某些特定应用软件封装成服务。


    四、云平台架构

    从托管Web应用程序的角度看,云平台主要包括云存储以及应用运行平台,如下图所示:


    云平台的核心组件包括:云存储组件和应用运行平台组件。

    (1)云存储组件

    云存储组件包括两层:分布式存储层以及存储访问层。

    分布式存储层管理存储服务器集群,实现各个存储设备之间的协同工作,保证数据可靠性,对外屏蔽数据所在位置,数据迁移,数据复制,机器增减等变化,是的整个分布式系统看起来像是一台服务器。分布式存储层是云存储系统的核心,也是整个云存储平台中最难实现的部分。CDN节点将云存储系统中的热点数据缓存到离用户最近的位置,从而减少用户的访问延时并节约带宽。

    存储访问层位于分布式存储层的上一层,该层的主要作用是将分布式存储层的客户端接口封装为WebService(基于RESTful等协议)服务,另外,该层通过调用公共服务实现用户认证,权限管理以及计费等功能。存储访问层不是必须的,云存储平台中的计算实例也可以直接铜鼓哦客户端API访问分布式存储层中的存储系统。

    (2)应用运行平台组件

    应用运行平台的主体为计算实例(笔者理解为就是所谓的虚机或者物理机),计算实例最主要的功能有两个:开发者的应用程序运行环境以及离线任务处理。

    多个计算实例构成一个计算实例组,当实例组中的某个实例出现故障时,能够自动将负载迁移到其他的实例,并且支持动态增加或者减少实例从而使得实例组的处理能力具有动态可伸缩性。运行平台的最前端是路由以及负载均衡(LVS等)组件,它将用户的请求按照一定的策略发送到适合的计算实例。

    云存储平台还包含一些公共服务,这些基础服务由云存储组件以及运行平台组件所公用,如下所示:

    >消息服务:消息服务将执行流程异步化,用于应用程序解耦。计算实例一般分为处理Web请求的前台实例以及处理离线任务的后台实例,在很多情况下,前台实例处理Web请求的过程中需要启动运行在后台的任务,这种需求可以通过消息服务(消息队列例如ActiveMQ)服务实现。

    >缓存服务:缓存服务用于存储云存储系统中的读多写少的热点数据,从而加速查询,减少对后端存储系统压力。大多数云存储平台提供Memcache服务。

    >用户管理:用户管理主要功能是用户身份认证,确保用户的身份合法,并存储用户相关的个人信息。云计算平台一般支持单点登录,在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的系统。

    >运维管理:云存储平台的运维需要做到自动化,从而降低运维成本,一般来说,有一套专门的Web运维系统用于系统上下线,批量升级系统程序版本等。

    >监控系统:监控系统由两个层面,其一是资源层面,即资源的运行情况,比如CPU使用率、内存使用率和网络带宽利用率,Load值等,需要注意的是,云计算平台除了监控物理机资源,还需要监控虚拟机资源的运行情况;其二是应用层面,主要记录应用每次请求的响应时间、读写请求数等。

    还有权限管理,安全服务,计费服务,资源管理等。


    五、云存储技术体系

    云存储设计的知识面很广,既涉及云存储服务端的技术,又涉及终端设备应用开发相关的技术。


    。。。图片太大,只能横着看了。以上是云存储技术体系,找到了方向,如果能都搞通,差不多就成神了。

    云存储技术体系结构分为四层:硬件层、单机存储层、分布式存储层、存储访问层,前面有介绍就不啰嗦了。

    用户的应用程序可能会托管在应用运行平台中,应用场景大致分为三类:

    >弹性计算平台:典型的弹性计算平台为Amazon EC2以及MS的各种虚拟机实例,底层设计的技术包括虚拟机、自动伸缩。弹性计算平台通过虚拟机自身的机制来保证云安全,比如虚拟机安全隔离,虚拟机防火墙。基于虚拟机的弹性计算平台的优势在于兼容性,支持各种编程语言和平台。

    >云引擎:典型的云引擎为Google APP Engine,底层设计的涉及的技术主要是应用容器(比如Java Tomcat,Jetty,Python Runtime)以及应用容器自动伸缩。当应用的负载过高时,自动增加应用的运行容器数;反之,自动减少应用的运行容器数。

    >分布式计算:云平台往往会支持分布式计算,通过后台的计算实例执行耗时较长的计算任务。MapReduce是最为常见的分布式计算模型,云平台一般都支持开源的Hadoop MapReduce计算框架。

    以上。


    Reference:

    《大规模分布式存储系统-原理解析与架构实战》






    展开全文
  • #资源达人分享计划#
  • 针对企业级用户面临文件和数据量的指数级增长,现有的文件存储设施不能适应业务增长问题,提出基于Hadoop构建企业私有云存储平台,通过采用Linux集群技术、分布式文件系统和云计算框架,实现海量数据存储和高速数据处理...
  • 存储访问框架

    千次阅读 2016-08-23 09:55:50
    存储访问框架 本文内容显示详细信息 概览控制流编写客户端应用编写自定义文档提供程序 关键类 DocumentsProviderDocumentsContract 视频 DevBytes:Android 4.4 存储访问框架:提供程序...

    存储访问框架

    Android 4.4(API 19 级)引入了存储访问框架 (SAF)。SAF 让用户能够在其所有首选文档存储提供程序中方便地浏览并打开文档、图像以及其他文件。 用户可以通过易用的标准 UI,以统一方式在所有应用和提供程序中浏览文件和访问最近使用的文件。

    云存储服务或本地存储服务可以通过实现封装其服务的 DocumentsProvider 参与此生态系统。只需几行代码,便可将需要访问提供程序文档的客户端应用与 SAF 集成。

    SAF 包括以下内容:

    • 文档提供程序—一种内容提供程序,允许存储服务(如 Google 云端硬盘)显示其管理的文件。文档提供程序作为 DocumentsProvider 类的子类实现。文档提供程序的架构基于传统文件层次结构,但其实际数据存储方式由您决定。Android 平台包括若干内置文档提供程序,如 Downloads、Images 和 Videos;
    • 客户端应用—一种自定义应用,它调用 ACTION_OPEN_DOCUMENT 和/或 ACTION_CREATE_DOCUMENT Intent 并接收文档提供程序返回的文件;
    • 选取器—一种系统 UI,允许用户访问所有满足客户端应用搜索条件的文档提供程序内的文档。

    SAF 提供的部分功能如下:

    • 允许用户浏览所有文档提供程序而不仅仅是单个应用中的内容;
    • 让您的应用获得对文档提供程序所拥有文档的长期、持久性访问权限。 用户可以通过此访问权限添加、编辑、保存和删除提供程序上的文件;
    • 支持多个用户帐户和临时根目录,如只有在插入驱动器后才会出现的 USB 存储提供程序。

    概览


    SAF 围绕的内容提供程序是 DocumentsProvider 类的一个子类。在文档提供程序内,数据结构采用传统的文件层次结构:

    data model

    图 1. 文档提供程序数据模型。根目录指向单个文档,后者随即启动整个结构树的扇出。

    请注意以下事项:

    • 每个文档提供程序都会报告一个或多个作为探索文档结构树起点的“根目录”。每个根目录都有一个唯一的 COLUMN_ROOT_ID,并且指向表示该根目录下内容的文档(目录)。根目录采用动态设计,以支持多个帐户、临时 USB 存储设备或用户登录/注销等用例;
    • 每个根目录下都有一个文档。该文档指向 1 至 N 个文档,而其中每个文档又可指向 1 至 N 个文档;
    • 每个存储后端都会通过使用唯一的 COLUMN_DOCUMENT_ID 引用各个文件和目录来显示它们。文档 ID 必须具有唯一性,一旦发放便不得更改,因为它们用于所有设备重启过程中的永久性 URI 授权;
    • 文档可以是可打开的文件(具有特定 MIME 类型)或包含附加文档的目录(具有 MIME_TYPE_DIR MIME 类型);
    • 每个文档都可以具有不同的功能,如 COLUMN_FLAGS 所述。例如,FLAG_SUPPORTS_WRITEFLAG_SUPPORTS_DELETE 和 FLAG_SUPPORTS_THUMBNAIL。多个目录中可以包含相同的 COLUMN_DOCUMENT_ID

    控制流


    如前文所述,文档提供程序数据模型基于传统文件层次结构。 不过,只要可以通过 DocumentsProvider API 访问数据,您实际上可以按照自己喜好的方式存储数据。例如,您可以使用基于标记的云存储来存储数据。

    图 2 中的示例展示的是照片应用如何利用 SAF 访问存储的数据:

    app

    图 2. 存储访问框架流

    请注意以下事项:

    • 在 SAF 中,提供程序和客户端并不直接交互。客户端请求与文件交互(即读取、编辑、创建或删除文件)的权限;
    • 交互在应用(在本示例中为照片应用)触发 Intent ACTION_OPEN_DOCUMENT 或 ACTION_CREATE_DOCUMENT 后开始。Intent 可能包括进一步细化条件的过滤器—例如,“为我提供所有 MIME 类型为‘图像’的可打开文件”;
    • Intent 触发后,系统选取器将检索每个已注册的提供程序,并向用户显示匹配的内容根目录;
    • 选取器会为用户提供一个标准的文档访问界面,但底层文档提供程序可能与其差异很大。 例如,图 2 显示了一个 Google 云端硬盘提供程序、一个 USB 提供程序和一个云提供程序。

    图 3 显示了一个选取器,一位搜索图像的用户在其中选择了一个 Google 云端硬盘帐户:

    picker

    图 3. 选取器

    当用户选择 Google 云端硬盘时,系统会显示图像,如图 4 所示。从这时起,用户就可以通过提供程序和客户端应用支持的任何方式与它们进行交互。

    picker

    图 4. 图像

    编写客户端应用


    对于 Android 4.3 及更低版本,如果您想让应用从其他应用中检索文件,它必须调用 ACTION_PICK 或 ACTION_GET_CONTENT 等 Intent。然后,用户必须选择一个要从中选取文件的应用,并且所选应用必须提供一个用户界面,以便用户浏览和选取可用文件。

    对于 Android 4.4 及更高版本,您还可以选择使用 ACTION_OPEN_DOCUMENT Intent,后者会显示一个由系统控制的选取器 UI,用户可以通过它浏览其他应用提供的所有文件。用户只需通过这一个 UI 便可从任何受支持的应用中选取文件。

    ACTION_OPEN_DOCUMENT 并非设计用于替代 ACTION_GET_CONTENT。应使用的 Intent 取决于应用的需要:

    • 如果您只想让应用读取/导入数据,请使用 ACTION_GET_CONTENT。使用此方法时,应用会导入数据(如图像文件)的副本;
    • 如果您想让应用获得对文档提供程序所拥有文档的长期、持久性访问权限,请使用 ACTION_OPEN_DOCUMENT。 例如,允许用户编辑存储在文档提供程序中的图像的照片编辑应用。

    本节描述如何编写基于 ACTION_OPEN_DOCUMENT 和 ACTION_CREATE_DOCUMENT Intent 的客户端应用。

    以下代码段使用 ACTION_OPEN_DOCUMENT 来搜索包含图像文件的文档提供程序:

    private static final int READ_REQUEST_CODE = 42;
    ...
    /**
     * Fires an intent to spin up the "file chooser" UI and select an image.
     */
    public void performFileSearch() {
    
        // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
        // browser.
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    
        // Filter to only show results that can be "opened", such as a
        // file (as opposed to a list of contacts or timezones)
        intent.addCategory(Intent.CATEGORY_OPENABLE);
    
        // Filter to show only images, using the image MIME data type.
        // If one wanted to search for ogg vorbis files, the type would be "audio/ogg".
        // To search for all documents available via installed storage providers,
        // it would be "*/*".
        intent.setType("image/*");
    
        startActivityForResult(intent, READ_REQUEST_CODE);
    }

    请注意以下事项:

    • 当应用触发 ACTION_OPEN_DOCUMENT Intent 时,后者会启动一个选取器来显示所有匹配的文档提供程序
    • 在 Intent 中添加类别 CATEGORY_OPENABLE 可对结果进行过滤,以仅显示可以打开的文档(如图像文件)
    • 语句 intent.setType("image/*") 可做进一步过滤,以仅显示 MIME 数据类型为图像的文档

    处理结果

    用户在选取器中选择文档后,系统就会调用 onActivityResult()。指向所选文档的 URI 包含在 resultData 参数中。使用 getData() 提取 URI。获得 URI 后,即可使用它来检索用户想要的文档。例如:

    @Override
    public void onActivityResult(int requestCode, int resultCode,
            Intent resultData) {
    
        // The ACTION_OPEN_DOCUMENT intent was sent with the request code
        // READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
        // response to some other intent, and the code below shouldn't run at all.
    
        if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
            // The document selected by the user won't be returned in the intent.
            // Instead, a URI to that document will be contained in the return intent
            // provided to this method as a parameter.
            // Pull that URI using resultData.getData().
            Uri uri = null;
            if (resultData != null) {
                uri = resultData.getData();
                Log.i(TAG, "Uri: " + uri.toString());
                showImage(uri);
            }
        }
    }

    检查文档元数据

    获得文档的 URI 后,即可获得对其元数据的访问权限。以下代码段用于获取 URI 所指定文档的元数据并将其记入日志:

    public void dumpImageMetaData(Uri uri) {
    
        // The query, since it only applies to a single document, will only return
        // one row. There's no need to filter, sort, or select fields, since we want
        // all fields for one document.
        Cursor cursor = getActivity().getContentResolver()
                .query(uri, null, null, null, null, null);
    
        try {
        // moveToFirst() returns false if the cursor has 0 rows.  Very handy for
        // "if there's anything to look at, look at it" conditionals.
            if (cursor != null && cursor.moveToFirst()) {
    
                // Note it's called "Display Name".  This is
                // provider-specific, and might not necessarily be the file name.
                String displayName = cursor.getString(
                        cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                Log.i(TAG, "Display Name: " + displayName);
    
                int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
                // If the size is unknown, the value stored is null.  But since an
                // int can't be null in Java, the behavior is implementation-specific,
                // which is just a fancy term for "unpredictable".  So as
                // a rule, check if it's null before assigning to an int.  This will
                // happen often:  The storage API allows for remote files, whose
                // size might not be locally known.
                String size = null;
                if (!cursor.isNull(sizeIndex)) {
                    // Technically the column stores an int, but cursor.getString()
                    // will do the conversion automatically.
                    size = cursor.getString(sizeIndex);
                } else {
                    size = "Unknown";
                }
                Log.i(TAG, "Size: " + size);
            }
        } finally {
            cursor.close();
        }
    }

    打开文档

    获得文档的 URI 后,即可打开文档或对其执行任何其他您想要执行的操作。

    位图

    以下示例展示了如何打开 Bitmap

    private Bitmap getBitmapFromUri(Uri uri) throws IOException {
        ParcelFileDescriptor parcelFileDescriptor =
                getContentResolver().openFileDescriptor(uri, "r");
        FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
        Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
        parcelFileDescriptor.close();
        return image;
    }

    请注意,您不应在 UI 线程上执行此操作。请使用 AsyncTask 在后台执行此操作。打开位图后,即可在 ImageView 中显示它。

    获取 InputStream

    以下示例展示了如何从 URI 中获取 InputStream。在此代码段中,系统将文件行读取到一个字符串中:

    private String readTextFromUri(Uri uri) throws IOException {
        InputStream inputStream = getContentResolver().openInputStream(uri);
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                inputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        fileInputStream.close();
        parcelFileDescriptor.close();
        return stringBuilder.toString();
    }

    创建新文档

    您的应用可以使用 ACTION_CREATE_DOCUMENT Intent 在文档提供程序中创建新文档。要想创建文件,请为您的 Intent 提供一个 MIME 类型和文件名,然后通过唯一的请求代码启动它。系统会为您执行其余操作:

    // Here are some examples of how you might call this method.
    // The first parameter is the MIME type, and the second parameter is the name
    // of the file you are creating:
    //
    // createFile("text/plain", "foobar.txt");
    // createFile("image/png", "mypicture.png");
    
    // Unique request code.
    private static final int WRITE_REQUEST_CODE = 43;
    ...
    private void createFile(String mimeType, String fileName) {
        Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
    
        // Filter to only show results that can be "opened", such as
        // a file (as opposed to a list of contacts or timezones).
        intent.addCategory(Intent.CATEGORY_OPENABLE);
    
        // Create a file with the requested MIME type.
        intent.setType(mimeType);
        intent.putExtra(Intent.EXTRA_TITLE, fileName);
        startActivityForResult(intent, WRITE_REQUEST_CODE);
    }

    创建新文档后,即可在 onActivityResult() 中获取其 URI,以便继续向其写入内容。

    删除文档

    如果您获得了文档的 URI,并且文档的 Document.COLUMN_FLAGS 包含 SUPPORTS_DELETE,便可以删除该文档。例如:

    DocumentsContract.deleteDocument(getContentResolver(), uri);

    编辑文档

    您可以使用 SAF 就地编辑文本文档。以下代码段会触发 ACTION_OPEN_DOCUMENT Intent 并使用类别 CATEGORY_OPENABLE 以仅显示可以打开的文档。它会进一步过滤以仅显示文本文件:

    private static final int EDIT_REQUEST_CODE = 44;
    /**
     * Open a file for writing and append some text to it.
     */
     private void editDocument() {
        // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's
        // file browser.
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    
        // Filter to only show results that can be "opened", such as a
        // file (as opposed to a list of contacts or timezones).
        intent.addCategory(Intent.CATEGORY_OPENABLE);
    
        // Filter to show only text files.
        intent.setType("text/plain");
    
        startActivityForResult(intent, EDIT_REQUEST_CODE);
    }

    接下来,您可以从 onActivityResult()(请参阅处理结果)调用代码以执行编辑。以下代码段可从 ContentResolver 获取 FileOutputStream。默认情况下,它使用“写入”模式。最佳做法是请求获得所需的最低限度访问权限,因此如果您只需要写入权限,就不要请求获得读取/写入权限。

    private void alterDocument(Uri uri) {
        try {
            ParcelFileDescriptor pfd = getActivity().getContentResolver().
                    openFileDescriptor(uri, "w");
            FileOutputStream fileOutputStream =
                    new FileOutputStream(pfd.getFileDescriptor());
            fileOutputStream.write(("Overwritten by MyCloud at " +
                    System.currentTimeMillis() + "\n").getBytes());
            // Let the document provider know you're done by closing the stream.
            fileOutputStream.close();
            pfd.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    保留权限

    当您的应用打开文件进行读取或写入时,系统会为您的应用提供针对该文件的 URI 授权。该授权将一直持续到用户设备重启时。但假定您的应用是图像编辑应用,而且您希望用户能够直接从应用中访问他们编辑的最后 5 张图像。如果用户的设备已经重启,您就需要将用户转回系统选取器以查找这些文件,这显然不是理想的做法。

    为防止出现这种情况,您可以保留系统为您的应用授予的权限。您的应用实际上是“获取”了系统提供的持久 URI 授权。这使用户能够通过您的应用持续访问文件,即使设备已重启也不受影响:

    final int takeFlags = intent.getFlags()
                & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    // Check for the freshest data.
    getContentResolver().takePersistableUriPermission(uri, takeFlags);

    还有最后一个步骤。您可能已经保存了应用最近访问的 URI,但它们可能不再有效—另一个应用可能已删除或修改了文档。 因此,您应该始终调用getContentResolver().takePersistableUriPermission() 以检查有无最新数据。

    编写自定义文档提供程序


    如果您要开发为文件提供存储服务(如云保存服务)的应用,可以通过编写自定义文档提供程序,通过 SAF 提供您的文件。本节描述如何执行此操作。

    清单文件

    要想实现自定义文档提供程序,请将以下内容添加到您的应用的清单文件:

    • 一个 API 19 级或更高级别的目标;
    • 一个声明自定义存储提供程序的 <provider> 元素;
    • 提供程序的名称(即其类名),包括软件包名称。例如:com.example.android.storageprovider.MyCloudProvider
    • 权限的名称,即您的软件包名称(在本例中为 com.example.android.storageprovider)加内容提供程序的类型 (documents)。例如,com.example.android.storageprovider.documents
    • 属性 android:exported 设置为 "true"。您必须导出提供程序,以便其他应用可以看到;
    • 属性 android:grantUriPermissions 设置为 "true"。此设置允许系统向其他应用授予对提供程序中内容的访问权限。 如需查看有关保留对特定文档授权的阐述,请参阅保留权限
    • MANAGE_DOCUMENTS 权限。默认情况下,提供程序对所有人可用。 添加此权限将限定您的提供程序只能供系统使用。此限制具有重要的安全意义;
    • android:enabled 属性设置为在资源文件中定义的一个布尔值。此属性的用途是,在运行 Android 4.3 或更低版本的设备上禁用提供程序。例如,android:enabled="@bool/atLeastKitKat"。除了在清单文件中加入此属性外,您还需要执行以下操作;
      • 在 res/values/ 下的 bool.xml 资源文件中,添加以下行
        <bool name="atLeastKitKat">false</bool>
      • 在 res/values-v19/ 下的 bool.xml 资源文件中,添加以下行
        <bool name="atLeastKitKat">true</bool>
    • 一个包括 android.content.action.DOCUMENTS_PROVIDER 操作的 Intent 过滤器,以便在系统搜索提供程序时让您的提供程序出现在选取器中。

    以下是从一个包括提供程序的示例清单文件中摘录的内容:

    <manifest... >
        ...
        <uses-sdk
            android:minSdkVersion="19"
            android:targetSdkVersion="19" />
            ....
            <provider
                android:name="com.example.android.storageprovider.MyCloudProvider"
                android:authorities="com.example.android.storageprovider.documents"
                android:grantUriPermissions="true"
                android:exported="true"
                android:permission="android.permission.MANAGE_DOCUMENTS"
                android:enabled="@bool/atLeastKitKat">
                <intent-filter>
                    <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
                </intent-filter>
            </provider>
        </application>
    
    </manifest>

    支持运行 Android 4.3 及更低版本的设备

    ACTION_OPEN_DOCUMENT Intent 仅可用于运行 Android 4.4 及更高版本的设备。如果您想让应用支持 ACTION_GET_CONTENT 以适应运行 Android 4.3 及更低版本的设备,则应在您的清单文件中为运行 Android 4.4 或更高版本的设备禁用 ACTION_GET_CONTENT Intent 过滤器。应将文档提供程序和ACTION_GET_CONTENT 视为具有互斥性。如果您同时支持这两者,您的应用将在系统选取器 UI 中出现两次,提供两种不同的方式来访问您存储的数据。这会给用户造成困惑。

    建议按照以下步骤为运行 Android 4.4 版或更高版本的设备禁用 ACTION_GET_CONTENT Intent 过滤器:

    1. 在 res/values/ 下的 bool.xml 资源文件中,添加以下行
      <bool name="atMostJellyBeanMR2">true</bool>
    2. 在 res/values-v19/ 下的 bool.xml 资源文件中,添加以下行
      <bool name="atMostJellyBeanMR2">false</bool>
    3. 添加一个Activity别名,为 4.4 版(API 19 级)或更高版本禁用 ACTION_GET_CONTENT Intent 过滤器。例如:
      <!-- This activity alias is added so that GET_CONTENT intent-filter
           can be disabled for builds on API level 19 and higher. -->
      <activity-alias android:name="com.android.example.app.MyPicker"
              android:targetActivity="com.android.example.app.MyActivity"
              ...
              android:enabled="@bool/atMostJellyBeanMR2">
          <intent-filter>
              <action android:name="android.intent.action.GET_CONTENT" />
              <category android:name="android.intent.category.OPENABLE" />
              <category android:name="android.intent.category.DEFAULT" />
              <data android:mimeType="image/*" />
              <data android:mimeType="video/*" />
          </intent-filter>
      </activity-alias>

    协定类

    通常,当您编写自定义内容提供程序时,其中一项任务是实现协定类,如内容提供程序开发者指南中所述。 协定类是一种 public final 类,它包含对 URI、列名称、MIME 类型以及其他与提供程序有关的元数据的常量定义。SAF 会为您提供这些协定类,因此您无需自行编写:

    例如,当系统在您的文档提供程序中查询文档或根目录时,您可能会在游标中返回以下列:

    private static final String[] DEFAULT_ROOT_PROJECTION =
            new String[]{Root.COLUMN_ROOT_ID, Root.COLUMN_MIME_TYPES,
            Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE,
            Root.COLUMN_SUMMARY, Root.COLUMN_DOCUMENT_ID,
            Root.COLUMN_AVAILABLE_BYTES,};
    private static final String[] DEFAULT_DOCUMENT_PROJECTION = new
            String[]{Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE,
            Document.COLUMN_DISPLAY_NAME, Document.COLUMN_LAST_MODIFIED,
            Document.COLUMN_FLAGS, Document.COLUMN_SIZE,};

    为 DocumentsProvider 创建子类

    编写自定义文档提供程序的下一步是为抽象类 DocumentsProvider 创建子类。您至少需要实现以下方法:

    这些只是您需要严格实现的方法,但您可能还想实现许多其他方法。 详情请参阅 DocumentsProvider

    实现 queryRoots

    您实现的 queryRoots() 必须使用在 DocumentsContract.Root 中定义的列返回一个指向文档提供程序所有根目录的 Cursor

    在以下代码段中,projection 参数表示调用方想要返回的特定字段。代码段会创建一个新游标,并为其添加一行—一个根目录,如 Downloads 或 Images 等顶层目录。大多数提供程序只有一个根目录。有时您可能有多个根目录,例如,当您具有多个用户帐户时。 在这种情况下,只需再为游标添加一行。

    @Override
    public Cursor queryRoots(String[] projection) throws FileNotFoundException {
    
        // Create a cursor with either the requested fields, or the default
        // projection if "projection" is null.
        final MatrixCursor result =
                new MatrixCursor(resolveRootProjection(projection));
    
        // If user is not logged in, return an empty root cursor.  This removes our
        // provider from the list entirely.
        if (!isUserLoggedIn()) {
            return result;
        }
    
        // It's possible to have multiple roots (e.g. for multiple accounts in the
        // same app) -- just add multiple cursor rows.
        // Construct one row for a root called "MyCloud".
        final MatrixCursor.RowBuilder row = result.newRow();
        row.add(Root.COLUMN_ROOT_ID, ROOT);
        row.add(Root.COLUMN_SUMMARY, getContext().getString(R.string.root_summary));
    
        // FLAG_SUPPORTS_CREATE means at least one directory under the root supports
        // creating documents. FLAG_SUPPORTS_RECENTS means your application's most
        // recently used documents will show up in the "Recents" category.
        // FLAG_SUPPORTS_SEARCH allows users to search all documents the application
        // shares.
        row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE |
                Root.FLAG_SUPPORTS_RECENTS |
                Root.FLAG_SUPPORTS_SEARCH);
    
        // COLUMN_TITLE is the root title (e.g. Gallery, Drive).
        row.add(Root.COLUMN_TITLE, getContext().getString(R.string.title));
    
        // This document id cannot change once it's shared.
        row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(mBaseDir));
    
        // The child MIME types are used to filter the roots and only present to the
        //  user roots that contain the desired type somewhere in their file hierarchy.
        row.add(Root.COLUMN_MIME_TYPES, getChildMimeTypes(mBaseDir));
        row.add(Root.COLUMN_AVAILABLE_BYTES, mBaseDir.getFreeSpace());
        row.add(Root.COLUMN_ICON, R.drawable.ic_launcher);
    
        return result;
    }

    实现 queryChildDocuments

    您实现的 queryChildDocuments() 必须使用在 DocumentsContract.Document 中定义的列返回一个指向指定目录中所有文件的 Cursor

    当您在选取器 UI 中选择应用时,系统会调用此方法。它会获取根目录下某个目录内的子文档。可以在文件层次结构的任何级别调用此方法,并非只能从根目录调用。 以下代码段可创建一个包含所请求列的新游标,然后向游标添加父目录中每个直接子目录的相关信息。子目录可以是图像、另一个目录乃至任何文件:

    @Override
    public Cursor queryChildDocuments(String parentDocumentId, String[] projection,
                                  String sortOrder) throws FileNotFoundException {
    
        final MatrixCursor result = new
                MatrixCursor(resolveDocumentProjection(projection));
        final File parent = getFileForDocId(parentDocumentId);
        for (File file : parent.listFiles()) {
            // Adds the file's display name, MIME type, size, and so on.
            includeFile(result, null, file);
        }
        return result;
    }

    实现 queryDocument

    您实现的 queryDocument() 必须使用在 DocumentsContract.Document 中定义的列返回一个指向指定文件的 Cursor

    除了特定文件的信息外,queryDocument() 方法返回的信息与 queryChildDocuments() 中传递的信息相同:

    @Override
    public Cursor queryDocument(String documentId, String[] projection) throws
            FileNotFoundException {
    
        // Create a cursor with the requested projection, or the default projection.
        final MatrixCursor result = new
                MatrixCursor(resolveDocumentProjection(projection));
        includeFile(result, documentId, null);
        return result;
    }

    实现 queryDocument

    您必须实现 openDocument() 以返回表示指定文件的 ParcelFileDescriptor。其他应用可以使用返回的 ParcelFileDescriptor 来流式传输数据。用户选择了文件,并且客户端应用通过调用 openFileDescriptor() 来请求对文件的访问权限,系统便会调用此方法。例如:

    @Override
    public ParcelFileDescriptor openDocument(final String documentId,
                                             final String mode,
                                             CancellationSignal signal) throws
            FileNotFoundException {
        Log.v(TAG, "openDocument, mode: " + mode);
        // It's OK to do network operations in this method to download the document,
        // as long as you periodically check the CancellationSignal. If you have an
        // extremely large file to transfer from the network, a better solution may
        // be pipes or sockets (see ParcelFileDescriptor for helper methods).
    
        final File file = getFileForDocId(documentId);
    
        final boolean isWrite = (mode.indexOf('w') != -1);
        if(isWrite) {
            // Attach a close listener if the document is opened in write mode.
            try {
                Handler handler = new Handler(getContext().getMainLooper());
                return ParcelFileDescriptor.open(file, accessMode, handler,
                            new ParcelFileDescriptor.OnCloseListener() {
                    @Override
                    public void onClose(IOException e) {
    
                        // Update the file with the cloud server. The client is done
                        // writing.
                        Log.i(TAG, "A file with id " +
                        documentId + " has been closed!
                        Time to " +
                        "update the server.");
                    }
    
                });
            } catch (IOException e) {
                throw new FileNotFoundException("Failed to open document with id "
                + documentId + " and mode " + mode);
            }
        } else {
            return ParcelFileDescriptor.open(file, accessMode);
        }
    }

    安全性

    假设您的文档提供程序是受密码保护的云存储服务,并且您想在开始共享用户的文件之前确保其已登录。如果用户未登录,您的应用应该执行哪些操作呢? 解决方案是在您实现的 queryRoots() 中返回零个根目录。也就是空的根目录游标:

    public Cursor queryRoots(String[] projection) throws FileNotFoundException {
    ...
        // If user is not logged in, return an empty root cursor.  This removes our
        // provider from the list entirely.
        if (!isUserLoggedIn()) {
            return result;
    }

    另一个步骤是调用 getContentResolver().notifyChange()。还记得 DocumentsContract 吗?我们将使用它来创建此 URI。以下代码段会在每次用户的登录状态发生变化时指示系统查询文档提供程序的根目录。 如果用户未登录,则调用 queryRoots() 会返回一个空游标,如上文所示。这可以确保只有在用户登录提供程序后其中的文档才可用。

    private void onLoginButtonClick() {
        loginOrLogout();
        getContentResolver().notifyChange(DocumentsContract
                .buildRootsUri(AUTHORITY), null);
    }
    展开全文
  • 为了保证云存储中用户数据和隐私的安全,提出了一种基于属性的安全增强云存储访问控制方案。通过共用属性集,将基于属性的加密体制(ABE)与XACML框架有机结合,在XACML框架上实现细粒度的基于属性的访问控制并由ABE...
  • 深度解析阿里云存储

    万次阅读 2017-08-31 18:41:06
    图1 2017年Gartner全球云存储魔力象限图在去年首次进入Gartner魔力象限即取得了不错的位置之后,今年阿里云存储再次强势进入公共云存储魔力象限,紧跟Google成为公共云存储厂商中在利基象限中最接近领导者象限的公共...

    国际知名调研机构Gartner近日公布了2017年全球云计算云存储魔力象限,阿里云的云存储强势崛起成为这一核心领域的前四名。

    图片描述
    图1 2017年Gartner全球云存储魔力象限图

    在去年首次进入Gartner魔力象限即取得了不错的位置之后,今年阿里云存储再次强势进入公共云存储魔力象限,紧跟Google成为公共云存储厂商中在利基象限中最接近领导者象限的公共云存储厂商,而领导者象限中目前只有AWS和Azure。

    图片描述
    图2 2016年Gartner全球云存储魔力象限图

    作为国内市场排名第一的云厂商的云存储产品系列,取得这样的成绩也并不是水涨船高的结果。首先从整体评估上来说,Gartner的评估方法并不依赖母体厂商的品牌和占有率,而是客观的从云存储类型(对象,块,文件)和冷热存储,全球数据中心的位置、技术成熟度、市场策略、市场份额、服务承诺和SLA等方面来综合考虑。

    在这次评选中,分析师认为,阿里巴巴集团对云计算业务的持续投入,在国际市场上也积极布局,让其云服务的技术、产品和全球规模都有长足的进步,阿里云在中国,美国,新加坡,德国,香港,澳大利亚,日本,阿联酋等地都开放了云存储服务,并且不少地方拥有多个数据中心。阿里云云存储的应用场景丰富、在多个领域拥有行业领先的客户,在中国的数字商业领域已经发挥了重要作用。不仅如此,阿里云云存储还吸引了大量的独立软件开发商加入到阿里云云存储的生态圈中。

    分析师认为,阿里云目前的存储产品系列展示了阿里云的潜力。随着时间的推移,已经成为全球超大规模云服务提供商的有力竞争者和替代者。阿里云云存储不仅拥有一系列不同的产品和功能,而且现在已经具备了相当的能力,在全球范围内提供广泛的服务。

    目前,阿里云在海外的积极布点已经让海外九个国家和区域拥有了云存储的服务能力,覆盖了欧洲,美洲,大洋洲,亚洲等区域。

    我们特别邀请到阿里云存储团队产品负责人承宗独家撰文,深度解读取得如此傲人成绩背后的技术思考。承宗2010年加入阿里云飞天团队,先后参与了飞天底层系统的研发以及阿里云所有云存储产品的产品设计工作,对于大规模分布式系统以及大规模互联网应用架构设计有着超过十年的经验,并对于云产品的设计有着深入的理解。

    云计算厂商中最丰富的存储产品线

    存储是云计算业务的基石,而阿里云有着所有云计算厂商中最齐全的存储产品线,对象存储OSS、块存储 Block Storage、共享文件存储NAS(支持NFS和SMB/CIFS协议)、共享块存储、表格存储、归档存储以及混合云存储系列,并且提供在线和离线数据搬迁服务。我们先来看一下阿里云存储的产品系列。

    支撑海量互联网应用的对象存储OSS

    阿里云对象存储OSS从商业化服务5年多以来,已经逐渐成为了中国互联网和移动互联网的存储基础设施。亲宝宝作为如今国内最大的亲子空间,帮助父母记录孩子的成长故事,也记录着OSS一路的发展。在OSS成立之初,亲宝宝这个APP就生长在云上,5年过去了,不仅亲宝宝这样的APP在阿里云OSS上发展壮大,新浪微博,映客,亿方云,华大基因,安诺优达,陌陌,努比亚手机等知名企业也纷纷采用阿里云OSS作为数据的存储。

    OSS的全称是Object Storage Service, 提供简单的网络访问接口(RESTful API),可以随时从网络上的任何位置,任何时间,来读写任意数量的数据。同时OSS是一个全托管的服务,提供安全、容量和性能的扩展性,容灾等服务能力,使得用户可以聚焦在自己的应用逻辑上面。 OSS提供丰富和强大的安全访问机制,通过安全灵活的授权访问控制,提供安全稳定的互联网或者专有网络的访问能力。互联网上的设备,云上的服务器,Web浏览器以及分散在世界各地的CDN节点都可以通过OSS对外的HTTP/HTTPS的访问接口来写入,读取和操作自己的数据。凭借3+N的多线BGP接入能力和稳定出色的系统访问延迟,OSS受到了像新浪微博,映客,陌陌等大型移动互联网APP的青睐,作为源站向全世界提供服务。

    图片描述

    阿里云对象存储OSS依托高性能的阿里云数据中心网络,以及丰富的与开源计算系统和阿里云自研的计算系统的集成,提供了方便,简单,和经济划算的数据分析和加工能力。OSS是中国第一家被官方Hadoop社区接纳为缺省的对象存储文件系统;意味着全球所有的Hadoop生态的离线、交互、数据仓库、深度学习等程序在不需要改代码的情况下,自由读写OSS的对象存储。开源的分布式内存文件系统Alluxio原生支持OSS,让存储在Alluxio内存文件系统中的数据可以使用OSS来作为持久化存储介质和数据交换平台。

    阿里云的E-MapReduce产品中的Hadoop组件也直接使用OSS作为存储后端进行数据存取。阿里云的MaxCompute计算平台通过阿里云内部Tb量级的网络通道,对OSS的数据进行分析和加工。阿里云的机器学习平台PAI,并行处理数据仓库服务HybridDB等产品也都和OSS存储联通。阿里云不仅投入了大量的资源来建立高带宽低延迟的数据中心物理网络,软件栈方面,我们也进行了大量的优化:QoS的管理和支持,前后端流量的管理,最小化通信库的软件开销,数据中心网络传输拥塞技术优化等。 通过丰富的计算和分析能力,一流的数据中心网络,以及高性能的数据访问,OSS系统成为共享的数据湖,一份数据被多种计算系统共享,达到存储与计算解耦的效果,使得资源的利用率最大化。

    图片描述

    阿里云对象存储OSS提供标准(Standard),低频(IA:Infrequent Access)和归档(Archive)三种存储类型,全面覆盖从热到冷的各种数据存储场景。作为OSS的特色,第一,提供了生命周期(Lifecycle)的自动管理,根据用户设置的策略在不同类型之间进行自动转化,节省用户的存储成本和管理成本。第二,统一的RESTful接口来访问不同类型的OSS存储,即使一个文件的存储类型通过Lifecycle自动进行了改变,应用程序不需要修改。其他存储厂商通常要求使用不同的接口来访问不同的存储类型。第三,归档存储的解冻时间小于60秒,不同于其他存储厂商需要若干小时。

    图片描述

    不仅如此,在繁荣的多媒体行业的催生下,OSS在对象存储的基础上,发展了自己的特色API能力,通过提供一站式的图片处理功能,RTMP协议支持,APPEND追加写入等功能,形成了图片社交解决方案,直播推流解决方案,短视频解决方案,云相册解决方案,让移动互联网APP的开发周期大大缩短。

    不断挑战性能和成本极限的块存储Block Storage

    阿里云提供了多种形态的块存储产品,满足日益多样化的用户需求。首先,阿里云的块存储服务为云服务器ECS提供低时延,持久性和高可靠的数据块级随机存储。块存储支持在一个可用区内多副本的方式来提供高可用和高可靠的数据读写。根据不同应用场景的需求,阿里云提供了七种类型的块存储产品:SSD云盘/高效云盘/普通云盘,SSD共享块存储/高效共享块存储,本地SSD盘和本地HDD盘。针对传统政企/金融客户的核心业务数据库高可用架构上云场景,推出了共享块存储产品,提供支持多台云服务器并发读写访问的共享块设备,配合多网卡和部署集功能,实现Oracle RAC的轻松上云。

    同时也提供快照,加密,弹性容量管理等高级数据服务功能。单个云服务器数据盘挂载数量也从4个提升到16个,提供更多单机容量和更高并发读写性能。

    其次,阿里云提供本地盘存储,专为对存储 I/O 性能有极高要求的业务场景而设计的存储产品。譬如在大型数据库业务场景下,具备每秒数万至数十万次低延迟随机读写能力,在 Hadoop/大数据等业务场景下,具备高达数 GB 的顺序读写吞吐能力。阿里云存储团队针对NVMe接口的SSD开发了基于SPDK的高IOPS并发、低延时的本地SSD型实例i1,单机随机IOPS高达48万,延时为微秒(us)级别,使得在云上运行MySQL/Cassandra/HBase/MongoDB的用户获得超过自建物理机的IO性能。为了满足泛互联网行业、金融、电商、政企等行业等搭建大数据存储与计算分析平台的要求,阿里云在2017年还推出了ECS大数据型实例d1/d1ne,选用高性能企业级6TB SATA硬盘,单GB存储成本降低97%(相比于SSD云盘),单实例最大5GB/s存储吞吐能力,可有效缩短HDFS文件读取和写入时间。

    基于阿里云第二代Apsara vSwitch技术技术,在25GE组网环境下,d1ne实例最大可提供35Gbps网络带宽,满足大数据分析节点间数据交互需求(譬如MapReduce计算框架下Shuffle过程),缩短分析任务整体运行时间。

    向传统与新兴科技同时发起冲击的新一代文件存储NAS

    相对于OSS在互联网存储上的流行,共享文件存储NAS在非互联网企业转型上云过程中发挥着巨大的作用。阿里云选择通过公共云NAS的方式来撬动新型行业数据上云,推动非互联网企业业务升级。与传统的NAS不同,阿里云NAS既具备了数据高可靠、完整性、完全托管服务,面向容错的设计和按量计费等云存储的特性;也具备线性扩展scaleout能力和丰富的安全控制和管理能力。 与微软Azure File仅支持CIFS/SMB协议和AWS EFS仅支持NFS协议不同,阿里云NAS同时支持CIFS/SMB和NFS协议,也是全球唯一一款云上同时支持CIFS/SMB和NFS协议的云上NAS系统,更好地满足Windows和Linux的云服务器对高效共享文件存储的需求。

    阿里云NAS分为性能型和容量型两种。性能型NAS采用全SSD的介质,满足I/O密集型应用的需求。容量型NAS采用混合存储的方式,写路径通过SSD,读路径从HDD,在不降低写性能的前提下,提供经济实效的 PB级共享文件存储。然而,仅仅满足支持企业用户文件存储的需求,并不是阿里云做NAS的唯一目的。在Docker、HPC等全新应用的推动下,如何为计算节点提供高可靠,高弹性,高性能,多共享的文件系统已经成为NAS领域的一个新的挑战和趋势。

    在2017年5月的成都云栖大会上,阿里云发布了行业性NAS Plus,首先向广电领域发起了冲击,NAS Plus是云上首个支持广电级别非编的NAS产品,针对广电收录系统并发路数多,顺序写性能要求高的特点,满足制作系统高带宽,低延迟,以及随机读性能要求高的要求,NAS Plus做了性能上的全链路优化,并且与合作厂商华栖云进行了深度合作,在防火墙技术、Hardlink跨卷共享、智能拼接以及帧级共享,快速检索等方面做了深度优化。在与企业中高端NAS的PK中,阿里云的NAS系统全面超出。

    NAS Plus不仅仅是针对广电的定制化版本,而是开创了一种模式,与行业的深度整合能够给客户带来数量级上的体验改进。NAS Plus不仅仅可以用于广电,也可以用于基因、渲染、机器学习等领域,并且能够与行业的使用方法做深度的整合。

    高可用的海量结构化/半结构化数据存储-表格存储TableStore

    海量结构化和半结构化数据则可以使用表格存储。表格存储在2011年开始在阿里巴巴内部使用,为阿里云邮箱、大数据分析MaxCompute、云OS等提供了海量元信息的存储与实时访问,每天承接着数百亿次的API调用访问。

    表格存储底层使用了分布式共享存储技术,通过自动分区Partitioning机制和特有的自动负载均衡Load Balance机制,在数据规模与访问并发上具有极好的扩展性。单表可以在无人工介入的情况下轻松扩展至PB级数据量与千万级QPS的访问能力,其高并发低延时的特点也使表格存储在2014年正式对外商业化之后迅速在社交、金融风控、电商交易、日志监控、物联网等行业获得了大量用户的青睐。

    针对不同的应用需求特点,表格存储提供了高性能与容量型两种实例规格。对读写性能敏感的社交、游戏、金融风控等场景可以使用高性能实例,高性能实例采用全SSD介质,在保证3份数据强一致性的情况下,提供个位数毫秒级的访问延时。而容量型实例则采用特有的混合存储介质,在不降低写性能的情况下提供更具性价比的数据存储及访问成本,适用于日志监控、物联网时序数据存储等对读性能不敏感但对成本较为敏感的业务。

    不仅如此,表格存储针对特定的行业应用也推出了一些特有的功能,例如针对社交IM场景推出了主键自增列功能,去掉了IM系统中对第三方自增ID生成器的依赖,简化IM系统的架构设计,大大提高了系统的响应并发。自有的增量Stream功能,配合阿里云的函数计算和阿里云流式计算,能够很好地同时满足海量结构化数据的存储与实时计算的需求。与MaxCompute、ADS以及Hive、Spark的数据打通,也真正兼顾了海量结构化数据的存储与分析的应用场景。

    图片描述

    传统IDC数据上云的加速器-混合云存储

    随着云存储的兴起,以及原有线下存储厂商开始向云靠拢,混合云架构已经被越来越多的客户接受。混合云把公共云和客户内部的IT环境整合为在性价比和安全性上更优的解决方案。而混合云存储的关键在于连接和传输,阿里云针对连接,易用性和传输在2017年连续推出了一系列混合云的产品组合,包括云存储网关,混合云存储阵列,备份服务,容灾恢复服务,和闪电立方数据搬迁服务。

    云存储网关是一款可以在线下和云上部署的软网关,以阿里云上的OSS作为后端存储,可在企业的内部IT环境和基于云的存储基础设施之间提供无缝、安全的集成。云存储网关支持标准的NFS和CIFS协议,支持VMWare/KVM/HyperV环境部署,提供本地缓存模式,让本地存储与云的链接具有更好的互操作性和性能。

    而混合云阵列则是阿里云混合云存储战略的重中之重。混合云阵列让您可以像本地存储一样使用和管理本地和云端的各种存储资源(块、文件和对象),本地存储通过云缓存、云同步、云分层、云备份等方式无缝连通云存储。混合云阵列不仅可以作为传统存储与云的连接器,而且因为混合云阵列的高稳定性和性能,支持双控机头的模式,在一些场景下也可以直接替代传统存储成为混合云中的一级存储。

    图片描述

    备份和容灾恢复服务是大量企业需求的混合云存储服务。云存储网关和混合云阵列能够帮助数据上云,同时也能够让云上和云下形成灾备机制。用户本地的虚拟机镜像备份,数据库备份以及应用备份,通过运行混合云阵列上的灾备服务,能够灵活的配置在云上的备份策略和备份周期,并且通过在云上进行与弹性计算服务的结合,在用户本地IDC发生故障时可以自动或手动的进行切换。

    当用户在本地机房有PB量级的数据,需要在短时间内进行迁移时,离线数据搬迁能力显得尤为重要,阿里云推出的闪电立方产品,单台一次支持480TB的迁移能力,且可横向拓展,利用多台设备可以同时迁移PB级别的数据,使得海量数据快速上云成为可能。除了加速数据迁移的速度,整体费用与专线方式对比,也降低60%以上。

    世界先进的分布式存储技术-盘古

    阿里云的云存储产品都拥有一个公共的底层存储平台,叫做盘古。阿里云在2009年成立之初就开始了盘古分布式文件系统的研发,经过多年的发展,盘古文件系统已经能够支持块存储云盘、对象存储、文件存储、大规模数据处理、数据库等各种复杂场景,并且针对离线和在线等不同场景做了精细的优化。

    在机器规模达到上万台时,硬件故障的发生不仅无法避免,而且成为了每时每刻都会发生的常态,磁盘损坏,机器宕机,网络设备故障,网络隔离,机房断电,运维故障等频繁发生。在一个多租户环境下,资源也变成非常难以预估,网络阻塞,后台任务,请求的突变,多租户任务的争抢,在线离线的争抢,负载热点等也会频繁出现。盘古文件系统从第一天设计开始,就遵循下面两点设计目标:
    • 基于不可靠的资源打造一个可靠的整体
    • 基于无法预估的资源打造可以预测的整体

    盘古具备下面的技术特色:
    • 单机群达到万台规模
    • 管理EB级别的存储空间
    • 统一的全局名字空间管理
    • 名字空间的管理和存储空间的管理分离
    • 统一的不同存储介质的智能数据分布和迁移
    • 支持离线和在线应用混跑
    • 支持多种访问方式:顺序,随机,数据流,记录流
    • 数据中心级别的可用性保障,地域级别的容灾

    高可靠高可用可扩展的元数据管理- 盘古Master

    盘古采用基于Paxos协议的盘古Master来管理元数据, 通常配置为5个实例,可以同时容忍两台机器出故障。采用Paxos一致性协议,保证了高可用和快速切换的能力,减少了外部的依赖,做到了独立自包含,在保障高稳定性和高性能前提下能够容忍复杂故障。 支持按照Namespace来分区, 支持EB级别容量和万亿级别文件数的线性扩展能力。

    数据的可靠性和高效访问 – 盘古ChunkServer

    ChunkServer负责管理存储空间和数据读写。首先,ChunkServer支持分级存储,针对不同的存储介质如NVMe SSD, SATA SDD, HDD等,根据相关配置的策略,把数据写入对应的存储介质,同时支持基于策略的迁移。比如说在混合存储云盘,数据先写入来自三台不同机器的SSD盘后就返回,后台异步地将数据迁移到HDD盘。

    其次,ChunkServer采用了一系列技术来提供稳定的性能:1)服务分级,对请求队列和网络流量设定不同的优先级;2)管理好昂贵的后台活动;3)热点负载平衡;4)增加副本来应对重度使用的数据;5)缓冲来加速;6)备份请求(Backup Requests) 来规避慢盘等。这些技术的本质目标就是基于无法预估的资源来打造可以预测的整体,提供稳定的性能,通常用99.9%分位和99.99%分位的性能来表征。

    第三,数据可靠性(Durability)和完整性(Integrity)是盘古的生命线。每一份数据成功地写入三台不同的机器(来自不同的可用区,或者不同的机架)后才返回。而且自动巡检系统不停地检测不可用的副本,一旦出现,自动地及时复制,使得每一份数据任何时刻至少有2个及以上的副本,提供至少10个9(11个9如果是多可用区)的可靠性。盘古系统也提供端到端的数据校验,上层的云存储产品提供数据的CRC,盘古在落盘的时候进行校验,并且把CRC和数据一起写入磁盘。后台任务也一直巡检,检查存储介质可能出现的位跳变(bit rot)错误,一旦发现和写入的CRC不符,找到正确的副本,重新复制一份新的副本。

    第四,全自动的健康检查和主动规避低性能的机器和磁盘。在盘古所管理的成千上万的机器中,总是会有已经出现了健康问题的磁盘和机器,盘古文件系统根据线上历史上所有的运维操作和硬件故障做了机器学习,自动地将这些盘和机器过滤出来,进行慢盘规避,磁盘打分下线和机器调整,把隐患提前解决。

    第五,支持多种访问方式并极致硬件的能力。在线访问追求低延迟,而离线访问追求高吞吐。盘古文件系统既要满足低延迟的在线访问,也要满足大并发大吞吐的离线访问,而传统的多线程系统在线程较多时,切换代价非常高。盘古文件系统从端到端采用协程的方式设计,使得在多任务的情况下,使用盘古文件系统的效率极高。内核态和用户态切换是另一个主要软件开销来源,盘古采用类似SPDK轻量级用户态文件系统来访问单机的磁盘,减少切换。高性能通信库和QoS是另一个重要的方面来提高存储的性能和资源的使用效率。

    全球第二家云厂商支持跨多可用区的存储系统

    盘古文件系统在生产系统中采用跨多可用区部署的方式,经典的模式是支持横跨三个可用区,每个可用区距离30公里到50公里。无论是三副本还是EC(纠删码)副本,都是均匀分布在三个可用区内。任何一次写入都在三个可用区数据落盘后才会返回客户成功。由于各可用区的数据中心有独立的供电,网络和冷却系统等,跨多可用区的存储提供了数据中心级别的容灾能力,在任一可用区完全不服务的情况下,整体服务无缝切换,数据无任何丢失。跨多可用区对阿里云内部核心骨干网络的要求非常极高,端到端的延迟要求在稳定1毫秒以内,并且有Tb级别带宽能力。阿里云投入了大量的资源来建设高容错能力和高性能的多可用区互访的内部核心骨干网络。

    图片描述

    存储无法计算的价值

    为亿万网民提供基础服务

    2016年双十一,淘宝交易额高达1207亿,其实背后是大数据的支撑和阿里云计算的能力的体现。和最高峰值每秒17.5万笔交易相比,淘宝APP和网站经历的流量和访问次数就比这个数字要高百倍以上了。而淘宝APP和淘宝主站上的所有图片和视频都存储在阿里云OSS之上,这背后是OSS整个链路低延迟和高稳定性带来的流畅体验。

    图片描述

    这就不难解释为什么新浪微博从2016年开始也把图片数据放在了阿里云OSS上。2015年,李晨与范冰冰在新浪微博上晒出合影并配文:“我们”,创造了两小时阅读量超过1000万次的记录,促成了新浪微博与阿里云史上最大规模的混合云合作,当流量激增导致的脉冲式访问,要保证系统的稳定性和服务的正常运转,除了实时扩容之外,就是保证后端系统在高压力下的延迟和稳定。2017年春节,新浪微博的Feed,广告,搜索,话题,视频,直播,手机微博,图片等多个核心业务系统部分迁移到阿里云平台,除夕期间的“红包飞”业务则100%架构在阿里云上。新浪微博核心业务之一图床系统就架设在阿里云OSS之上,并且根据用户使用终端的不同,所有的图片需要进行实时的缩放和质量调整,为新浪微博在不降低用户体验的情况下,大幅的降低了流量,节省了成本。

    存储牵手计算造福社会

    2016年10月,阿里云计算与中国科学院国家天文台达成了战略合作协议,并与2017年1月成立了天文大数据联合研究中心。中国虚拟天文台主节点成功迁移至阿里云,成为一个集成超过500TB科学数据、1.5PB存储能力、700多Tflops计算能力和100多种软件的天文数据库与综合服务部门,其中包括我国自主研发的郭守敬望远镜(LAMOST)巡天数据,从2009年开始做观测,到现在已经累计了800多万的天体光谱数据,是全世界最大的全体光谱数据库,而LAMOST的数据,经过天文台研究和技术人员评估论证,放在了阿里云OSS上。不仅因为OSS的高可靠性,高性价比和易用性,更多是考虑到阿里云计算节点与OSS之间的连通性和高可访问性。

    我们经历的每一次地震,都在提醒自己预测和预警这种灾害的迫切性,但是,我们离这个目标还很远。为了更好的认识地震这一物理现象,需要极其详细的地壳结构影像,而为了绘制这张地下地图,需要有详尽的数据计算,中国地震局在长期的观测积累中,已经积累了PB量级的数据。中国地震局的研究员如果使用地震局的单机设备对这些数据进行一次相关性计算,大概需要七年的时间,而使用阿里云批量计算和云存储OSS,同时调度阿里云上万核的资源以及存储系统Tb量级的吞吐能力,将需要耗时七年的计算任务在48小时之内跑完了,这些计算的结果成为科学研究所依赖的重要数据。

    解析一个人类基因组,包含100-1000GB的数据量,如何及时获取、快速分析、安全存储这些庞大的数据是亟需解决的问题。单独建设一套计算和存储的系统会带来昂贵的维护成本,也需要漫长的时间才能完成一次大规模的基因组学分析。2016年4月20日,基于华大基因开发的新一代基因云计算平台BGI Online,在21小时47分12秒内完成了1000例人类全外显子组数据的分析,即使使用传统的本地高性能计算中心也需要4-7天,而BGIOnline 正是基于阿里云的ECS和云存储OSS、NAS和块存储完成了这一壮举。

    展开全文
  • qiniu-suits-java 是一个多线程的云存储 api tools (base-qiniu),通过设计的能够高效并发列举 云存储空间的资源列表(支持七牛云/阿里云/腾讯云/AWS S3/又拍云/华为云/百度云等,支持 S3 接口的均可以通过 S3 数据源...
  • 为了提高当前校园信息管理系统效率的目的,本研究在构建校园云存储服务系统用户层的基础上,开发设计了基于HDFS体系的校园云存储平台及各个功能模块。利用了Mybatis的开源持久层框架对HDFS体系进行改进,并且DAO层...
  • 云存储——简介

    2016-07-11 10:49:45
    摘要 本文主要简述云存储的基本概念。...2. 云存储框架模型? 部署模型从逻辑上根据谁来拥有和运行,可以分为:私有云,社区云,公有云和混合云。 服务模型根据云服务厂商给客户提供的服务类型,可以
  • 当前的IT产业中,“云”几乎成了时下最火红、时髦的代名词,软硬件厂商开始将旗下...其中属于储存领域的“云存储”,究竟在整个云运算的框架中扮演什么角色?现在的发展状况与面临的瓶颈为何?请看今天我们的分析探讨。
  • 提出了一种基于云计算的数据存储和处理框架,支持用户对大规模数据集进行低成本、安全的共享和处理。该框架研究了基于矩阵的数据挖掘算法,重点是安全的Top-k特征向量算法。该算法采用了一种迭代处理模型,授权用户...
  • 规律提出一种基于复制和纠删码自适应切换的云存储容错算法,构建了一个相应的云存储容错框架。容错算法根据.文件的访问频率和存储大小,自适应地选择容错策略,一方面降低了低访问量文件的存储开销,另一方面提高了...
  • 厉害了!Word云存储

    千次阅读 2016-11-05 10:54:01
    这是一篇看完之后对云存储的认识有醍醐灌顶之效的干货,请耐心看完 标准的云存储是?— 谷歌是第一家推出云存储的公司, 现在市场上云存储的产品,架构本质上是一样的。— 都是通过存储虚拟化技术,采用分布式...
  • 如下图所示,它在同一底层平台之上可以对外提供三种存储接口,分别是文件存储、对象存储以及块存储,本文主要关注的是对象存储即radosgw。基于Ceph可方便快捷地搭建安全性好、可用性高、扩展性好的私有化存储平台。...
  • android SAF存储访问框架

    千次阅读 2018-10-11 13:05:04
    Android 4.4(API 级别 19)引入了Storage Access Framework存储访问框架 (SAF),SAF 让用户能够在其所有首选文档存储提供程序中方便...云存储服务或本地存储服务可以通过实现封装其服务的 DocumentsProvider 参与此...
  • 云存储云计算选择开源还是商业版

    千次阅读 2018-04-11 18:06:25
    现在市场上有很多云计算架构可供选择,既有成熟的商业版本,也有基于开源的技术。 每个公司在面临存储运算...选择商用平台还是选择开源平台创建企业的私有,这确实是个问题。企业需要综合考虑,权衡利弊,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 95,105
精华内容 38,042
关键字:

云存储框架