天天看點

促科技創新:高德資料優化篇之OceanBase最佳實踐

作者:閃念基因

背景

高德成立于2002年,是中國領先的移動數字地圖、導航及實時交通資訊服務提供商,向終端使用者提供包括導航、本地生活、叫車等服務的一站式入口。從擁有甲級測繪資質的領先地圖廠商,到首家成功轉型移動網際網路的地理資訊企業,再到國民出行平台,以及出門好生活開放服務平台。業務一直在進化,但高德“讓出行和生活更美好”的初心未變,本質的核心專注點一直沒有改變,就是地圖導航,擁有從資料到軟體到網際網路的完整研發能力和經驗,同時在人工智能、大資料、計算機視覺等一系列新技能方面也擁有深厚的積累。

地圖是什麼?它是真實(實體)世界在網絡空間的數字化映射;高德的目标就是“連接配接真實世界,做好一張活地圖”。作為如今各行各業都非常關注的一個概念,“數實融合”代表大家對于實體經濟進一步更新發展的期望,代表着能力和效率的現象級提升,以及面向使用者和消費者的更優質産品和服務。而要做到這一點,其中的關鍵在于推動實體經濟和數字經濟的高度融合,對于高德地圖所在的交通出行行業來說,也是如此。我們緻力于用“促科技創新、與生态共進”的方針,助力交通産業更好的實作數實融合。

從高德的視角,對于“數實融合”的了解是什麼樣的?一方面,我們明确了包括人、車、路、店等在内的實體要素,才是交通出行産業中的真正主體,相關領域中耕耘多年的企業和機構,才是真正值得尊重的老師傅,他們在各自領域的專業度和經驗不可或缺;另一方面,科技創新平台提供了交通服務和海量使用者之間的連接配接能力、數字化的展示平台,提供了産業要素轉化為資料的能力,并且還能為各類新型交通服務提供強大的計算能力。

高德的二十餘年,始終與大交通産業中其他領域的老師傅攜手共進,尊重他們的專業領域,尊重他們的不可或缺,才得以與他們建立起了深厚的合作關系,成為他們服務的科技标配。2022年10月1日,中國國慶黃金周假期的首日,高德實作了創紀錄的2.2億日活躍使用者。在2023年3月,受到日益增長的同城通勤和城際出行需求推動,高德的日均活躍使用者數量達到了1.5億的新紀錄。

高德一直不斷地探索和應用新的技術,以持續提升使用者體驗、提高效率和降低成本。

首先是北鬥高精度定位。作為一家科技企業,高德有幸見證了北鬥從起步到世界一流的發展曆程。尤其是2020年的北鬥三号全球組網成功,客觀上幫助我們在産品研發上迅速打開了新局面,車道級導航、智能紅綠燈、綠色出行和位置共享報平安等一系列基于北鬥高精尖技術的服務得以在手機上落地,并獲得了行業内外的好評。如今,高德地圖調用北鬥衛星日定位量已超過3000億次,且在定位時北鬥的調用率已超越了GPS等其他衛星導航系統。

網際網路地圖使用者高并發通路和随之而來的海量資料存儲處理,是我們必須應對的技術難題。其中,雲原生和行業無關化架構是高德地圖服務端未來的努力方向。雲原生是一個新的軟體架構模式,它将應用程式和系統環境抽象化,并将它們封裝到容器中,以實作快速、可靠和可擴充的部署和管理;雲原生是未來軟體架構的發展趨勢,它的本質是更高次元的抽象、封裝和屏蔽,高德地圖服務端會聚焦于把雲原生相關技術用到日常應用研發,以提高生産力,快速疊代産品,跟業務一起給使用者最好的體驗。行業無關化架構是針對高德應用的特點提出的,核心是解決研發效率的問題,業務上讓更多的行業快速接入高德,技術上嘗試中繼資料驅動+多租戶隔離,屏蔽行業變化對底層的影響,做到行業無關化架構,以進一步提高生産力。

随着“高德地圖”成為使用者出行必備工具之一,其中資料的存儲、加密、快速檢索和絕對安全就非常重要,是我們工作的重點,目的是讓使用者在任何時刻、不同的端裝置上都能快速的獲得自己想要的真實世界的資訊,讓使用者出行更美好。随着業務後續發展很快就會進入萬億時代,無論是存儲成本,還是針對資料查詢的性能來講,資料治理對我們來說顯得尤其重要,我們要讓資料快速發揮出價值,帶給使用者最真實最實時的資料,還不會過度的浪費成本。

OceanBase是由螞蟻集團完全自主研發的國産原生分布式資料庫,始創于2010年。OceanBase已連續10年穩定支撐雙11,創新推出“三地五中心”城市級容災新标準,在被譽為“資料庫世界杯”的TPC-C和TPC-H測試上都重新整理過世界紀錄。自研一體化架構,兼顧分布式架構的擴充性與集中式架構的性能優勢,用一套引擎同時支援OLTP和OLAP的混合負載,具備資料強一緻、高擴充、高可用、高成本效益、高度相容Oracle/MySQL、穩定可靠等特征,不斷用技術降低企業使用資料庫的門檻。

經過長時間的調研和測試對比,我們決定采用成本效益最佳的OceanBase來迎接高德萬億(條)資料時代!

促科技創新:高德資料優化篇之OceanBase最佳實踐

讀者收益

正因為真實世界的資料存儲量大,高德采用的OceanBase來解決,此篇文章會讓大家看到OceanBase在高德的實踐體會,我們會從不同的視角去诠釋整篇文章。整體如下:

服務端的視角

1)我們為什麼選擇OceanBase?

2)OceanBase在高德落地過程中分應用的融合方案、痛點和收益?

3)OceanBase在高德應用中未來的規劃?

讀者的視角

1)高德為什麼選擇OceanBase,背後選擇的原因是什麼?

2)高德怎麼用OceanBase的,方案是什麼,遇到了哪些問題,解決方案是什麼?

3)OceanBase在高德應用場景中,表現結果怎麼樣,穩定性和性能怎麼樣,降本效果怎麼樣?

4)結合我們自己的場景哪些可以用OceanBase幫我們解題?

以下用OB代替“OceanBase”,整篇文章也會圍繞幾點來貫徹核心思想:

1)了解選擇OceanBase的原因,了解OB的落地實踐

2)了解分布式資料庫和OB相關技術内幕

3)作為工具文章,在猶豫是否選擇OB的時候會給大家一些思路

1.為什麼選擇OB

阿裡雲提供的資料存儲産品有很多, 簡單羅列幾個常用的(排名不分先後,沒寫進來的不代表不好)

  • PolarDB
  • Lindorm
  • OB
  • ES
  • MongoDB
  • ...

每種存儲都有自己的特色,有關系型資料庫,有分布式資料庫,有列族資料庫等在不同的場景都表現十分出色。然而我們為什麼選擇了OB呢?

其實從21年開始,我們就一直在做一個事,就是去MongoDB。過去高德有一些業務服務用的MongoDB做存儲,由于MongoDB的特性和設計特點,導緻它偶爾會出現CPU占用很高,服務Pause無法正常提供服務。 對于上遊來說展現就是逾時問題了,如果通路量大且重試帶來的階梯效應就是毀滅的,服務基本被打垮。很多時候不是MongoDB本身的問題,它定義是分布式文檔存儲系統,通過Documents的方式來維護資料,理論上在關系型比較重的場景上确實不太适合。

後來我們服務就相繼的遷移到XDB、Lindorm、ES。選擇ES是因為成本低和穩定性高;選擇Lindorm是因為對于我們的異構場景、Key Value場景和減少請求穿透到XDB的場景非常合适。那麼就剩下資料庫選型了,雖然OB是NewSQL資料庫,但是他保留了關系型資料庫的特性,讓我們以NewSQL的方式去管理資料,但不是說明任意場景都比較适合,在結構化資料量大的體系中,OB在降本上非常具有優勢。

那麼這裡又有一個疑問?Lindorm和ES不也可以做這種存儲嗎? 存儲和檢索都非常高效。 但是從工具的角度Lindorm和ES對我們來說都是加快檢索和異構檢索使用的,無法真正像關系型資料庫那樣去使用,往往後面都會存在一個資料庫,會嚴重增加資料沉餘和成本。

針對資料庫的場景,我們其實都關注兩點:OLTP和OLAP。PolarDB是天然的OLTP,分布式MySQL引擎後續架構也支援了OLAP設計。 然而OB本身設計就是NewSQL模式,天然具備OLTP和OLAP兩種場景,而且針對大資料有自己的壓縮體系,在降本和應用都有天然的優勢。

1.1 OB基礎屬性資訊

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 1.1 OB的基礎屬性資訊

1.2 經過多方面平衡,解釋下我們為什麼要選擇OB?

