天天看點

中繼資料驅動架構的官方資料空間設計

作者:閃念基因

淘寶開放平台是阿裡與外部生态互聯互通的重要開放途徑,通過開放的産品技術把阿裡經濟體一系列基礎服務,像水、電、煤一樣輸送給我們的商家、開發者、社群媒體以及其他合作夥伴,推動行業的定制、創新、進化, 并最終促成新商業文明生态圈。

開放業務場景常常跟随内部業務的變化,在資料層面上會頻繁發生變更。傳統資料庫在成本、易用性方面無法很好滿足生态異變場景的需求。資料空間的探索,是為了在生态場景中支撐業務快速增長的基礎上,提供一個可存儲海量資料、單表可自動擴容、字段可無限擴充、查詢效率不低于 MySQL 資料庫的産品。如何以一套統一的資料架構,支援不同使用者按需自定義資料模型,保證資料定義層面的擴充和變更不會影響自身和其他租戶業務功能的可用性,将資料和能力內建在平台自身。為此我們打造官方彈性存儲空間,在安全可控的情況下沉澱資料支撐更多業務場景标準化開放內建。

中繼資料驅動架構的官方資料空間設計

多租戶資料模型

我們先站在巨人的肩膀上來看看業界有哪些通用的多租戶存儲模型。

中繼資料驅動架構的官方資料空間設計

資料空間采用類似Salesforce的大寬表模型設計,通過SAAS化的方式開放給開放業務使用。中繼資料對于平台而言,存儲的是所有租戶的資料。對于租戶而言,每個租戶/組織隻能看到和定義按照自己租戶OrgID隔離的它自己版本的中繼資料和資料, 而且隻能執行自己租戶OrgID所授權的行為,這樣每個租戶就擁有各自版本的SAAS方案。

▐中繼資料驅動的多租戶資料架構

資料空間通過業務場景&租戶次元隔離每個租戶下自己版本的中繼資料和資料,整個架構分為以下5個邏輯層次。

  1. 底層資料存儲層:存儲了租戶底層資料結構以及對底層資料的對象和字段定義資訊,支援多種存儲類型
  2. 存儲引擎路由層:根據業務場景及租戶定制,路由到不同的存儲産品中執行
  3. 中繼資料層:中繼資料模型主要由對象、字段以及底層資料表組成。中繼資料執行引擎是将業務邏輯模型映射到統一的中繼資料存儲模型最核心的能力,我們常說的ORM功能也是其核心功能,但比其複雜的多
  4. 平台接口層:對外提供資料空間SDK和标準MySQL協定兩種調用方式。資料空間SDK中包含對象模型的建立、簡化版的SQL執行等操作。标準MySQL協定通過自建MySQL代理層對外提供資料庫服務
  5. 業務場景層:資料空間對外服務的特色業務場景
中繼資料驅動架構的官方資料空間設計

▐中繼資料存儲模型

資料空間整個存儲采用了與業務無關的寬表設計,可擴充性非常好。底層資料使用動态列存儲,加以額外的中繼資料描述資訊。資料模型設計包含以下幾部分:

  1. 對象中繼資料表:存放使用者自定義和定制化的對象
  2. 字段中繼資料表:對象下字段的定義,包括字段類型、字段映射在真實存儲中的位置、是否需要索引、字段校驗規則等
  3. 資料表:存放使用者真實業務資料,由靈活可擴充的彈性列組成,通過對象和字段的中繼資料定義映射到真實的存儲

與Salesforces不同是,這裡并沒有維護索引表,索引的維護非常複雜,針對ADB有全列索引,并不需要建索引。針對關系型資料庫,不使用共享寬表模式的情況下,DDL獨立建索引會更為靈活。

中繼資料驅動架構的官方資料空間設計

基于這個設計可以實作資料空間的彈性列無感DDL,當增加一個資料列時,僅需要選取Data表中相同值類型的資料列,加入到邏輯表字段模型中即可,無需進行顯式DDL。

▐ 中繼資料執行引擎

中繼資料執行引擎由中繼資料映射、建構語句、組裝SQL、執行語句、反中繼資料映射五個部分組成。使用者業務SQL經過引擎執行後映射成與業務無關的中繼資料存儲模型SQL,路由到相應的邏輯租戶資料庫執行,執行成功後再反中繼資料映射成使用者真實的對象資料。通過中繼資料執行引擎,就可以實作在統一的多租戶中繼資料存儲模型上承載多租戶自定義的資料需求。

中繼資料驅動架構的官方資料空間設計

下面是一個簡單的例子。

中繼資料驅動架構的官方資料空間設計
中繼資料驅動架構的官方資料空間設計

通用存儲協定支援

為了友善使用者使用習慣,資料空間除了自身提供SDK調用方式外,還需要适配标準MySQL協定。

