天天看點

深度解析:騰訊雲分布式資料庫 DCDB這些問題,騰訊全部遇到過分布式資料庫為什麼能解決容量、并發、擴充等難題騰訊雲分布式資料庫DCDB分布式資料庫DCDB的分表方案如何選擇拆分鍵

我們知道,集中式(單機)資料庫在存儲容量、并發性能、快速擴容等都會因業務增長而達到瓶頸。而在業務發展初期,團隊很難準确預測資料庫增長的速度和規模,隻有靠拍腦袋确定規模進行裝置選型:

若達不到預期,會導緻資源浪費;

若超過預期,則會出現擴充難題;

若成為行業領先,那麼性能瓶頸又擺在了面前。

還有集中式資料庫一系列容災、恢複、管理等一系列問題,都讓人糟心。

多數情況下,網際網路業務往往都會超出預期,随之而來的問題就令人頭疼了。為解決上述問題,騰訊資料庫團隊曾經選擇多種方向,也考察過商業資料庫基于共享存儲的體系架構(RAC)。我們發現,RAC架構無法通過增加計算節點來“線性的”提升資料庫叢集性能,因為共享存儲的體系架構中多個節點對同一個資料塊有對等通路權限,這就意味着所有資料都是全局資源,任何節點在操作資料時必須加鎖以防止其它節點的幹擾,為了協調節點間的通路,就必須通過密集的消息通信來傳遞資源鎖。在傳統企業IT(内部ERP、OA)等系統上,這樣的問題并不明顯;然而當其面對的是網際網路海量處理應用是,這種資源鎖機制嚴重限制了RAC架構的擴充能力。其次,從營運成本角度上講,商業資料庫高昂的授權費用、昂貴的硬體成本,都制約了業務的快速發展。是以,騰訊最終選擇了分布式資料庫方案。

時至今日,放眼網際網路行業,排名靠前企業的核心業務都在使用分布式資料庫,我們不禁要問,這其中有什麼秘密?

了解分布式資料庫,需要先了解垂直切分(分庫)、水準切分(分表)兩種方案:

垂直切分(通常也叫做“分庫”)也就是按功能切分資料庫,這種切分方法跟業務緊密相關,實施思路也比較直接,比如“京東JD”等電商平台,一個原有一個資料庫執行個體,按功能切分為會員資料庫、商品資料庫、交易資料庫、物流資料庫等多個資料庫執行個體,共同承擔業務壓力。有時候,垂直拆分并不能徹底解決壓力問題,因為單台資料庫伺服器的負載和容量也是有限的,随着業務發展勢必也會成為瓶頸,解決這些問題的常見方案就是水準切分了。

水準切分(又叫做“分表”)是按照某種規則,将一個表的資料分散到多個實體獨立的資料庫伺服器中,這些“獨立”的資料庫“分片”;多個分片組成一個邏輯完整的資料庫執行個體。一般來說,分表的前提是分庫。

深度解析:騰訊雲分布式資料庫 DCDB這些問題,騰訊全部遇到過分布式資料庫為什麼能解決容量、并發、擴充等難題騰訊雲分布式資料庫DCDB分布式資料庫DCDB的分表方案如何選擇拆分鍵

水準拆分的方案,實際上是分布式資料庫的基礎原理,他的每個節點都參與計算和資料存儲,而且每個節點都僅計算和存儲一部分資料。是以,無論業務的規模如何增長,我們僅需要在分布式叢集中不斷的添加裝置,用新裝置去應對增長的計算和存儲需要就夠了。

深度解析:騰訊雲分布式資料庫 DCDB這些問題,騰訊全部遇到過分布式資料庫為什麼能解決容量、并發、擴充等難題騰訊雲分布式資料庫DCDB分布式資料庫DCDB的分表方案如何選擇拆分鍵