1)OB是基于Paxos一緻性協定實作的資料多副本存儲(多版本并行送出),滿足多數派即可傳回,最終一緻性。

2)采用無共享的多副本架構,系統沒有單點障礙,保證系統持續可用。即使單副本出現故障,也可以達到多數派可用。

3)OB是可以動态擴容的,擴容後分區表的資料會自動均衡到新節點上,對上層業務透明,節省遷移成本。

4)OB存儲具有高度壓縮的能力,資料可以壓縮到原有資料到三分之一,對于存儲量大的業務會極大降低存儲成本。

5)OB作為準記憶體資料庫,采用LSM-Tree存儲引擎,增量資料操作記憶體,減少随機寫,讀寫性能超傳統關系型資料庫,而且支援Hash和B+Tree。

6)比較重要的是OB也支援MySQL的協定,可以直接使用MySQL驅動通路,可以基本完全的将OB當成分布式的MySQL使用。

在布式資料庫出來之前,針對大資料量的讀寫場景廣泛采用分庫分表方案,也由此誕生了很多分庫分表、讀寫分離中間件。這些方案雖然能帶來一定的效果,也會引發一些後遺症,比如:

  • 需要提前規劃好分片規則,一旦定好規則就難以移動,擴充困難
  • 分得太細會浪費資源,分得太粗會導緻二次拆分
  • 資料遷移困難

說到這裡,大家應該還沒太多體感,那麼我們會從分布式資料庫和OB的一些技術角度去诠釋上面的決策點(為友善更好的做決策,主要講一些相應的分布式資料庫和OB技術原理,了解的同學可以直接跳過)。

2. 雲原生分布式資料庫和OB技術内幕

2.1 雲原生資料庫的發展曆程

雲原生分布式資料庫發展曆程,經曆以下3個階段。

  • 單機:傳統單機資料庫、依賴高端硬體、系統難以擴充、成本高。
    • PG-XC:基于中間件的分布式資料庫(TDDL)。待解決全局一緻性、跨庫事務、複雜的SQL等問題。
    • NewSQL:高可用、水準擴充、分布式事務,全局一緻性、複雜SQL、自動負載均衡、OLAP等。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.1 資料庫發展曆程 (圖檔引自OceanBase)

3個階段衍生出3種架構,但是統一被歸整為NewSQL和PG-XC的2大類風格

  • Sharding on MySQL:一般我們可以在應用側或者代理層做分片來管理多個MySQL實體庫,以解決單機容量和性能不足的問題。現在正在使用的TDDL就是該架構,雖然計算存儲資源可擴充,但在擴充和資料遷移時,業務系統層面需要做不少改造和業務資料的灰階,為了保證業務不停機會産生比較大的改造成本和資料遷移的風險。(PG-XC風格)
    • NewSQL:國内以TiDB和OceanBase為代表的原生支援分布式的關系型資料庫,主要也是為了解決MySQL的問題。和Sharding on MySQL不同的是,NewSQL将分片功能作為資料庫的一部分來實作,并提供了動态擴縮容的能力,且對上層業務透明,具備透明可擴充性。
    • Cloud Native DB:雲原生資料庫國内以PolarDB為代表,具備池化的資源,也可以實作存儲資源的動态擴縮容,其一般采用的主備方式來實作高可用,同時其擴容和主備探活等功能需要大量依賴外部系統。(PG-XC風格)
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.2 資料庫3種架構 (圖檔引自阿裡雲[1])

從架構體系又分為2種流派

  • Shard-Nothing:架構的每個節點有獨立的計算和存儲功能并且節點之間不共享資料
    • 無狀态SQL計算節點,無限水準擴充
    • 遠端存儲,共享存儲節
    • 強SQL支援( 系統自動擴充路由 )
    • 和單機一樣的事務支援
    • 跨資料中心故障自動恢複
    • 無限的彈性水準擴充
    • Shard-Everying:也叫Shard-Storage,即Shared-Disk,架構是在存儲層做了統一和共享,但計算節點是獨立節點
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.3 資料庫架構的2種流派 (圖檔引自論文Survey of Large-Scale Data Management Systems for Big Data Applications)

從上述圖可以看出來,Shard-Everying的存儲是共享的,前面計算節點多,查詢量極大的情況下就會造成共享存儲壓力過大,導緻查詢性能非常低下。Shard-Nothing的則不然,有獨立的計算和存儲節點,資料不共享性能可靠,市面上的NewSQL大多數都是依照Google 的Spanner/F1來進行設計的,這裡先簡單介紹下Spanner/F1職責:

  • F1設計的目标
    • 無限彈性水準擴充
    • 跨資料中心故障自愈
    • 事務的ACID一緻性
    • 全面的SQL支援,支援索引
  • Spanner設計的目标
    • 管理跨資料中心複制的資料
    • 重新分片和平衡資料的能力
    • 跨資料中心遷移資料

到這裡想必大家都知道什麼是NewSQL了, 完美的具備關系型資料庫的基因且具備更加強的擴充性和性能,其實NewSQL跟分布式資料庫不能完全畫等号的。NewSQL還是遵循事務ACID,SQL引擎那一套,保證的是無縫遷移。但是分布式資料庫強調的是最終一緻性,也是NewSQL要展現的,是以NewSQL是在原生分布式資料庫上建構而成的“雲原生分布式資料庫”,有點繞嘴,用簡單的描述來闡述下兩種事務模型,大家平時用的最多的也是事務相關。

2.2 OB的技術内幕

資料庫有3大特征,上文介紹了OLTP 3大特征(SQL解析、事務、存儲)中的2種,分别為事務&存儲。 接下來會介紹OB的技術内幕。然後也會介紹下OB在OLAP上的表現。

先介紹OLAP 3個特性:列存(解決寬表)、壓縮(減少存儲空間)、向量化SIMD (Single Instruction Multiple Data) 即單條指令操作多條資料——原理即在CPU寄存器層面實作資料的并行操作

2.2.1 OB存儲引擎

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.4 OB存儲引擎架構 (圖檔引自OceanBase)

關鍵設計:

1)基于LSM理念自研底層存儲引擎,未選擇RocksDB

2)宏塊與微塊存儲媒體,微塊是資料的組織單元,宏塊則是由微塊組成。Compact操作時可以在宏和微塊兩個級别判斷,是否複用

3)多Parttion多副本解耦Compact操作,避免磁盤IO競争

4)控制User IO/System IO,減少前台請求影響

5)按行存儲,按列編碼,減少體積

6)三副本Compaction的Checksum防止靜默錯誤

7)支援分布式事務

8)支援B+Tree和Hash索引模式,針對熱資料做了很多優化,查詢效率很高,本身也通過Bloom Filter Cache來加速查詢

特性:

  • 低成本,自研行列混存的壓縮算法,壓縮率較傳統庫提高10+倍。
  • 易使用,支援活躍事務落盤來保證大事務的正常執行和復原。多級轉儲和合并來平衡性能和空間。
  • 高性能,提供多級緩存保證低延時。OLAP操作提供向量化支援。
  • 高可靠,全局合并時多副本比對和主表與索引表比對校驗和來保證使用者資料正确性。

多類型緩存, 覆寫資料通路全鍊路

  • 資料緩存:
    • Bloom Filter Cache:維護緩存靜态資料的Bloom Filter,快速過濾無需通路的資料。當一個宏塊上的空查次數超過某個門檻值時,就會自動建構BloomFilter Cache。
    • Row Cache:資料行緩存,在進行單行或多行通路時建構并命中。
    • Block Index Cache:描述對每個宏塊中所有的微塊的範圍,用于快速定位微塊。
    • Block Cache:微塊緩存,在對資料塊通路是建構和命中。
    • Fuse Row Cache:資料在多SSTable中的融合結果。
    • ···
  • Metadata緩存:
    • Partition Location Cache:用于緩存Partition的位置資訊,幫助對一個查詢進行路由。
    • Schema Cache:緩存資料表的元資訊,用于執行計劃的生成以及後續的查詢。
    • Clog Cache:緩存Clog資料,用于加速某些情況下Paxos日志的拉取。

總結:

  • 改進底層SSTable的存儲結構,通過宏和微塊的模式,解決寫放大的問題,而且可以随時調整Compact時機,在挪移Parttion的時候,底層資料存儲單元非常适合快速移動。
  • 本身OB也會對底層存儲進行監控,控制Compact時機,不會導緻前端請求收到影響,在Compcat也會針對資料進行對比,防止靜默導緻資料錯亂,而且壓縮比高,整體體積很小。
  • 講解存儲和為什麼MySQL不能Online DDL等。 主要介紹B+Tree和LSM的存儲差別。

2.2.2 資料複制-Paxos

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.5 資料複制Paxos (圖檔引自OceanBase)