對外接口 說明 優點 缺點
資料空間SDK MySQL語句簡版描述 可以通過代碼實作資料通路,适合java程式設計習慣
  1. 可擴充性差
  2. 複雜SQL描述難
  3. 類型轉換複雜
  4. 通用型不強,對接業界查詢引擎困難
MySQL協定 提供MySQL代理,對外适配MySQL協定 通用性強,通過資料庫代理可做治理和管控 技術成本較大,需要平台自建代理層,代理穩定性需要保障

▐ MySQL Proxy

在抽象的多租戶中繼資料模型下,協定層開發的技術成本以及難度還是非常大的。資料空間選用開源中間件Sharing-Proxy作為MySQL代理對外提供資料庫服務,隐藏底層中繼資料存儲模型,使用者不需要感覺底層資料存儲。Sharding-Proxy的定位是透明化的資料庫代理,它封裝了資料庫二進制協定,用于完成對異構語言的支援,我們先來看下它原始的架構圖。

中繼資料驅動架構的官方資料空間設計

Frontend層實作了MySQL協定的編解碼。原始Sharing-Proxy 得到解碼的MySQL指令後,開始調用Sharding-Core對SQL進行解析、路由、改寫、結果歸并等核心功能,在Backend層與真實資料庫的互動。

資料空間由于有一套自定義的中繼資料模型,解耦了使用者邏輯模型和底層實體模型,需要對Sharing-Proxy進行改造。

  1. Frontend層:MySQL協定層編碼/解碼保持不變
  2. Backend層:與真實資料庫的互動并不需要,根據存儲路由,存儲到相應的實體庫即可
  3. Core-module層:得到解碼的SQL指令後,需要解析文法樹,對中繼資料進行映射,調用執行引擎執行
中繼資料驅動架構的官方資料空間設計

改造中最核心的部分在于Core Module層。在Sharding-Proxy的線程模型中,Frontend層使用IO多路複用處理用戶端請求,後端使用HiKari連接配接池同步請求資料庫,User Executor Group用于執行MySQL指令。

中繼資料驅動架構的官方資料空間設計

核心層(Core-module)的執行過程委托給CommandExecuteEngine完成,流程如下:

中繼資料驅動架構的官方資料空間設計

Sharding-Proxy擷取SQL指令執行器的流程保持不變,我們主要對解析Statement語句和SQL解析執行引擎進行修改。

▐ SQL解析執行引擎

在資料空間中,我們把SQL執行的整體結構劃分為以下幾部分。

  1. 解析器。ShardingSphere采用完全自研的antlr進行解析,通過測試發現非常耗時,資料空間改成Druid解析後性能提升5倍
  2. 提取器。這裡需要将AST節點進行深入解析,封裝成資料空間簡版SDK
  3. 建構器。這裡指建構查詢請求包需要的字段定義資訊,包含字段名、表名、字段類型、字段長度等基礎參數,由中繼資料擷取。
  4. 執行器。交由資料空間中繼資料執行引擎執行
中繼資料驅動架構的官方資料空間設計

▐引擎更新

在上述解析執行過程中,SQL協定層需要将SQL解析成資料空間規定的協定格式再執行,存在着以下問題。

  1. 可擴充性差。每次适配新的SQL語句都需要修改提取器和底層中繼資料執行引擎,改造成本較大
  2. 複雜SQL描述難。資料空間規定的協定格式對于簡單SQL描述起來比較容易,但對于子查詢、多表查詢等複雜類SQL描述起來較為困難
  3. 類型轉換複雜。在執行參數準備以及結果傳回參數過程中,都需要進行類型的轉換,負擔還是比較大的。對于MySQL支援的标準查詢文法,轉換邏輯需要考慮的非常全面

基于以上考量,為了保證代理層的穩定性,對上述SQL解析執行引擎進行了整體更新改造。解析、建構過程不變,增加了改寫引擎,并将改寫後的SQL語句經過執行引擎處理。

中繼資料驅動架構的官方資料空間設計

SQL改寫在中繼資料存儲模型下需要将使用者真實字段改寫為底層真實存儲的彈性列,詳細改寫規則如下。

中繼資料驅動架構的官方資料空間設計
  • 辨別符改寫

由于中繼資料底層真實存儲其實是彈性列,業務側表名和字段名都是邏輯上的概念,需要改寫的辨別符包括表名稱、字段名稱等。表名稱改寫是指解析AST,擷取邏輯表名,并找到中繼資料定義,将其改寫為真實表的過程。字段名稱改寫是指解析抽象文法樹,将所有的字段列改寫為真實字段列的過程。

  • 補列

在多租戶資料架構下,租戶之間資料依賴業務類型&租戶ID進行邏輯隔離,需要補列的唯一情況就是所有語句都需要增加租戶查詢條件(租戶+業務類型+表模型)。

▐标準協定層适配

