淘宝开放平台是阿里与外部生态互联互通的重要开放途径,通过开放的产品技术把阿里经济体一系列基础服务,像水、电、煤一样输送给我们的商家、开发者、社区媒体以及其他合作伙伴,推动行业的定制、创新、进化, 并最终促成新商业文明生态圈。
开放业务场景常常跟随内部业务的变化,在数据层面上会频繁发生变更。传统数据库在成本、易用性方面无法很好满足生态异变场景的需求。数据空间的探索,是为了在生态场景中支撑业务快速增长的基础上,提供一个可存储海量数据、单表可自动扩容、字段可无限扩充、查询效率不低于 MySQL 数据库的产品。如何以一套统一的数据架构,支持不同用户按需自定义数据模型,保证数据定义层面的扩展和变更不会影响自身和其他租户业务功能的可用性,将数据和能力集成在平台自身。为此我们打造官方弹性存储空间,在安全可控的情况下沉淀数据支撑更多业务场景标准化开放集成。
本文为此系列第二篇文章,前一篇见——
第一篇:开放网关架构演进
多租户数据模型
我们先站在巨人的肩膀上来看看业界有哪些通用的多租户存储模型。
数据空间采用类似Salesforce的大宽表模型设计,通过SAAS化的方式开放给开放业务使用。元数据对于平台而言,存储的是所有租户的数据。对于租户而言,每个租户/组织只能看到和定义按照自己租户OrgID隔离的它自己版本的元数据和数据, 而且只能执行自己租户OrgID所授权的行为,这样每个租户就拥有各自版本的SAAS方案。
▐ 元数据驱动的多租户数据架构
数据空间通过业务场景&租户维度隔离每个租户下自己版本的元数据和数据,整个架构分为以下5个逻辑层次。
底层数据存储层:存储了租户底层数据结构以及对底层数据的对象和字段定义信息,支持多种存储类型
存储引擎路由层:根据业务场景及租户定制,路由到不同的存储产品中执行
元数据层:元数据模型主要由对象、字段以及底层数据表组成。元数据执行引擎是将业务逻辑模型映射到统一的元数据存储模型最核心的能力,我们常说的ORM功能也是其核心功能,但比其复杂的多
平台接口层:对外提供数据空间SDK和标准MySQL协议两种调用方式。数据空间SDK中包含对象模型的创建、简化版的SQL执行等操作。标准MySQL协议通过自建MySQL代理层对外提供数据库服务
业务场景层:数据空间对外服务的特色业务场景
▐ 元数据存储模型
数据空间整个存储采用了与业务无关的宽表设计,可扩展性非常好。底层数据使用动态列存储,加以额外的元数据描述信息。数据模型设计包含以下几部分:
对象元数据表:存放用户自定义和定制化的对象
字段元数据表:对象下字段的定义,包括字段类型、字段映射在真实存储中的位置、是否需要索引、字段校验规则等
数据表:存放用户真实业务数据,由灵活可扩展的弹性列组成,通过对象和字段的元数据定义映射到真实的存储
与Salesforces不同是,这里并没有维护索引表,索引的维护非常复杂,针对ADB有全列索引,并不需要建索引。针对关系型数据库,不使用共享宽表模式的情况下,DDL独立建索引会更为灵活。
基于这个设计可以实现数据空间的弹性列无感DDL,当增加一个数据列时,仅需要选取Data表中相同值类型的数据列,加入到逻辑表字段模型中即可,无需进行显式DDL。
▐ 元数据执行引擎
元数据执行引擎由元数据映射、构建语句、组装SQL、执行语句、反元数据映射五个部分组成。用户业务SQL经过引擎执行后映射成与业务无关的元数据存储模型SQL,路由到相应的逻辑租户数据库执行,执行成功后再反元数据映射成用户真实的对象数据。通过元数据执行引擎,就可以实现在统一的多租户元数据存储模型上承载多租户自定义的数据需求。
下面是一个简单的例子。
通用存储协议支持
为了方便用户使用习惯,数据空间除了自身提供SDK调用方式外,还需要适配标准MySQL协议。
对外接口 | 说明 | 优点 | 缺点 |
数据空间SDK | MySQL语句简版描述 | 可以通过代码实现数据访问,适合java编程习惯 |
|
MySQL协议 | 提供MySQL代理,对外适配MySQL协议 | 通用性强,通过数据库代理可做治理和管控 | 技术成本较大,需要平台自建代理层,代理稳定性需要保障 |
▐ MySQL Proxy
在抽象的多租户元数据模型下,协议层开发的技术成本以及难度还是非常大的。数据空间选用开源中间件Sharing-Proxy作为MySQL代理对外提供数据库服务,隐藏底层元数据存储模型,用户不需要感知底层数据存储。Sharding-Proxy的定位是透明化的数据库代理,它封装了数据库二进制协议,用于完成对异构语言的支持,我们先来看下它原始的架构图。
Frontend层实现了MySQL协议的编解码。原始Sharing-Proxy 得到解码的MySQL命令后,开始调用Sharding-Core对SQL进行解析、路由、改写、结果归并等核心功能,在Backend层与真实数据库的交互。
数据空间由于有一套自定义的元数据模型,解耦了用户逻辑模型和底层物理模型,需要对Sharing-Proxy进行改造。
Frontend层:MySQL协议层编码/解码保持不变
Backend层:与真实数据库的交互并不需要,根据存储路由,存储到相应的物理库即可
Core-module层:得到解码的SQL命令后,需要解析语法树,对元数据进行映射,调用执行引擎执行
改造中最核心的部分在于Core Module层。在Sharding-Proxy的线程模型中,Frontend层使用IO多路复用处理客户端请求,后端使用HiKari连接池同步请求数据库,User Executor Group用于执行MySQL命令。
核心层(Core-module)的执行过程委托给CommandExecuteEngine完成,流程如下:
Sharding-Proxy获取SQL命令执行器的流程保持不变,我们主要对解析Statement语句和SQL解析执行引擎进行修改。
▐ SQL解析执行引擎
在数据空间中,我们把SQL执行的整体结构划分为以下几部分。
解析器。ShardingSphere采用完全自研的antlr进行解析,通过测试发现非常耗时,数据空间改成Druid解析后性能提升5倍
提取器。这里需要将AST节点进行深入解析,封装成数据空间简版SDK
构建器。这里指构建查询请求包需要的字段定义信息,包含字段名、表名、字段类型、字段长度等基础参数,由元数据获取。
执行器。交由数据空间元数据执行引擎执行
▐ 引擎升级
在上述解析执行过程中,SQL协议层需要将SQL解析成数据空间规定的协议格式再执行,存在着以下问题。
可扩展性差。每次适配新的SQL语句都需要修改提取器和底层元数据执行引擎,改造成本较大
复杂SQL描述难。数据空间规定的协议格式对于简单SQL描述起来比较容易,但对于子查询、多表查询等复杂类SQL描述起来较为困难
类型转换复杂。在执行参数准备以及结果返回参数过程中,都需要进行类型的转换,负担还是比较大的。对于MySQL支持的标准查询语法,转换逻辑需要考虑的非常全面
基于以上考量,为了保证代理层的稳定性,对上述SQL解析执行引擎进行了整体升级改造。解析、构建过程不变,增加了改写引擎,并将改写后的SQL语句经过执行引擎处理。
SQL改写在元数据存储模型下需要将用户真实字段改写为底层真实存储的弹性列,详细改写规则如下。
标识符改写
由于元数据底层真实存储其实是弹性列,业务侧表名和字段名都是逻辑上的概念,需要改写的标识符包括表名称、字段名称等。表名称改写是指解析AST,获取逻辑表名,并找到元数据定义,将其改写为真实表的过程。字段名称改写是指解析抽象语法树,将所有的字段列改写为真实字段列的过程。
补列
在多租户数据架构下,租户之间数据依赖业务类型&租户ID进行逻辑隔离,需要补列的唯一情况就是所有语句都需要增加租户查询条件(租户+业务类型+表模型)。
▐ 标准协议层适配
对于协议层SQL需要进行单独适配。包括:
information_schema库
MySQL系统变量
set/commit语句等
比如,对于information_schema元数据库中的库表和字段元数据信息,我们需要查询元数据定义信息,并封装返回结果包返回,这里就不一一赘述。
整体技术架构
至此整个官方数据空间的基本形态和框架已经构建完成。以元数据管理为核心,向上提供租户模型管理、数据服务、数据分析等能力,并通过MySQL Proxy和数据空间SDK完成能力暴露。
具体的技术大图如下:
应用场景
官方数据空间在业务场景上的应用很多,目前低代码平台以及推送服务都在使用。接下来,我们以最近比较火热的低代码搭建以及推送服务来看下是如何使用的。
▐ 场景一 低代码搭建
随着低代码&零代码热潮的来袭,非开发人员也可通过自由组装、拖拽式组件来 搭建应用,大大降低了商家在日常经营中的成本。在搭建平台中,商家通过智能表单承载商家数据存储、管理、分析等需求,低代码场景下对于存储的要求主要表现为以下方面。
多租户数据模型:支持用户自定义搭建数据模型,模型和数据按租户隔离
免运维:非开发者用户无数据库使用经验和运维能力,如何保证在各数据&流量模型下的稳定性可控
通用存储协议:需支持业界通用数据库协议,以复用集团或开源报表搭建产品
相比传统数据库存储产品,数据空间作为智能应用工作表存储目标的优势主要有以下几点。
无感DDL:与物理模型解耦,业务模型的变更,只需对元数据层进行数据变更,而无需对数据库物理结构变更,即无运行时DDL操作
弹性:使用ADB进行底层数据存储。ADB是分布式数据库,存储计算分离的架构天然具备弹性能力,且数据分散在各个shard上,shard会自动扩展,能够有效解决共享表模式下存在的数据膨胀问题
报表搭建与查询分析:数据空间支持标准MySQL协议,可借助DeepInsight设计器进行报表制作,并加以数据、权限管控,可指定不同商家访问其权限内的数据
运维成本低:平台托管大部分运维操作,用户无需感知数据库实例的存在
▐ 场景二 推送云存储
推送服务历年在大促中中腰部及以下服务商 rds 性能难以管控,一方面存在单库挂载大流量多卖家,集中式的流量存在难以承载的情况,导致推送分组持续 堆积和推送延迟。另一方面,无法确保 rds 的稳定性,大促保障以及运维手段难、以触达,大促期间发生 rds 质量抖动或持续低下等问题屡见不鲜,导致推送延迟。
推送云存储产品是数据空间for推送服务提供的官方云存储空间,在该模式下,将服务商管控的数据库服务托管到平台侧,平台为其提供生态稳定性以及性能保障。相比传统RDS接入,具备更优的弹性能力及业务稳定性。
链路变化
推送服务可以选择订单数据推送到平台自建的推送共享云存储上,服务商从云存储中读取订单数据,进行打包、发货等处理,同时为其保证推送的实时性。
推送服务-RDS | 推送服务-云存储 | 说明 |
数据归属服务商 | 数据归属平台 | 数据归属服务商下,服务商拥有平台核心数据。云存储模式下数据归属平台,服务商仅有数据的只读权限,同时Proxy代理统一管控治理数据,开放更加安全。 |
RDS | RDS/Polar/ADB等 | 数据空间底层可对多存储产品进行支持 |
不支持 | 字段变更无DDL,可随时开放自定义字段,使用自定义字段进行订单筛选 | 推送服务表结构业务字段都在API返回的整个JSON字符串,服务商需要转单后解析JSON获取。云存储模式下,服务商可自定义表结构 |
无法知道服务商作业链路中的SQL处理 | 平台可查看服务商SQL模版 | 平台获取服务商作业链路SQL有助于分析生态履约链路能力瓶颈 |
服务商保证 | 平台保证 | Proxy代理进行数据管控和治理,保证推送写入速率,对服务商不合法以及慢SQL进行治理 |
服务商运维成本高 | 平台托管运维操作 | 平台托管大部分运维操作,深度集成推送业务 |
网络架构
数据空间弹内部署支撑低代码搭建。对于推送服务,数据空间单独部署一套服务 在聚石塔下生产网(部署二方业务组件或应用的网络区域)内。
云存储-Core 主要进行实例、账号、权限、连接串、表结构等管理。通过云通道调用数据空间服务。使用privatelink进行租户VPC和生产网的打通,部署在聚石塔内的推送客户端和服务商的转单服务通过分配的数据库逻辑实例连接串访问推送云存储服务。
该方案在网络上可行,但由于经过了多跳网络信息,协议侧已经丢失了连接地址信息,如何获取如何获取逻辑实例信息是一个难点。目前解决方案是开启 SLB TCP 四层监听的ProxyProtocol配置,通过Proxy Protocol协议携带客户端源地址到后端服务器, Proxy 代理侧 Netty 解析 HAProxy 协议,取出其中的终端节点信息进行用户身份识别后,再进行MySQL协议的解码。
流量控制
平台为了保证服务商线上推送写入服务质量,需要对服务商SQL进行治理,防止数据库被击穿,需要在Proxy侧进行流控,限制底层数据库连接。由于共享存储模式下,多个云存储实例连到一台数据库实例上,需要使用分布式并发度流控方案。虽然可以给每台应用服务器平均分配流控配额,把问题转换为单机流控,但如果碰到流量不均匀、机器宕机、临时扩缩容等场景,这种做法的效果不佳。
分布式环境下做流控的核心算法思路其实与单机流控是一致的,区别在于需要实现一种同步机制来保证全局配额。推送云存储采用ZK+Redis来实现。
详细流程如下:
服务器启动时,将IP注册到Zookeeper上,动态监听上下线节点
MySQL连接建立成功,鉴权通过后,需要在Redis中向IP节点添加该云存储实例,连接销毁时,清除该IP节点下的实例
执行真正的业务SQL前,尝试去获取令牌,SQL执行完,归还该令牌
服务器下线时,清除该IP节点下的实例列表
获取令牌主要是在Redis中记录当前云存储实例在机器上的连接数,详细逻辑如下。
//获取令牌逻辑
lock
int count = count (hvals instanceId)
if(count + 1 > limit)
ERROR(RATE_LIMIT)
else
hincrby instanceId IP 1
unlock
//释放令牌逻辑
lock
//先获取一次,防止redis重启
int value = hget instanceId Ip
if value == false
return
else if value == "0"
return
else
hincrby instanceId IP -1
unlock
总结
目前数据空间初步技术架构雏形已经具备,作为官方存储已经在低代码平台和推送服务中使用,完成了阶段性里程碑,涉及的技术细节还比较多,当然数据空间适用的场景和业务还并不完善,毕竟需要像Salesforce一样使用自研的SOQL查 询语言也不太现实,适配完整的 MySQL 协议工作量也比较大,目前基础能力还有待完善,未来的规划和需要解决的问题是:
存储弹性。多租户数据库跨所有租户共享计算和存储资源,如何保证保证租户之间不受影响的情况下,进行弹性伸缩是我们需要解决的问题。
协议适配。元数据存储模型为数据模型带来灵活多变的同时,如何开放给商家和生态合作伙伴无门槛使用是亟需解决的问题之一。目前数据空间针对二方开放一套简版 SDK,对于三方通过自建 Proxy 适配 MySQL 协议,让客户无感知连接平台数据库。协议适配工作量巨大,要完全和 MySQL 标准协议对其需要一个漫长的过程,但自建 Proxy 的好处是SQL可以完全控在我们自己手上,针对不支持的SQL或者平台不希望执行的 SQL可以进行拦截。
业务稳定性治理。数据空间终极目标还是为上层各类业务服务的,如何针对不同类型业务定制不同的规则也是需要解决的一个难点。例如:针对推送服务,基于数据空间无感DDL的设计,开放自定义字段; 针对不规范SQL使用,使用隔离、限流、并发度控制等一系列手段治理; 还可以基于查询SQL优先级进行读取,同时平台管控SQL的另一大好处,可以为品牌商家生态全链路履约监控服务提供数据支持,帮助商家发现履约链路问题。
团队介绍
大淘宝技术开放平台,是阿里与外部生态互联互通的重要开放途径,通过开放的产品技术把阿里经济体一系列基础服务,像水、电、煤一样输送给我们的商家、开发者、社区媒体以及其他合作伙伴,推动行业的定制、创新、进化, 并最终促成新商业文明生态圈。
我们是一支技术能力雄厚,有着光荣历史传统的技术团队。在历年双十一战场上,团队都表现着优异的成绩。这里承载着每秒百万级的业务处理,90%的订单通过订单推送服务实时地推送到商家的ERP系统完成电商作业,通过奇门开放的ERP-WMS场景已经成为仓储行业标准。随着新零售业务的持续探索与快速发展,我们渴求各路高手加入,参与核心系统架构设计、性能调优,开放模式创新等富有技术挑战的工作。
¤ 拓展阅读 ¤
3DXR技术 | 终端技术 | 音视频技术
服务端技术 | 技术质量 | 数据算法