關鍵設計

1)Paxos與Raft最本質的差別是在于是否允許日志空洞,Raft必須是連續的,隻能串行無法并行,Multi-Paxos允許日志空洞存在,應對複雜的網絡環境更魯棒。(市面上有很多針對Raft的優化,以Beth Index的方式去批量疊代Index等)

2)一次WAL日志

示例:

順序投票政策對于主庫的負面影響比較嚴重,出于性能提升的原因,資料庫的MVCC使得不存在互相關聯的事務以并發處理,但是上述的順序投票政策是的事務#5-#9可能呢被毫不相幹的事務#4阻塞,且必須Hold在記憶體

如果是允許日志空洞,事務#5-#9就可以繼續執行,#4後續在落盤

2.2.3 資料複制-延展

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.6 資料複制延展-副本類型 (圖檔引自OceanBase)

關鍵設計

1)全能型副本:擁有事務日志,MemTable和SSTable等全部完整的資料和功能。可以随時快速切換為Leader對外提供服務。

2)日志型副本:隻包含日志,沒有MemTable和SSTable,隻參與投票和對外提供日志服務,也可以參加其他副本回複,但是不能對外提供服務。

3)隻讀型副本:擁有事務日志,MemTable和SSTable等全部完整的資料和功能。他的日志比較特殊,它不作為Paxos承運參與投票,而是作為觀察者實時追趕日志,然後在本地回放。對業務取資料一緻性要求不高的時候提供隻讀服務。

2.2.4 分布式事務

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.7 分布式事務 (圖檔引自OceanBase)

關鍵設計:

分布式事務:2pc + gps線性一緻性事務事務流程:

1)prepare:生成prepare version = max(gts,max_readable_ts,log_ts)。

2)pre commit:推高本地Max readable timestamp。

3)commit/abort:日志多數派成功之後,解行鎖,應答用戶端。

4)clear:釋放參與者上下文。

Percolator模型

關鍵設計:

1)事務第一個分區作為協調者,其他分區作為參與者,事務本地送出,無需等待其他參與者傳回。

2)參與者粒度分區,少部分分布式事務。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.8 Percolator事務模型(圖檔引自OceanBase)

擴充:

1)租戶級别的GPS,基于Paxos保障穩定性。

2)實作類似Truetime的機制,在保證正确的情況下,允許多個事務複用SYS,減少壓力。

提前解行鎖:

優化前:一個事務持鎖的時間,包括了4個方方面:

1)資料寫入

2)日志序列化

3)同步備份機網絡通信

4)日志刷盤的耗時

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.9 事務優化過程解析 (圖檔引自OceanBase)

優化後:

1)日志序列化完成,送出到Buffer Manager之後。

2)就開始觸發解行鎖操作,不等日志多數派刷盤完成,進而降低事務持鎖時間。

3)當事務解鎖之後,允許後續事務進來操作同一行,達到多個事務并發更新的效果,提高吞吐。

2.2.5 向量化+并行執行引擎

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.10 OB并行引擎&向量化 (圖檔引自OceanBase)

上文提到了,AP資料庫3大特性,向量化,資料壓縮,列存。OB的引擎在TP和AP上都有不錯的表現,支援了向量化和并行執行引擎,提升了規模化處理邏輯。

2.2.6 空間優化

OB的存儲上是行列混存的,底層SSTable由若幹個宏塊(Macro Block)構成, 宏塊2M固定大小的長度不可更改。在宏塊内部資料被組織為多個大小為 16KB 左右的變長資料塊,稱之為微塊(Micro Block),微塊中包含若幹資料行(Row),微塊是資料檔案讀IO的最小機關。每個資料微塊在建構時都會根據使用者指定的壓縮算法進行壓縮,是以宏塊上存儲的實際是壓縮後的資料微塊。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.11 OB的存儲引擎空間優化 (圖檔引自OceanBase)

行列混合的存儲結構 :

SSTable由多個定長(2MB)的宏塊組成,而每個宏塊由多個變長的微塊組成。微塊是讀IO的最小機關。OceanBase微塊有兩種存儲方式,平鋪模式(Flat)或編碼模式(Encoding) :平鋪模式即為通常意義上的行存形态,微塊内資料以行的順序連續存儲;編碼模式在微塊裡仍舊存儲完整的行資料,但存儲組織方式則按照列的形式。OceanBase根據資料格式與語義選擇多種編碼手段,以達到最佳的壓縮效果。同時,在執行過程中,資料以列的組織方式載入記憶體提供給向量化引擎,進一步提升HTAP處理性能。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 2.12 行列混合模式圖形詳解 (圖檔引自OceanBase)

OceanBase資料庫提供了多種按列進行壓縮的編碼格式,根據實際資料定義進行選擇,包括列存資料庫中常見的字典編碼,遊程編碼 (Run-Length Encoding),整形內插補點編碼 (Delta Encoding),常量編碼,字元串字首編碼、Hex編碼、列間等值編碼、列間子串編碼等。

2.2.7 OLAP場景支撐

上文我們說了,OLAP場景3大特征 向量化 + 列存儲 + 資料壓縮是AP場景的大殺器,從上面介紹我們看到了,OB是一個引擎滿足TP和AP兩個場景。

  • 支援列存和行存
  • 支援向量化
  • 支援并行計算
  • 支援資料壓縮,根據不同的類型壓縮類型也不同

美中不足的是OB在AP上支援不是特别完美,還在優化中。雖然支援列存儲,但從原理上一個大宏塊裡面包含很多個小微塊,宏塊層面,資料還是按行掃描,微塊層面,一個微塊可能包含若幹行,這些行是按列存儲的。是以OB這個架構還是行存架構,隻有微觀層面能享受部分列存帶來的好處,想要徹底提升分析型性能表現,需要一個徹底的列存引擎。

2.2.8 OB更多場景支援

因為高德業務比較多樣化,分别有結構化和非結構化的場景,OB在支援高德業務的同時也衍生疊代了不同功能行産品。

  • OB 正常模式
  • OB Key-Val模式
  • OB NoSQL模式
  • OB 純列存模式
  • OB Serverless模式

3. OB在高德落地過程中分應用的的融合方案、痛點和收益

OB在高德多個業務場景均有落地,支撐着高德業務資料的穩定性下面将介紹三個不同架構下,典型的業務落地場景:

  • 強一緻金融場景的業務落地
  • 海量資料,多點寫入場景落地
  • 中心寫單元讀場景落地

3.1 強一緻金融場景落地實踐

業務背景及訴求

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.1 财務結算業務架構

高德359行财務結算服務主要服務于高德資訊業務的結算和财務資料,主要訴求是要求資料強一緻性,保障資料不丢失,跨地域容災能力。

業務痛點與技術解題

  • 财務結算服務作為與B端商家合作的錢款計算的一環,對資料一緻性有極高的要求,不能出現因資料不一緻或最終一緻而導緻錢款計算錯誤的情況。
  • 财務結算服務業務邏輯複雜,需要降低遷移改造成本,最好能完整相容原業務所使用的SQL協定,平滑替換底層資料庫,不需要業務過多的改造。
  • 為了提升财務結算系統的資料強一緻性,優先選擇了三機房的部署架構。

業務架構圖如下,圖中紅框内容即本次資料遷移OB時涉及到的系統改造部分,使用Diamond做XDB和OB的資料源路由控制,通過OMS做資料遷移,并使用MAC進行遷移前後的兩份資料的核驗。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.2 财務結算OB改造設計

為什麼選擇OB?

1)财務需要資料的強一緻性和跨地域容災,而OB提供的能力完美支援該需求,其提供的跨地域部署的能力,可使得财務資料同時寫入多地域的資料副本中,即使一地域不可用後仍然能保證有完整的資料可用。并且OB的Paxos一緻性協定可保證OB多副本資料寫入成功後才應答成功,為分布式多副本資料的強一緻提供了保證。

2)為了驗證和解決SQL相容問題,未使用OB提供的OceanBase Client去通路OB,而是使用原生的MySQL資料庫的SDK驅動,通過MySQL驅動通路OB,在OB上回放财務全量SQL并驗證通過。

3)為了降低财務結算系統改造量,将OB的表按不同的功能進行建設,将原有分庫分表的設計邏輯應用到OB分區表的分區鍵設計上,以便上層業務可透明的切換資料源。對于資料量比較穩定的維表資料,比如合同資料等,将其建設為單表,避免全局分布式事務,提高頻繁查詢的性能。

  • 解題設計核心要點:

1)遷移資料,将資料從XDB(類似MySQL)到OceanBase的資料平滑遷移。

2)協定相容,驗證OB的SQL協定相容能力,達到業務可平滑遷移應用代碼無須修改 。

遷移方案要點:

資料遷移:通過使用OMS進行資料遷移,資料一緻性的校驗通過使用集團的MAC系統來核對,而實時的資料寫入不一緻問題通過監控方式報警處理。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.3 财務結算系統資料遷移設計

因财務結算非C端業務,核心關注是資料的強一緻型和跨地域容災型。并在平衡成本後,在OB的同城三機房、兩地三中心和三地五中心的部署方案中選擇使用同城三機房的部署方案,既可以實作财務結算的資料一緻性和跨地域容災的目标,也能一定程度上節省成本,後續有需要也可以快速更新為三地五中心部署。

在完全切換OB前,XDB和OB都有全量的業務資料,并可通過MAC每天進行全量資料核對,同時對于增量資料不一緻情況及時報警處理。同時又因為XDB和OB都保有全量資料,是以一旦切流遇到問題,可通過開關一鍵回切原XDB資料庫。

部署架構

  • 采用同地三機房部署
    • OB原生支援能力,多份資料同時寫入,無同步延時問題
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.4 财務結算部署架構

業務收益

  • 提升存儲穩定性,高可用和容災能力,跨地域級别的容災能力。
  • 強一緻的存儲保證,對于結算财務類的資料,保障較高的一緻性,而非用最終一緻性的妥協換取其他方面的能力。
  • 提升擴充性,提升資料庫彈性擴縮容的能力,存儲橫向擴充對上層系統透明,極大降低資料遷移的風險。
  • 資料壓縮,減少資料占用的存儲容量,OB使用的LSM-tree結構存儲最大可壓縮資料至原大小的35%,降低存儲費用成本。
  • 平衡更新:遷移OB後仍然可使用MySQL原生驅動,使用MySQL5.7版本的SQL進行業務功能開發,相容原有存儲(XDB)的協定,極大降低業務系統改造成本。
  • 整理壓測結果

目前壓測資料寫流量在4K左右,RT穩定在1ms左右。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.5 财務結算遷移OB效果收益

3.2 海量資料多點寫入場景落地實踐

業務背景

高德地圖雲同步是高德地圖的基礎業務服務,主要負責資料的雲端存儲,多端裝置資料同步。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.6 多端裝置資料同步雲端設計

雲同步的業務系統部署架構示意圖如下:可以看出雲同步業務使用者多點就近接入,一次請求系統會多次讀寫資料庫,是以可以看出系統需要,支援海量資料,多點寫入,讀寫性能出色的資料庫。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.7 雲同步單元化系統架構

業務痛點與技術解題

業務上需要保證資料多端準确寫入,及時更新,更換裝置後的資料快速讀取;資料上随着高德業務的迅速發展雲同步存儲着大量資料,怎麼做到保證穩定性為前提,追求極緻性能,同時極大的降低業務成本,也是雲同步系統需要技術解題的突破點,從雲同步的業務分析得出整體資料庫選型要求如下:

異地多活、海量資料存儲、低成本

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.8 雲同步選型詳解

可行性分析

可以看出,針對我們的業務場景,OceanBase完全符合了業務上資料庫選型要求,從原理上分析(原理詳見上節):

  • 從成本上,針對雲同步的結構化的海量資料,其"低成本存儲的進階壓縮技術",資料文本壓縮+行列存儲資料特性壓縮,将成本壓縮到極緻,且資料量越大優勢越大。
  • 從原理上,LSM-tree的底層資料結構,記憶體處理增、删、改與批量順序的磁盤寫入極大提高了寫入性能,足以支援了數萬級TPS的資料寫入,其B+樹的索引支撐了數十萬QPS的業務讀請求。
  • 從架構上,其多單元同步鍊路,OMS的秒級資料同步能力,保障了多機房資料同步低延遲支撐了多機房多活的可行性。
  • 從業務上
    • 分布式原生資料庫從本質解決了業務研發需要考慮的分庫分表問題。
    • 業務特性為多端資料同步,可用ID作為分區鍵,所有操作在單分區内完成極大提升讀寫性能。
    • 多語言SDK,支撐各類業務系統,極大簡化對接成本;同時支援SQL形式,更換配置無業務入侵。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.9 雲同步遷移OB可行性分析

落地方案

從原理上分析了整體方案的可行性與業務收益,剩下就是業務資料源切換,主要分為DAO層改造、資料遷移、業務放量,達到目标使用者無感,無損切換資料源。

  • DAO層業務改造,使用OceanBase Client實作業務邏輯改造。
    • 簡單通用的SDK,Java SDK的流式程式設計,簡單易用
    • 業務無SQL語句配置
    • 調用過程SDK封裝業務無感
  • 資料遷移:全量資料遷移,使用集團内部工具DATAX将ID分桶并發拉取,整體數千億資料2天左右完成全量同步,采用OceanBase異地備份恢複能力,将資料同步到其他單元,天級完成。
  • 資料比對:業務自研千億級資料對比、更新、同步架構,實作千億資料天級對比完成,通用架構,實作增量/全量對比/修複。
  • 灰階遷移:資料雙寫,ID次元 白名單/灰階,支援比例控制,核心支援按ID随時復原。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.10 雲同步遷移OB落地方案

部署架構

  • 多點寫入
    • 三地讀寫
    • 無網絡延遲
  • 同城雙主庫容災,異地多活容災
    • 同城資料庫側容災切流
    • 三地業務側容災切流
  • 三地六向資料同步
    • 三地六向秒級同步
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.11 雲同步遷移OB部署架構

業務收益

整體降本明顯,性能出色。

性能-壓測資料:讀單單元8wqps,三單元24wqps,寫2.8wtps,讀in查詢,寫批量寫入,平均RT 均在2~3ms。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.12 雲同步遷移OB收益成果

3.3 中心讀寫單元讀架構落地實踐

業務背景

高德地圖評價業務在輔助使用者出行、交易等決策方面有着積極正向的引導,且評論覆寫與POI的CTR、CVR呈正相關;在本地生活大戰略背景之下,高德評價業務的建設幫助高德地圖從平台采集資料邁入到UGC時代。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.13 評價業務效果展現

從評價業務的形态來看,内容生成有一定門檻,寫入TPS不會太高,但是内容會在高德端内各個入口投放,對RT響應有很高的需求,作為一個讀多寫少的場景,需要有一個支援海量資料存儲,可異地容災,讀寫性能出色的資料庫。

業務痛點與技術解題

  • 評價系統作為整體評價的入口,對于性能有極緻的要求,整體RT必須控制在15ms以内。
  • 為了提升讀性能,整體采用使用者就近接入,三單元讀資料,中心寫入資料,對于讀資料需要異地容災能力。
  • 需要支援後續資料量的持續增長。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.14 評價系統痛點分析

上述按照評價的業務場景,采用OB主備叢集的架構,支撐着整體高德評價系統的大量讀寫,三單的讀性能得到極大提升,主備延遲在秒級,完全滿足性能要求。

為什麼選擇中心寫單元讀?

評價的業務特點決定寫入TPS不會太高,中心寫能滿足目前階段的系統發展訴求,多點寫在容災能力上更優,但是會帶來資料沖突等一系列問題,複雜度更高。綜合系統和業務的發展階段,我們選擇了中心寫單元讀的方案。

為什麼選擇OceanBase?

我們從成本,架構特點等多個方面橫向對比了多個資料庫,最終選擇OceanBase

  • 業務上,業務不斷發展,資料量不斷增長,需要解決資料存儲的瓶頸,OB優異的橫向擴容能力能很好的解決這個問題。
  • 成本上,OceanBase自研的基于行列混存結構/高效數字編碼的存儲壓縮技術,将成本壓縮到極緻,能有效的降低評價資料的存儲成本。
  • 原理上,基于LSM-Tree的底層資料結構,極大提高了寫入性能,足以滿足評價場景的寫入訴求。基于B+樹的索引,能滿足評價場景大量讀的查詢訴求。
  • 架構上,基于OceanBase主備庫的架構,利用叢集原生的複制能力,實作秒級同步,可靠性高。

部署架構圖

  • 中心寫入
  • 中心寫單元讀,架構更加簡單,不用擔心資料覆寫的問題
  • 同城雙主容災,異地多活容災
  • 同城多機房容災切流
  • 三地讀容災切流
  • 三地主備資料同步
  • 利用叢集間原生同步能力,秒級同步
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.15 評價系統部署架構

核心要點:

  • 張北中心主叢集可讀可寫,實作強一緻讀。
  • 上海和深圳為備叢集,通過OB原生的叢集複制能力同步,秒級延遲,實作非強一緻異構存儲的高流量低耗時讀業務。

資料一緻性保障:

  • 實時:OB主備之間通過叢集原生的同步能力,可靠性非常高,基本不需要擔心。
  • 離線:提供離線分析的兜底手段,通過MAC平台T+1分析監控資料一緻性。
  • 延遲監控:OB主備之間通過叢集原生的主備同步延遲監控能力進行監控,叢集級别的複制能力性能很高,正常的延遲都在秒級。

