• 董朝:打造云存储服务——移动端数据存储与分发


    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~

    作者:董朝,腾讯云存储业务终端负责人,2013年加入腾讯,主要负责手Q红点运营系统、会员、腾讯云云存储、移动开发平台的研发和优化工作。在移动端APP构建上面有丰富的经验,目前主要负责腾讯云存储业务终端相关的工作。

    先做一个简单的自我介绍,2011年我毕业以后,一直从事IOS的开发,目前为止大概有七年的工作经验,前四年的时间主要在做APP里开发,之后三年主要做SDK相关的工作开发。

    我今天的演讲包括两个部分,第一个部分是关注存储这一方面,从终端的角度出发,来看看存储这个东西对我们来说意味着什么。第二个部分,简单分享一下我们在制作SDK上的经验和探索。

    COS服务介绍

    数据存储 一个通用的基础服务

    为什么要从终端角度考虑呢?当我们从终端的角度来看待我们数据存储的场景的话,更多情况下,会从业务场景出发,比如有一些头像上传、Feed图片上传、音频上传、视频上传、短视频非结构化的数据,这时注重的是数据集反馈的URL,为此,我们需要去匹配相关的上传及下载接口。

    从终端讲,其实很简单,我们做到了一个仓储服务,真正的将数据存储看成了一个透明的事情。对于用户来讲,只需要关注传输所关注的事情,给用户返回一个URL,由URL进行处理。

    COS服务

    腾讯云为了完成上面所述的目标,向用户提供了一套整体的COS服务,一套面向用户的对象存储服务。这里不是数据或者非结构化数据存储,而是对象存储。对于端上来讲,我们更多关注数据和URL,COS更偏向于PaaS层的服务,这个URL可以理解为一个指向的数据内容,没有限定具体什么样的格式,如音频、视频都是可以存储的。

    当这些数据传上来之后,首先,腾讯云会在整体COS的系统内部帮助大家将数据整体仓储起来,其次,我们也会配合腾讯云已有的CDN的能力帮助大家去分发。这样,对于用户来讲,您只需要我们的一个SDK,剩下所有的事情在腾讯云帮你托管。当然这里我们这里只是一个简单的上传和下载,对仓储还有很多事情需要处理的,后面去讲。

    高并发,高可用

    为了达到图中高可用、高可靠的11个九的要求,数据的可用性、输入可访问性达到3个九的要求,我们做了很多努力!

    对于基于大量并发,端上来讲面临一个问题,我们属于分发类的软件,比如QQ、微信或者自己内部的一些APP,他们有大量的用户,可能同一秒出现大量同时的上传或者下载请求,这些都在内部做的一些处理去支持大量的并发。

    那这块如何去解决呢?

    当数据传上来之后,除了上传、下载通讯需求之外,还会有很多管理类的需求。举个非常典型的例子,比如刚才说的业务场景,其中一个是头像的上传和Feed,或者用户UGC的内容传上来之后,最典型的业务是鉴黄。当您的服务数据有少儿不宜的内容后,你将面临很多问题。所以你的数据传上来之后,像这些鉴黄、水印处理等工资,原先自己构建服务的状态下是自己后台去处理,非常麻烦,你不仅需要去构建整套的鉴黄体系,机器学习、人工去处理等,而且这些处理其实非常消耗时间。我们针对这些需求,整合数据、仓储到处理的需求,在COS内部帮助你把通用性的需求解决掉,真正做到端上处理您面临的所有需求。

    我这里分三个层次来讲解,我们在满足这些常见诉求上做了什么事。

    • 一是我们最关注的数据接口层,如何使用我们这个服务。这里通过我们常用的各种各样的方式,包括API、SDK、控制台等,如何把服务提供到我们的客户或者终端开发人员,这一层可以简单地归结为一个使用界面层。我现在从事SDK的开发也是在使用界面层的工作,后面也会着重讲一下。
    • 二是分布式的高可用集群,应用接入层,除了API层,上面还有一个应用接入。应用接入的时候会把像刚才提到的鉴黄的一些服务,水印的服务,接入进来。这样可以给用户提供一个能力,你可以自主去选择你上层需要的能力,然后把这些能力集成进去之后,用户服务端不需要再进行二次开发。
    • 三是传输的服务。这块是最开始一直提到的问题,就是上传和下载的问题,上传主要是安全和数据稳定性的问题。关键还有下载分发的问题,这里有成体系化的CDN的一些加速的策略、动态加速的策略,就近接入让你的数据更快的能从云端下载到客户端上。

    权限与安全

    除了刚才说到上传、下载,接下来可能更关注的是权限与安全。为什么单独讲这一块,因为之前做APP和SDK过程中会我们发现COS服务是一种数据服务,而数据是一种资源。这种资源天然会带着一定的权限,涉及谁可以访问,谁不可以访问的问题。

    访问控制的策略

    我们在处理这个问题的时候引入了一整套的访问控制的策略(CAM)。内部有一个整体的访问控制策略,一个请求从端上发过来之后,首先使用非对称加密的策略,客户端其实是拿着一个临时密钥,其实是一个公钥加密,加密整个请求,整个请求来到服务器端,服务器端判断他是不是合法用户,才会让他访问后面的资源。在访问后面资源的时候会有ACL的策略,去控制对应的人、对应的请求是否有权限访问你对应的这些资源。

    对于端上来讲,我们在构建的时候会遇到一些问题。端上用这种公钥的时候进行迁移请求,迁移请求的时候必然发现端是一个分发性的软件,只要你的公钥存在二进制当中,一旦分发出去,别人就很容易去反编译,很简单就能把公钥破解。当破解出来后,整个的服务就暴露在别人面前,所以这里我们采取临时密钥的策略,为了不存储永久密钥,建立了临时密钥。这个临时密钥,相当于一个永久密钥的二次分发,在用户的服务器端,拿着用户自己的永久密钥去自己的服务器签发一个临时密钥,临时密钥是有有效时间的,我们甚至加一些机制,限制他去访问哪些资源,把一个临时密钥下发到客户端,在客户端使用是一个相对来说更加安全的策略。

    这里可以看到,因为大多数情况使用的是APP cad的策略,因此特别容易被反编译和破解,所以这里临时引入了临时密钥策略。

    数据落地

    加密

    当然我们考虑的问题,我们的数据最后存哪儿,怎么落地的。落地的过程也考虑了很多的问题,比如刚才说的安全性的问题,这里支持服务端加密,可以在请求中携带一个特定头部,携带数据会用一个用户指定的密钥去进行加密,即使被人偷库了,拿到的数据也是不可读的数据。同时也支持像客户端加密,服务器的非对称加密一些这样的策略,主要也是安全性。

    生命周期

    同时,像我们常说的数据的生命周期,比如一个Feed,常见的Feed有生命周期的,假如一个月之后这条Feed就没人看了,我们可能要删掉,而生命周期可以直接在对象上,一个月之后过期,过期之后就无效了,不需要再手工的在整个仓储里排除这列数据。

    跨域复制

    还有一个我们比较关注的问题,这个东西在哪里是可用的。我们可以看到这张图,COS的产品在世界各地分布了非常多的点,就是我们的接入点数据仓储的落地,现在标记的就是在这些地域已经有了接入点和数据仓储。也就是说如果你的服务现在需要出海或者跨国服务,使用我们的COS是一个非常好的选择。

    SDK

    我这几年的工作经验主要围绕COS-SDK产品的开发,我和大家分享一下我们在制作这个COS-SDK上的一些经验。

    这里所谓的SDK对用户来说,只是一个服务界面,而COS服务来说,更像是后端服务。为了更好的易用性,我们将COS服务封装成了SDK,只让用户看到上传和下载,其他不需要考虑。

    做这个事情的时候,我们可能会面对第一个问题,什么样的SDK是一个合格的或者说是一个更容易去使用的SDK?首先有一些感性的认知,好用,快速上手、高性能。对端上来讲,不会宕机、服务是稳定的,这是一些比较感性的词。

    这些感性的词,是比较难去实现的一个目标,如果转化一下,我们转化到SDK具体的形态上,可以把SDK分成几个模块。第一个是我们最核心的,代码或者二进制,这是我们的分发形态。第二个是我们和SDK用户交互的API,传统意义上SDK的开发,只有API和代码或者二进制,我们常常就是把这两个东西丢给客户,客户自己去摸索吧。但是的文档和Demo,是一个合格的SDK必备的部分。在制作SDK的时候,需要把每一个模块都去做好。

    之前我们作为一个程序开发人员来说,更多关注的是代码、API,但这几年的经验告诉我,如果真正能让用户把你的SDK用起来,或者觉得好用能快速上手,你需要把Demo、文档补充好。这一点,也是我们在做整个的移动研发平台的时候,会着重考虑的一些点。

    靠谱SDK

    如何制把这个SDK做成一个靠谱的东西,怎么做呢?这是我们现在正在做的一个流程化、工程化的图。

    这里非常强调设计的。因为对于SDK来说特别强调API的重要性,API是设计出来的。这里设计架构设计,类结构的设计,类关系的设计,模块化,一些东西我们都需要考虑到。刚才也说到一个API的设计,比如针对COS的API来讲,我们就会考虑它会有一个基础的模型,它是一个请求回复的模型。针对这个模型,就需要把请求需要的参数给描述出来就好了,描述出来之后,使用者能快速的把这个请求构建出来,丢给COS层就OK了。所以我们在设计这一个COS的API的时候,我们遵循请求回复的模型,去进行整体的设计。

    设计完成之后下一个阶段,实施。把我设计的东西翻译成代码,让它变成一个可跑的东西。设计好整体的API,设计好整体的模块化之后,发现一个比较有意思的现象,我们大概有几十个API,这里包括几个生命周期的管理、bugly的管理等其实都是基于请求回复的模型,唯一区别是每一个API的地址、参数、回参不一样,这样完全可以用代码生成的策略。

    我们自定义了一套模板语言,把刚才说的API的请求回复模型描述好,只要描述好之后,加一个简单的模板,就可以通过卡梅隆的代码生成策略,一次性把所有的API生成。我们最开始的想法是为了优化效率,如果说人工的去写每一个API的话可能需要投入很多的人力成本,但是如果是代码生成的话,整个效率提高的。把整个事情做完之后,我们设计好带有模型性的能代码,质量提高的也令我们感到很恐怖的一个地步。

    针对不同网络优化

    因为我们是做SDK,对SDK来讲,在处理质量的时候会面对的一个和APP不一样的问题,APP现在测试基本上是基于,我们有一个开发人员,开发人员来写。但SDK不可能写一个Demo,所以我们把整套的测试体系建立起来了,比如常见的UT、代码检查,同时对所有历史性版本,做了一整套的测试。SDK是持续发布的,只要发出去的SDK,线上一定会有用户在跑着,比如现在我的SDK版本号是1.1,之前发过五个版本,那么我们的线上总共有六个版本,不可能说我测试的时候只测当前的版本,就能保证历史的版本是没有任何问题的。只要发一个版本,就加入到one box当中,在每次发版之前就会把全量的SDK跑一遍。

    当然这里并不单指端上,安卓、IOS甚至后台的SDK,这些SDK都统一收拢进来,收拢进一个one box测试,把这些全跑一遍,只要有改动我们全跑。这样保证你使用了我们的SDK,在你没有更新的情况下,后台有变更,也不会影响你的现象服务。这种对界面性的SDK是一个非常关键的问题,你需要保证你发出去的SDK运行是没有任何问题的。这是我们在测试上做的一些事情。

    最后会把整套东西提交给客户使用,在客户使用的过程中,我们其实也有很多的思考。比如说我们会使用统一的配置服务框架。后面也会考虑把整套的基础,你使用腾讯其它服务的话,也可以使用我们这套端上的统一配置服务的框架,然后去做一个集成。

    支持动态加速

    再切回到COS这个单独的产品,它主要做上传服务,上传更多的是和网络进行交互。进行交互的时候这里有一些常见的优化策略,前面三个不用说了,这可能是大家基本上会形成一个共识的东西。第四个支持动态加速,同时在SDK内部有了一个更好的任务并发处理。

    更好的任务并发控制

    我们在上传的时候会同时上传非常多的任务,而且网络库有不只是专门用来处理像我们这种文件上传的任务,有可能也是处理一些常见的IPC的任务,就是一个简单的请求一个Feed,或者请求一个用户名称的东西。而常见的文件上传的任务,是一个非常耗时的任务。如果你把这些任务和刚才我们说的不耗时的任务放在一起的话,会形成一个瓶颈,阻碍你正常的流程,所以这里做一个并发控制。将所谓的耗时任务降低优先级,让正常的IPC的命令能更快的响应,而不是更快的响应文件并发的任务,其实是业务细节上有优化了。

    接口封装OOP化

    最后在接口上,我们是请求回复的模型,完全是OOP化的模型。我们在API设计的时候严格按照OOP的思想去设计的,这样大家更容易去使用。因为我在使用其它SDK的时候,我看到更多C化的一些API接口,基本上是静态函数或者一个类方法抛给你去使用。其实这样的话不会形成一个整体上的概念,因为OOP命名对象更多的是讲究抽象,这样可以把整体的COS一个宏观的概况,可以看这个类结构图,能很好的理解概况或者每个类的设计意图,怎么去用,可以更好的理解这些东西。

    Q/A

    Q:咱们COS-SDK是每个应用都要申请一个SDK,一个用户手机上需要安装多个应用,我们多个应用可以共用这一个SDK吗?因为我们的应用资源可能需要进行共享的。

    A:可以,因为我们这个不是和应用绑定的。

    Q:关于存储,首先想到的问题,像图象、视频流,压缩和解压缩是怎么做的?保证不失真。最后上传和优化,关于COS的对象存储和阿里云的OSS的对象存储,它的优势在哪里?

    A:先回答第一个问题,关于音视频的问题。其实COS作为一个通用的数据服务,我们在传输上并没有做太多的关于特定数据的优化,如果你对音视频压缩或者数据传输有一些诉求,可能是上层业务。比如上层业务会提供短视频SDK,短视频SDK会进行数据压缩或者一些设定,是分层的业务来处理这个问题。应对不同的场景,可能有不同的分层。

    第二个问题,我作为一个终端开发人员通过我的角度回答这个问题,非官方的回答。可能觉得我们支持更多的存储的上层业务逻辑的处理,我们把整个存储的事情不单单当成一个仓储的东西,我们会做更多的上层业务逻辑的事情,帮助大家更好地接入使用。

    Q:COS这款产品在实现文件上传的时候,提供的接口需要先设定一个远程的内经存放路径和本地的文件路径是吗?

    A:您这么说是对的,先尝试解释一下看看我说得是不是跟您一样。你要存一个东西,第一要知道存什么,第二要知道存哪儿,所以您问的这两个一定要有的。

    Q:我是做web开发的,如果要上传一个文件到web后端,但通过这个文件可能没办法去到那个服务器缓存的本地文件的路径。那那边如果需要上传的话,可以直接把这个文件上传吗?

    A:可以直接上传,其实刚才说的对象存储系统的时候,我们会有一个对象键的概念。就是你远端的一个地址的概念,这个远端的地址,其实可以在本地生成,然后上传。

    更多相关资料,请点击下方链接获取:
    移动端数据存储与分发-董朝.pdf

    问答
    云存储Redis的实例怎么备份?
    相关阅读
    Docker解决数据存储问题的方案
    杨列昂:腾讯移动分析与服务架构
    胡泽锐:移动开发即服务——腾讯云移动开发平台技术分享

    **此文已由作者授权腾讯云+社区发布,原文链接:https://cloud.tencent.com/developer/article/1138213?fromSource=waitui **

    欢迎大家前往腾讯云+社区或关注云加社区微信公众号(QcloudCommunity),第一时间获取更多海量技术实践干货哦~

  • 相关阅读:
    索引
    IComparer 与 IComparable
    foreach
    修正needle在摘要认证时第二次请求仍返回401错误
    js笔记
    Ntp客户端
    c# 笔记
    android笔记
    nodejs笔记
    js 常用基本知识
  • 原文地址:https://www.cnblogs.com/qcloud1001/p/9120927.html
Copyright © 2020-2023  润新知