騰訊雲分布式資料庫(DCDB)是部署在騰訊雲上的一種,面向OLTP業務支援自動水準拆分(分表)的share nothing架構的分布式資料庫。DCDB也是随着騰訊業務規模不斷擴大而發展起來的,從2004年開始,騰訊部分業務就已經開始遇到單機資料庫架構已經無法支撐,進而開始研究分布式架構,業務發展最終推動了資料庫架構技術的不斷革新,面對日益複雜的需求。截止到2017年,包括微信支付,騰訊充值,閱文集團等騰訊公司交易、轉賬等核心系統90%以上都使用了騰訊分布式資料庫(DCDB)。

深度解析:騰訊雲分布式資料庫 DCDB這些問題,騰訊全部遇到過分布式資料庫為什麼能解決容量、并發、擴充等難題騰訊雲分布式資料庫DCDB分布式資料庫DCDB的分表方案如何選擇拆分鍵

DCDB的前身是騰訊自研TDSQL,我們的設計理念是淡化複雜的拆分、擴充等邏輯,讓開發者使用DCDB就像使用集中式單機資料庫一樣順利。

目前,DCDB已支援MySQL 5.7、5.6(基于Percona、MariaDB分支),未來計劃進一步支援PostgreSQL引擎(基于騰訊自研PostgreSQL-XZ分布式引擎)等。

DCDB整個叢集架構簡圖如下圖,這種叢集架構極大簡化了各個節點之間的通信機制,也簡化了對于硬體的需求,這就意味着即使是簡單的x86伺服器,也可以搭建出類似于小型機、共享存儲等一樣穩定可靠的資料庫。

深度解析:騰訊雲分布式資料庫 DCDB這些問題,騰訊全部遇到過分布式資料庫為什麼能解決容量、并發、擴充等難題騰訊雲分布式資料庫DCDB分布式資料庫DCDB的分表方案如何選擇拆分鍵

大多數情況下,可以用您熟悉的對象映射架構使用DCDB。對于分表,建議您盡量使用基礎的SQL語句,因為這樣能達到最佳性能,特别是幾億甚至幾百億條記錄的情況下。這意味着,某些情況下,您可能需要一定的改造,才可以接入DCDB。

關系型資料庫是一個二維模型,資料的切分通常就需要找到一個分表字段(shardkey)以确定拆分次元,再通過定義規則來實作資料庫的拆分。業内的幾種常見的分表規則如下:

基于日期順序(Time),如按年拆分,2015年一個分表,2016年一個分表。

基于某字段劃分範圍(Range),如按使用者ID劃分,0~1000一個分表,1001~2000一個分表。

基于某字段求模(HASH),将求模後的值,再按Range方式分散到不同庫中。

無論是Time、Range都有個主要缺點就是可能導緻嚴重資料傾斜,即多個實體節點(又叫做分片)之間負載和資料容量嚴重不均衡。在大部分資料庫系統中,資料都有明顯的冷熱特征——顯然目前的訂單被通路的機率比半年前的訂單要高的多(更熱)——而采用Time分表或range分表,就意味大部分熱資料将會被路由在少數幾個分表中,而存儲冷資料的裝置性能卻被浪費掉了。

是以,DCDB通常采用某個字段求模(HASH)的方案進行分表,而計算HASH的某個字段就叫做shardkey。因為HASH算法本身就能夠基本保證資料相對均勻的分散在不同的實體裝置中(某些特殊情況下除外,我們将在後續章節進行介紹)。

HASH的過程大緻就是,當某條記錄(SQL)請求時被發起時,DCDB 會了解 SQL 語句的含義,然後按照拆分鍵的值和執行政策将 SQL 路由到對應分表進行執行,如下圖所示,先通過hash算法計算,再路由到各個節點上。

深度解析:騰訊雲分布式資料庫 DCDB這些問題,騰訊全部遇到過分布式資料庫為什麼能解決容量、并發、擴充等難題騰訊雲分布式資料庫DCDB分布式資料庫DCDB的分表方案如何選擇拆分鍵

而如果一個查詢 SQL 語句的資料涉及到多個分表,此時SQL會被路由到多個分表執行,DCDB 會将各個分表傳回的資料按照原始 SQL 語義進行合并,并将最終結果傳回給使用者。