上述采用OB主備叢集的架構,支撐着整體高德評價系統的大量讀寫,三單的讀性能得到極大提升,主備延遲在秒級,完全滿足性能要求。

索引設計實踐

面對大資料量的C端場景,基本都需要建立分區表對資料分片實作存儲的橫向擴容,下面我們就讨論分區場景下的索引設計。評價場景下最核心的模型就是評價基礎資訊,其他如評價标簽、評價元素、評價評分等都可以通過評價ID關聯出來,是以我們主要讨論如何設計索引實作評價主表(appraise_base)高效查詢。

(1)分區鍵設計:

最開始我們使用評價(appraise_id)作為分區鍵

partition by key(appraise_id) partitions 512           

這麼設計的考慮是:通過評價ID進行分區,資料分散比較均勻,同時通過評價ID也是高頻查詢,這種方案是個比較正常且通用的設計,表面上看起來并沒有什麼問題。但是按照線上流量實際壓測時發現一直達不到預期效果。我們開始靜下心來和OB同學一起分析原因:

分析業務流量發現,大多數查詢都是評價者(appraiser_id)次元進行查詢(業務場景是查詢使用者在POI下是否首評、POI詳情頁展示使用者最新一條評價),這部分查詢都是都是走了全局索引,而全局索引場景下索引和資料不一定在同一個節點上,大多數請求都需要經過一次跨機分布式事務,消耗了較多資料庫資源。

對線上查詢流量分析:

  • 使用者次元單個、批量查詢(占比75%)
  • 通過評價ID查詢(占比15%)
  • 評價對象次元查詢/按時間分頁查詢(占比10%)

到這裡問題原因就比較清晰了,因為分區設計的缺陷導緻大量的查詢走到一個低效的索引上,整體性能上不去,這裡引出了分區設計一個很重要的原則——在main SQL 次元建立分區鍵!分區索引的性能是最好的。

是以改為評價者(appraiser_id)次元建立分區鍵

partition by key(appraiser_id) partitions 512           

(2)索引設計

分區鍵确定後其他次元的查詢一般都設定為全局索引,分區鍵次元的多條件查詢設定為本地索引,具體為

PRIMARY KEY (`appraise_id`, `appraiser_id`),
KEY `idx_appraiser_id_gmt_create` (`appraiser_id`, `gmt_create`) BLOCK_SIZE 16384 GLOBAL,
KEY `idx_targetid_gmt_create` (`appraise_target_id`, `gmt_create`) BLOCK_SIZE 16384 GLOBAL,
KEY `idex_modified_status` (`gmt_modified`, `status`) BLOCK_SIZE 16384 GLOBAL
partition by key(appraiser_id)           
  • 評價者ID次元(appraiser_id)設定分區鍵
  • 評價ID(appraise_id)設定為主鍵查詢
  • 評價對象次元(appraise_target_id)設定全局索引查詢

這裡有沒有發現idx_appraiser_id_gmt_create的索引設定有點不太合理,索引被設定為全局索引了,這裡可以設定為性能更好的本地索引,原因為:appraiser_id已經是分區鍵,通過appraiser_id路由到的分片上有全量的的資料,通過本地索引完全能定位到資料,不需要走全局索引查詢,這個索引最終改為本地索引:

KEY `idx_appraiser_id_gmt_create` (`appraiser_id`, `gmt_create`) BLOCK_SIZE 16384 LOCAL,           

(3)分區表下的資料更新

業務上評價資料都是通過評價ID(appraise_id)進行更新,在實際壓測中發現CPU 會飙升到70%左右,排查發現通過appraise_id更新時不帶分區鍵,定位分區有額外的成本,是以在更新條件中加入了分區鍵,這樣在相同的壓力下CPU 降至20%以下。

評價系統-索引設計總結如下圖:在分區表場景下,有一個好的索引設計非常重要。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.16 評價系統索引設計實踐總結

業務收益

  • 新的資料庫架構完全支撐整體評論體系的讀寫性能
  • 分布式資料庫,不用擔心後續的海量資料增長導緻重新分庫分表
  • 整體壓測結果如下:讀/寫2w,平均響應穩定在1~2ms
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 3.17 評價系統遷移OB收益成果

4.OB在高德落地的最佳實踐總結

4.1 關于為什麼選擇OB

在第二節,第三節分别講述了,OB的技術内幕,和高德OB的落地場景,但是詳細考慮為什麼選擇OB,就是關于資料庫的選型是怎麼思考的?我想說“一切基于業務場景,不同業務适合考慮不同資料庫”,如果業務隻有一個很小的場景,幾十萬條資料,幾百QPS的查詢,且資料基本不增長,那單執行個體的MySQL就足夠滿足要求,以雲同步業務(3.2節)看,雲同步業務特性:單元化、海量資料存儲、海量請求,而雲同步經曆Mongo->Lindorm->OceanBase,為什麼進行遷移,同時為什麼不使用MySQL,我們對比如下:

PS:關于為什麼我們業務上既考慮關系型資料庫,又考慮NoSQL資料庫,我們業務上本質是結構化資料,适合關系型資料庫,但是整體業務查詢簡單,對于NoSQL或者KV同樣可以支撐我們的業務。

促科技創新:高德資料優化篇之OceanBase最佳實踐

表 4.1 資料庫選型屬性資訊

我們最關注的三點:穩定性、業務支撐、成本,三個角度綜合考量,OceanBase是我們看到的最優解,确定了資料庫,我們就要選擇OceanBase的部署架構。

4.2 OceanBase部署架構選擇

從上面的項目實踐可以看出,我們對于異地多活的部署使用了兩種架構:多點寫入和中心寫入多單元讀,針對OceanBase也同樣的是兩種不同的架構:

4.2.1 架構選擇-多點寫入

對于多點寫入的部署架構,三個單元的資料庫互相獨立,通過OceanBase提供的資料同步工具OMS進行三地六向的互相同步,此種部署架構優勢如下:

  • 使用者就近接入,讀寫對應單元,無資料延遲
  • 實作完美的異地多活,各單元異地容災,機房故障,随時切流,使用者無損
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.1 OB單元化部署架構

4.2.2 架構選擇-中心寫單元讀

對于中心寫單元讀系統架構,主要采用OceanBase的主從架構,整體優勢如下:

  • 整體對于讀支撐能力提供三倍,同時節省了網絡耗時
  • 主從架構為叢集内部機制,自動同步,運維更簡單

圖 4.2 OB的中心寫單元讀架構

4.2.3 架構選擇-同城多機房讀寫

  • 使用者請求到業務系統無法避免的實體延遲(30~50ms)
  • 同城多機房災備,無法媲美異地災備能力
  • 架構簡單運維友善

4.2.4 關于多單中繼資料同步

其實中心寫,單元讀也可以采用OMS,但是沒必要:

促科技創新:高德資料優化篇之OceanBase最佳實踐

表 4.2 多單中繼資料同步對比

4.2.5 架構選擇結論

結論:不用結構有不同的優劣,具體采用哪種架構要看業務需求,如果業務對讀延遲沒有強要求,可采用主備模式,否則選擇多單元OMS同步模式,而針對本身就是單元化的雲同步業務,多點寫入是我們最好的選擇。

4.2.6 多點寫入系統的問題與解決方案

關于多點寫入的系統(3.2節雲同步系統舉例),整體會有很多疑問點,例如:

  • 雲同步系統是否業務一定要單元化?不單元化會有什麼問題?
  • 從成本考慮,已經單元化,三個單元是否可以不存全量資料?
  • 單元化系統容災切流是否會有問題?

4.2.6.1 雲同步系統為什麼要實作單元化

業務背景分析:

(1)從業務要求上,一次請求,雲同步系統需要與資料庫多次互動,資料庫必須是張北、上海、深圳,三中心來降低網絡延遲。

(2)從使用者通路上,通過APP通路,目前的方式是就近接入,但是使用者的連續兩次請求很可能跨中心。

(3)三單中繼資料庫同步是一定存在延遲的,隻能縮小延遲,但是不可避免(例如網絡實體延遲)。

異常情況舉例(出現資料缺失與覆寫詳見4.2.7.2):

使用者連續兩次請求更改同一條資料,但是請求跨中心(第一次張北中心,第二次上海中心),會産生什麼情況?

(1)使用者第一次請求張北更新成功。

(2)使用者第二次請求上海更新成功。

(3)如果兩次的請求的間隔小于同步延遲,那麼資料同步過來後,上海中心的資料最新資料,會被張北中心的資料覆寫,張北中心的資料最新資料,會被上海中心的資料覆寫;會産生資料的不一緻性。