對于協定層SQL需要進行單獨适配。包括:

  1. information_schema庫
  2. MySQL系統變量
  3. set/commit語句等

比如,對于information_schema中繼資料庫中的庫表和字段中繼資料資訊,我們需要查詢中繼資料定義資訊,并封裝傳回結果包傳回,這裡就不一一贅述。

中繼資料驅動架構的官方資料空間設計

整體技術架構

至此整個官方資料空間的基本形态和架構已經建構完成。以中繼資料管理為核心,向上提供租戶模型管理、資料服務、資料分析等能力,并通過MySQL Proxy和資料空間SDK完成能力暴露。

具體的技術大圖如下:

中繼資料驅動架構的官方資料空間設計
中繼資料驅動架構的官方資料空間設計

應用場景

官方資料空間在業務場景上的應用很多,目前低代碼平台以及推送服務都在使用。接下來,我們以最近比較火熱的低代碼搭建以及推送服務來看下是如何使用的。

▐場景一 低代碼搭建

随着低代碼&零代碼熱潮的來襲,非開發人員也可通過自由組裝、拖拽式元件來 搭建應用,大大降低了商家在日常經營中的成本。在搭建平台中,商家通過智能表單承載商家資料存儲、管理、分析等需求,低代碼場景下對于存儲的要求主要表現為以下方面。

  1. 多租戶資料模型:支援使用者自定義搭建資料模型,模型和資料按租戶隔離
  2. 免運維:非開發者使用者無資料庫使用經驗和運維能力,如何保證在各資料&流量模型下的穩定性可控
  3. 通用存儲協定:需支援業界通用資料庫協定,以複用集團或開源報表搭建産品
中繼資料驅動架構的官方資料空間設計

相比傳統資料庫存儲産品,資料空間作為智能應用工作表存儲目标的優勢主要有以下幾點。

  1. 無感DDL:與實體模型解耦,業務模型的變更,隻需對中繼資料層進行資料變更,而無需對資料庫實體結構變更,即無運作時DDL操作
  2. 彈性:使用ADB進行底層資料存儲。ADB是分布式資料庫,存儲計算分離的架構天然具備彈性能力,且資料分散在各個shard上,shard會自動擴充,能夠有效解決共享表模式下存在的資料膨脹問題
  3. 報表搭建與查詢分析:資料空間支援标準MySQL協定,可借助DeepInsight設計器進行報表制作,并加以資料、權限管控,可指定不同商家通路其權限内的資料
  4. 運維成本低:平台托管大部分運維操作,使用者無需感覺資料庫執行個體的存在
中繼資料驅動架構的官方資料空間設計

▐場景二 推送雲存儲

推送服務曆年在大促中中腰部及以下服務商 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來實作。

詳細流程如下:

  1. 伺服器啟動時,将IP注冊到Zookeeper上,動态監聽上下線節點
  2. MySQL連接配接建立成功,鑒權通過後,需要在Redis中向IP節點添加該雲存儲執行個體,連接配接銷毀時,清除該IP節點下的執行個體
  3. 執行真正的業務SQL前,嘗試去擷取令牌,SQL執行完,歸還該令牌
  4. 伺服器下線時,清除該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 協定工作量也比較大,目前基礎能力還有待完善,未來的規劃和需要解決的問題是:

  1. 存儲彈性。多租戶資料庫跨所有租戶共享計算和存儲資源,如何保證保證租戶之間不受影響的情況下,進行彈性伸縮是我們需要解決的問題。
  2. 協定适配。中繼資料存儲模型為資料模型帶來靈活多變的同時,如何開放給商家和生态合作夥伴無門檻使用是亟需解決的問題之一。目前資料空間針對二方開放一套簡版 SDK,對于三方通過自建 Proxy 适配 MySQL 協定,讓客戶無感覺連接配接平台資料庫。協定适配工作量巨大,要完全和 MySQL 标準協定對其需要一個漫長的過程,但自建 Proxy 的好處是SQL可以完全控在我們自己手上,針對不支援的SQL或者平台不希望執行的 SQL可以進行攔截。
  3. 業務穩定性治理。資料空間終極目标還是為上層各類業務服務的,如何針對不同類型業務定制不同的規則也是需要解決的一個難點。例如:針對推送服務,基于資料空間無感DDL的設計,開放自定義字段; 針對不規範SQL使用,使用隔離、限流、并發度控制等一系列手段治理; 還可以基于查詢SQL優先級進行讀取,同時平台管控SQL的另一大好處,可以為品牌商家生态全鍊路履約監控服務提供資料支援,幫助商家發現履約鍊路問題。

作者:龐煜芬(玉瑤)

來源:微信公衆号:大淘寶技術

出處:https://mp.weixin.qq.com/s/ZV23sKa-KrNcGTgQuq64aA

繼續閱讀