深度解析:騰訊雲分布式資料庫 DCDB這些問題,騰訊全部遇到過分布式資料庫為什麼能解決容量、并發、擴充等難題騰訊雲分布式資料庫DCDB分布式資料庫DCDB的分表方案如何選擇拆分鍵

讀取資料時(如果有明确shardkey值):

業務發送select請求中含有shardkey時,網關通過對shardkey進行hash

不同的hash值範圍對應不同的分表

資料根據分表算法,将資料從對應的分表中取出

讀取資料時(如果沒有明确shardkey值):

業務發送select請求沒有shardkey時,将請求發往所有分表

各個分表查詢自身内容,發回Proxy;

Proxy根據SQL規則,對資料進行聚合,再答複給網關

從上述原理來看,查詢SQL中含有shardkey值比不含shardkey值效率将會更高。

拆分鍵是在水準拆分過程中用于生成拆分規則的資料表字段,必須在建表時就指定好。DCDB建議拆分鍵要盡可能找到資料表中的資料在業務邏輯上的主體,并确定大部分(或核心的)資料庫操作都是圍繞這個主體的資料進行,然後可使用該主體對應的字段作為拆分鍵進行分表,該分表方案通常叫做groupshard(按組分表),如下圖:

深度解析:騰訊雲分布式資料庫 DCDB這些問題,騰訊全部遇到過分布式資料庫為什麼能解決容量、并發、擴充等難題騰訊雲分布式資料庫DCDB分布式資料庫DCDB的分表方案如何選擇拆分鍵

Groupshard方案,可以確定不同分表的某些關聯資料和複雜的業務邏輯運算,可以聚合到一個實體分片内,進而減輕分布式資料庫本身一些使用缺陷。例如,某電商平台訂單表和使用者表都是基于使用者次元(UserID)拆分,平台就可以很容易的通過聯合查詢(不會存在跨節點join,或分布式事務)快速計算某個使用者近期産生了多少訂單。

下面的一些典型選擇拆分鍵的應用場景:

面向使用者的網際網路應用,都是圍繞使用者次元來做各種操作,那麼業務邏輯主體就是使用者,可使用使用者對應的字段作為拆分鍵;

電商應用或O2O應用,都是圍繞賣家/買家次元來進行各種操作,那麼業務邏輯主體就是賣家/買家,可使用賣家/買家對應的字段作為拆分鍵;但請注意,某些情況下幾個超大賣家占到絕大多數交易額,這種情況會導緻某幾個分片的負載和壓力明顯高于其他分片,我們會在後面章節予以說明。

遊戲類的應用,是圍繞玩家次元來做各種操作,那麼業務邏輯主體就是玩家,可使用玩家對應的字段作為拆分鍵;

物聯網方面的應用,則是基于物聯資訊進行操作,那麼業務邏輯主體就是傳感器/SIM卡,可使用傳感器、獨立裝置、SIM卡的IMEI作為對應的字段作為拆分鍵;

稅務/工商類/社保的應用,主要是基于納稅人/法人/居民的資訊來開展前台業務,那麼業務邏輯主體就是納稅人/法人,可使用納稅人/法人對應的字段作為拆分鍵。

以此類推,其它類型的應用場景,大多也能找到合适的業務邏輯主體作為拆分鍵的選擇。

拆分鍵的限制 為了提高文法解析效率,避免因為shardkey設定導緻路由錯誤,DCDB規定了拆分鍵設定的技術限制(請參考騰訊雲官方文檔):

如存在主鍵或者唯一索引,則shardkey字段必須是主鍵以及所有唯一索引的一部分;

shardkey字段的類型必須是int,bigint,smallint,char,varchar;

shardkey字段的值盡量使用ascii碼,網關不會轉換字元集,是以不同字元集可能會路由到不同的分區(且盡量不要有中文);

不能update shardkey字段的值,如必須則先delete,再insert;

<code>shardkey=</code> 放在create語句的最後面,如下示例:

6. 通路資料盡量都能帶上shardkey字段,可以極大的提升效率;