單元化解決的問題:

(1) 将使用者請求封閉在同一中心單元,解決可能産生的資料不一緻性問題。

(2)使用者最多産生一次網絡延遲,入口層識别使用者單元分發時,可能産生轉發到其他單元,業務與資料庫多次互動均無額外網絡延遲。

4.2.6.2 單元化系統每個單元是否要存全量資料

(1)從成本角度看,單元化系統隻存儲對應單中繼資料,不需要資料同步,同時存儲成本很低(優點)。

(2)但是三個單元存儲非全量資料,業務将無法進行容災切流,隻能依靠資料庫同城容災,做不到異地多活容災(缺點)。

結論:要看系統對于容災的穩定性要求,如果要做到異地多活,随時切流容災,則需要每個單元存儲全量資料。

4.2.6.3 單元化系統容災切流是否會有問題

單元化系統解決了日常情況的資料一緻性問題,但是如果系統發生容災切流,依然會産生資料一緻性問題,需要進一步解決。

圖 4.3 單元化部署同步延時

4.2.7 切流态的資料缺失和覆寫解決方案

4.2.7.1 什麼情況下會有資料缺失

對于資料缺失很好了解,使用者從一個單元切換到另外一個單元,如果使用者前一個單元的資料剛寫入,但是由于同步鍊路延遲,使用者已經切換到其他單元,但是之前寫入的資料還沒同步過來,這樣,就産生了資料缺失。

4.2.7.2 什麼情況下會有資料覆寫

這是個極端情況,不過也有可能發生,如下圖,如果使用者先執行1,後執行2,在執行1和2之間發生了使用者單元切換,如果資料延遲大于使用者操作會發生什麼?會造成資料永久性差異,同時張北OB存在資料錯誤。

  • 對于張北OB如果資料延遲:則2先進行,1通過同步鍊路進行,最終資料,id = 1 name = 'a'。
  • 對于深圳OB:則1先進行,2後進行,最終資料,id = 1 name = 'b'。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.4 資料覆寫問題詳解

4.2.7.3 解決方案是什麼

  • 業務側保證禁寫時間,同時要求OMS不能有長延遲。
  • OMS資料同步時保證資料不被覆寫(目前OMS支援啟停後重新追資料,會比較時間戳),是以我們在切流預案中內建了OMS的啟停。
  • OMS延遲越低,風險越小。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.5 避免資料覆寫設計

4.2.7.4 OMS同步怎麼降低延遲

OMS同步鍊路的拆分與互相獨立。

同步鍊路可以從資料庫次元拆分到表次元,互相鍊路獨立,無影響,同時提升同步性能。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.6 OMS如何降低延時

4.2.7.5 OMS降低延遲效果

在我們降所有表獨立成三條鍊路後,測試資料結果,峰值寫入百兆/秒,同步延遲在10s~20s之間。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.7 OMS 降低延時效果 (注:因資料敏感,部分資料脫敏)

4.3 針對于OceanBase,我們要選擇分區表,還是單表

4.3.1 業務設計選擇-分區表OR單表

  • 業務增長迅猛一定選擇分區表。
  • 注意目前OceanBase的分區數量最大8192,且分區數在建立時即固定,不可自動分列。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.8 OB表設計選型詳解

4.3.2 業務設計選擇-全局索引OR局部索引

  • 局部索引:索引和資料相同的分區規則,在同一機器上,可避免部分分布式事務。
  • 全局索引:不管是全局分區索引還是全局不分區索引,其都可能導緻索引和資料不在同一機器上,每次寫入都是跨機分布式事務。換句話說全局索引會影響表資料寫入性能。

4.3.2.1 使用全局索引的場景

  • 有除主鍵外的全局唯一性的強需求,需要全局性的唯一索引。
  • 查詢條件沒有分區謂詞,無高并發寫入。避免全局掃描,可建構全局索引,但一般限制在4條全局索引内。

4.3.2.2 全局索引、局部索引性能對比

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.9 OB索引間性能對比[2]

引用自:https://www.zhihu.com/question/400141995/answer/2652474150

4.3.2.3 局部索引讀寫注意事項

針對局部索引的讀寫,一定要在請求時指定分區鍵,這樣在OceanBase實際處理時才會直接确定對應分區,整體性能會有明顯差距,以高德評價系統為例,Update場景下命中分區鍵CPU使用率從75%降低到20%以下。

4.3.2.4 全局索引使用的注意事項

1)使用全局索引需要避免掃描行數過大,掃描行數過大會帶來大量RPC調用,導緻RT過高,建議對大查詢做分批查詢。

2)不建議使用全局索引做更新操作,基于全局索引更新性能比較查,QPS高時系統負載比較高。

4.3.3 業務設計選擇-OBKV OR OB普通版本

一句話解釋OBKV版本和OB普通版本,OBKV版本沒有SQL解析優化器,很多SQL需要業務手動優化SQL,指定索引等,但KV版本比普通版本要便宜。

促科技創新:高德資料優化篇之OceanBase最佳實踐

表 4.3 OB版本之間的成本對比

PS:目前OBKV版提供了SDK,支援Java/Go/Rust語言。

4.3.4 業務設計選擇-什麼時候使用複制表?

複制表概念:OceanBase有一種表類型叫做複制表,這種表資料不像分區表一樣做分片存儲,也不像單表一樣隻存儲于單個Observer上,而是會将全部資料完整的存儲在所有Observer上。

主要優勢:複制表資料存在于所有Observer, 資料庫在制定查詢計劃時會做針對性優化,盡量保證從本地機器擷取資料,避免遠端調用。

使用場景:如果某張表資料很少,且業務上這張表需要與其它分區表做大量JOIN查詢,可以将這張表設定複制表,提升JOIN性能。有個常見的例子,我們系統中通用會有一些基礎資料表,比如城市表、類目表等,這類表如果需要與其他表做JOIN查詢,可以考慮設定成複制表,這樣可以避免跨分區JOIN。

4.3.5 業務設計選擇-Leader副本是否要分散到各個Observer上?

OceanBase一個Zone通常有3個Observer節點,預設情況下系統中所有分區表Lead副本隻分布在一台。Observer上,這台Observer抗住這個Zone所有讀寫請求。我們可以考慮将Leader副本分布到所有Observer上,這樣可以提升整個系統的資源使用率。但是這樣也會帶來其他問題,如果我們系統中存在大量跨分區的讀寫操作,會增加很多遠端調用,導緻讀寫RT升高。

大多數情況下,我們使用系統預設配置就行,隻有當遇到資料庫性能問題時才考慮打散Leader副本,并進行壓力測試驗證效果。使用場景總結如下:

分散Leader副本:系統中大部分查詢都可以使用局部索引完成,隻有少量查詢使用全局索引,且系統中寫操作使用分布式事務場景也不多。

不分散Leader副本:系統中有一定比例的全局索引或寫分布式事務,這種情況下打散後會導緻這部分讀寫操作RT升高。

4.3.6 業務設計選擇-主鍵和分區鍵設定

主鍵:Oceanbase作為傳統關系型資料庫替代品,經常使用在OLTP場景,作為業務系統主資料庫使用,這種場景下推薦使用自增主鍵,便于後期維護、資料異構等。Oceanbase雖然自帶自增主鍵,但是隻能保證在一個分區内具有單調性,不推薦使用。建議使用外置分布式ID方案,比如“資料庫号段模式” 或者 “雪花算法”等。

分區鍵:

1)Oceanbase分區方式設定很靈活,支援多級分區、Hash和Range函數分區,通常情況下我們使用最多是基于某一個字段Hash分區。

2)分區鍵選擇上需要綜合考慮查詢方式和資料熱點問題,通常情況下我們可以使用查詢最多的一個次元作為分區鍵,保證大部分查詢可以有最佳的性能。

3)如果系統中有一組表,彼此關系比較密切,經常一起JOIN使用,這組表可以使用相同的分區方式,且設定相同的分區數量,資料庫可以保證這組表同一個分片下的資料分布在同一個Obsever上。比如訂單表和訂單明細表可以都使用使用者ID為分區鍵。

4)分片數量要适宜,分片太大對查詢性能有影響,這個要注意按自己場景設定并測試驗證。

4.4 業務落地的瓶頸

針對雲同步這樣海量的讀寫,同時針對節假日出行高峰,我們的流量即可能翻倍,經過壓測,我們發現了部分瓶頸。

4.4.1 瓶頸-流量稍高,Client明顯報錯逾時

  • Java Client代碼問題,在發起請求處理連結,不合理使用Synchronized。
  • 更新最新包即可解決。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.10 瓶頸Client延時問題

4.4.2 瓶頸-讀寫流量增加,業務逾時明顯

  • 随着壓測的增加,平均RT明顯上漲,且失敗逾時明顯增加。
  • 原因:Proxy側性能瓶頸。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.11 讀寫流量增加業務逾時明顯(注:因資料敏感,部分資料脫敏)

4.4.3 瓶頸-業務機器擴容失敗,無法連結資料庫

  • 擴容失敗提示無法連接配接資料庫。
  • 業務系統不斷重試依然無法連接配接。

原因是:單Proxy連結數有上限。

4.4.4 瓶頸解決-海量資料雲上部署架構優化

OceanBase公有雲,正常部署架構為Client -> SLB -> Proxy -> OBServer,如下圖 4.4.3 左圖,但是針對海量資料請求可能存在瓶頸,單Proxy的連結數,讀寫性能不足以支撐業務請求時,可以進行架構優化,進行水準拆分;多單元OBServer之間可以采用OMS進行資料同步,針對高TPS的寫入,同時寫入資料量很大的情況下,OMS同樣可以進行拆分,正常情況下,一條同步鍊路支撐兩點資料庫之間的全量同步,優化架構可以拆分成表次元互相同步(詳見:4.2.7.4節)。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.12 針對海量請求的OceanBase水準拆分

4.4.5 業務落地-優化效果

在剛剛過去的出行高峰,雲同步業務峰值OceanBase整體RT平穩在2~3ms

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.13 海量資料延時優化效果 (注:因資料敏感,部分資料脫敏)

4.5 當然我們也趟過一些坑

4.5.1 OB KV版不支援SQL優化器,使用索引需要程式指定

OBKV版本:為了達到最大的性能優化,針對我們沒有複雜查詢的業務,我們采用OB KV版本,此版本不支援,SQL優化索引自動選擇的能力,需要程式指定,示例如下:

我們建立了"item_uid", "item_id"的聯合索引,在OB KV如果業務需要走索引,要制定indexName,如代碼行6。

TableQuery query = obTableClient.query(table).setScanRangeColumns("item_uid", "item_id");
            for (String itemId : itemIdSet) {
                query.addScanRange(new Object[]{uidStr, itemId}, new Object[]{uidStr, itemId});
            }
            QueryRESultSet rESults = query
                    .indexName(INDEX_UID_ITEM_ID)
                    .execute();           

同時正如上面提到請求需要指定分區鍵,我們在使用時,一定注意指定分區鍵,我們這裡分區鍵是uid。

public TableQuery queryWithFilter(int uid, String table, ObTableFilterList filterList) {
        return obTableClient
                .query(table)
                .setScanRangeColumns("uid")
                .addScanRange(uid, uid)
                .setFilter(filterList);
    }           

4.5.2 OMS clog丢失、OMS同步明顯延遲觸發報警

在第四節開頭的多點寫入部分介紹了三地六向資料同步的架構,OMS會有Store節點,而Store節點的資料是在記憶體存儲的,在我們壓測時發現,當寫入資料量過大時,會導緻記憶體覆寫,導緻同步日志Clog丢失,針對此種解決方案為:記憶體+日志落盤,保證日志持久化,那如果磁盤滿了怎麼辦?目前磁盤餘量會比較大,同時加設磁盤的相關報警,值班人員随時關注。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.14 OMS 資料鍊路

4.5.3 主從架構高德評論庫上海備叢集縮容後無法提供服務

業務解決在發現問題時第一時間做了業務切流,整體業務無影響,這也同樣展現出異地多活的重要性,可以迅速容災。

  • 直接原因:叢集縮容,把SLB切換到了不支援備叢集的OBProxy版本上,導緻服務不可用。
  • 根本原因:公有雲上OB叢集的OBProxy預設是和observer同機部署,3月初為了配合支援主備庫和POC測試,将OBProxy部署模式切到了獨立支援主備庫的執行個體和版本部署,但是元資訊記錄沒有修改(仍然為混部模式)。導緻本次縮容過程中,識别到混部模式後,認為需要修改SLB挂載的OBProxy資訊,進而挂載到了現在的不支援主備庫的版本,業務通路異常。

問題解決方案

  • OBProxy運維操作自動化優化:避免操作疏漏引入的後續問題,支援建立各版本OBProxy叢集、SLB綁定OBProxy等。
  • 釋放節點操作新增靜默期:有問題可以馬上復原。

4.5.4 OceanBaseServer 部分節點CPU被打滿

問題現象:某一天中午突然收到告警,CPU被打滿,整展現象如下圖4.5.2 和4.5.3:

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.15 OB 異常節點CPU (注:因資料敏感,部分資料脫敏)

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.16 OB 正常節點CPU(注:因資料敏感,部分資料脫敏)

問題分析:通過阿裡雲SQL分析發現,資料庫存在部分慢查詢以及大量KILL QUERY請求記錄

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 4.17 雲SQL分析CPU問題效果(注:因資料敏感,部分資料脫敏)

問題原因:

出問題SQL的業務場景:通過工單ID查詢工單的回調記錄,倒序取100條

select gmt_create,id from table a where a.feedback_id=xxxx order by gmt_create asc,id DESC limit 100;

PRIMARY KEY (`feedback_id`, `id`),
KEY `idx_gmt_create_id` (`gmt_create`, `id`) BLOCK_SIZE 16384 LOCAL
partition by hash(feedback_id)           

這個SQL存在兩種執行計劃:

計劃A:使用主鍵索引,走feedback_id次元的主鍵索引查詢(feedback_id為分區鍵)。

計劃B:使用本地索引idx_gmt_create_id,走feedback_id 次元的本地索引查詢。

正常情況下工單的回調記錄就幾十條(小ID),執行計劃選擇的是A,但是那天剛好有個工單有某種異常導緻下遊一直發送回調消息,回調記錄達到5w條(大ID),這時候OB引擎認為計劃B性能更佳,根據OB執行計劃的淘汰機制,一段時間的執行計劃切換為計劃B。這時候小ID的查詢也切換到計劃B上,小ID SQL走了idx_gmt_create_id local索引導緻性變差逾時,引起應用大量發起KILL QUERY,最終導緻CPU打滿。

小ID走本地索引性能變差的原因:

與OB确認是排序引起的性能問題,具體為正向排序目前3.2.3.3版本做了性能優化,目前版本逆序排序還未做優化,進而出現Desc排序耗時超5秒的情況。大ID執行時掃描的記錄數達到Limit時會提前結束掃描全部子分區,而小ID查詢時總記錄數不足Limit,在未做優化的時候需要掃描全分區,導緻性能問題出現。

解決方案:

  • 為解決大小ID查詢性能不一緻的問題,需要重構idx_gmt_create_id索引,增加feedback_id篩選列,避免全分區掃描。具體索引為KEY `idx_feedback_id_gmt_create_id` (`feedback_id`, `gmt_create`, `id`) BLOCK_SIZE 16384 LOCAL。
  • OB側做逆序排序優化,新版本已修複。

5. 高德雲原生生态未來規劃

高德本着“促科技創新,與生态共進”初心,通過技術創新的手段連接配接真實世界,做好一張活地圖,讓出行變得更加美好。在過程中我們會通過技術的手段去高效的疊代産品提升使用者體驗,也會通過技術的手段去降低成本,涵蓋人力成本和資源成本。

其實網際網路發展到現在這個階段,2個關鍵詞“降本”和“提效”也非常重要。我們已經從“單體架構”過度到“分布式架構”到現在的“微服務架構”進入到未來的“雲原生架構”,資料也從當初xG衍生到現在的xPB級别。伴随着ChatGPT出現,算法也達到了一個高光的時代,“算法+大資料”的方式,可以讓模拟人類大腦的方式去思考,去幫助人類提效,這類新的技術也讓機器完成了涅槃,擁有了生命,我們稱之為“矽基生命”。

這麼一看科技是可以促進創新、促進社會進步的,擁抱新的技術對我們來說顯得尤為重要。因為要在這個生态環境下提供更好的服務是我們的初心,我們不但要擁抱新技術,還要回報社會,促進科技創新,促進生态發展。那麼回過頭說說我們在雲原生上是如何做“降本”和“提效”的。

因OB也是雲原生資料庫,我們在雲原生後續的規劃裡會繼續跟OB合作,在降本和性能(涵蓋AP場景)做更大的突破。高德在Serverless上已經取得了100w/QPS+成績,我們也會繼續發揮這個優勢,利用雲原生+行業無關化架構提升開發效率,比如利用Serverless,能大幅降低研發成本、提升人效并加快疊代速度,讓業務更快,一起做好極緻的使用者體驗。

[這裡做一個雲原生的概念回顧,因為可能讀者會産生一個疑問,OceanBase不是分布式資料庫嗎,什麼時候變成雲原生資料庫了。]

雲原生(Cloud Native)其實是一套架構體系,說到體系其實就會衍生出方法論。Cloud的含義是應用和資料都不在機房或者IDC中,而在N多機器組合的雲中.Native設計之初就是以雲架構為基礎,提供資源池化、彈性和分布式服務等核心能力。

非原生到雲原生的轉化路徑為:

1、DevOps疊代與運維自動化,彈性伸縮、動态排程

2、微服務,Service Mesh、聲明式API

3、容器化

4、持續傳遞

OB提供了租戶的概念,資源池+彈性+排程都是互相隔離的,資料非常安全。本身OB的元件也都是服務化的基礎服務,也可以跑到容器裡。做到Native架構所要求的特性,而且OB的資源都在雲上。從這些來看OB就是一個雲原生資料庫了。

5.1 高德與OceanBase合作後續展望

上文也簡單的介紹了OB的技術内幕,我們直接說結論。DevOps和持續傳遞這裡不提,因為現在每款資料存儲工具都會做,而且都會提供極緻的使用者體驗,讓運維變得更加簡單。這裡我們想說的是OB的資料壓縮技術,OB對資料壓縮和路由上做了很多優化與創新,單說資料壓縮,針對不同的列類型提供不同的壓縮技術,盡量使得存儲量變得小而不失查詢效率。

這裡是否會産生一個疑問?高德為什麼這麼在乎資料壓縮和存儲空間大小。其實可以先思考下這個問題,大家在使用高德地圖的時候,體感隻是目前使用的功能。為了更好的使用者體驗,我們做了很多資料和算法上的事來提升使用者體驗,這也導緻高德資料體量非常大,所需要的成本會很高,可能都是指數的級别,從公司的角度來看,優化這塊對我們來說收益很大,不但可以節省成本,還可以降低耗電量,保護環境。從另外一個角度來說做極緻的優化也是我們的追求。

總結下,未來跟OB合作的事項,以及詳細規劃。事項如下:

  • 因高德資料體量很大,後續會持續落地OB( 正常結構化和非結構化版本)
  • 探索OB的AP能力,替換ADB方案
  • 探索Serverless版本
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 5.1 高德與OB後續合作展望

5.1.1 海量資料項目 - 結構化資料

高德有許多結構化的資料存儲在Lindorm中,Lindorm本質是列存+多副本備援架構本質上跟OB一樣高可用架構。列存的資料庫對于大資料計算其實是很友好的,如果一個Sum的計算其實隻要讀一次列值然後計算就可以(這裡是一個列,不涉及IO的計算) 。雖然結構化資料也支援,但是畢竟場景不是很合适因為我們有複雜的查詢在裡面,這裡就比較适合遷移到OB上,從另外一個角度來說OB的多列類型壓縮在成本上也有很大優勢。

後續我們會持續把結構化資料場景的業務遷移到OB上,比如(存儲)高德足迹(結構化存儲),目标降本50%以上。

當然遷移後,我們也可以享受OB線性優化的收益,可以壓縮資料的節點數量達到最小,當大促或者量大的時候自動進行彈性擴容,而且因OB具備分布式的能力,我們也無需關注負載均衡的問題,完全實作了自動化透明擴容。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 5.2 OB彈性擴容設計

5.1.2 海量資料項目 - 非結構化資料

在高德的複雜場景裡,我們處理結構化資料,還有許多非結構化存儲場景,這裡這的不是簡單的KV模式,一個Key對應一個Val。我們其實用的更加複雜,因為我們的非結構化的場景需要動态列-Schemaless能力,也會和固定表結構混用,這樣就顯得十分複雜。如果再加上一個多版本的資料保留,那麼在查詢上就會更加複雜。你們以為這就完了嗎?我們還會加上一個列級的TTL。這種複雜的組合真的很考驗資料庫的能力和性能。OB在收到我們的需求後,響應也是非常的及時,快速的開發出NoSQL+多版資料版本來支援我們,目前已經滿足了我們大部分場景。列級的TTL也已經開發的差不多了,近月就會提供出一個穩定版本讓我們使用。

目前在非結構化資料場景,也一直和OB在一起探索,目标把打車的特征平台(典型的KV場景)遷移到OB上,預計降本目标50%以上。

如果隻是單獨提出“多版本、動态列、列級TTL”組合能力,看着隻是稍微複雜點,其實還好。 如果說我們每個應用的資料量級都是過百T的存儲量,幾百張表,讀峰值在百萬級/S,寫峰值在十萬級/S。 這麼看是不是會體感更好點。是以針對這塊降本還是很可觀的具體降本在30%-40%。

5.1.3 探索OB的AP能力,替換ADB方案

OB目前的引擎能力已經支援了AP場景,但是因為OB的目前的表現還是行,極少能吃到列存在AP上的表現。下半年OB推出純列存儲引擎,在路由和資料模式上(冷熱資料)也做了很多優化,性能會提升至少3倍數。我們也會在下半年把現有AP場景切一個試點到OB上,目前預計降本20%。

這裡不是對OB的OLAP場景的性能要求苛刻,我們還是本着降本提效的思路,要壓榨出OB極緻的性能,因為我們在大資料分析場景,對資料分析的實時性要求很高,隻要在快速的效果下才能提供極緻的使用者體驗。而且同一個租戶叢集裡,我們可以同時享受到OLTP+OLAP雙引擎的優勢和收益,降本收益還是很客觀的。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 5.3 OB的OLAP方案

當然我們也會把OB引入到交易的場景裡,在交易的複雜場景裡,OB也會表現的非常好。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 5.4 OB交易場景探索

5.1.4 Serverless版本的探索

高德本身已經在Serverless上取得了很多成績,百萬級QPS。我們有很多Serverless落地經驗,也會跟OB一起嘗試落地Serverless版本的OB,再次降本。

  • 資源按需使用,規格動态更新
  • 資源按需使用,底層存儲空間擴容

因OB是多副本模式+轉存模式+多數派模式,擴容時可用。

促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 5.5 OB在Serverless上的探索

5.2 極簡架建構構雲原生Serverless群組裝式研發生态

說到組裝式研發,這并不是一個新詞,這種架構模式其實很早就存在了,隻是每個公司實作的方式不同。高德針對組裝式研發進行了調整,因為對我們來說資料流轉就是2大屬性,“Request和Response”。但是從業務組合的視角,我們其實隻有“Input和Output”。從架構的視角就更加簡單明了,也更加靈活了。

我們其實隻要針對"輸入和輸出"進行加工,然後通過流水線的方式把流程編排起來,整個業務流程和資料流轉就會非常清晰,我們也會根據公共特性進行封裝變成通用元件進行複用,大大提供人效成本和降低後續維護成本。不再擔心面對業務孵化和不敢改的局面,真正做到從人到機器再加上業務疊代上的一石三鳥的收益。(因輔助的工具比較多,這裡不深入叙述,後續可以單獨寫一個專題)

組裝式不單單可以用到應用上,還可以用到Serverless的FaaS裡,其實我們現在好多服務已經進化成Serverless的BaaS模式。整個組裝式已經深入到Serverless生态裡面。我們也會繼續建設Serverless生态,應對初心,促進科技發展,開源高德Serverless FaaS的Runtime腳手架到社群,讓大家可以快速複刻高德的Serverless落地方案。我們已經在“交易、出行、廣告、車生态”等多個場景裡落地了,感興趣的同學可以去搜尋“高德雲原生之Serverless體系建設&實踐”。

整體抽象如下3點:

  • 組裝式研發,樂高元件,動态編排,快速疊代提升人效,降低維護成本,快速疊代業務。
  • Serverless生态建設,更加豐富的腳手架和工具落地,快速降本。
  • 存儲層面支援Serverless,一個函數通殺所有,端雲一體,語言無關,降低研發門檻。
促科技創新:高德資料優化篇之OceanBase最佳實踐

圖 5.6 Serverless 端雲引擎一體化探索設計

6. 參考

[1] 阿裡雲. PolarDB-X技術架構[EB/OL]. 2023-07-18[2023-07]. https://help.aliyun.com/document_detail/316639.html

[2] PolarDB-X. PolarDB-X、OceanBase、CockroachDB、TiDB二級索引寫入性能測評[EB/OL]. 2022[2023-07]. https://www.zhihu.com/org/polardb-x.

[3] Wu L, Yuan L, You J. Survey of large-scale data management systems for big data applications[J]. Journal of computer science and technology, 2015, 30(1): 163-183.

[4] https://glossary.cncf.io/serverless/

[5] https://developer.salesforce.com/docs

本文作者:

振飛(高德地圖總裁)

炳蔚(高德技術服務平台負責人)

福辰(高德服務端架構師)

來源:微信公衆号:高德技術

出處:https://mp.weixin.qq.com/s/8nMqORGIPXF6IrHVAzG-9A