必修課!深度解析金融級分散式資料庫一致性技術

来源:https://www.cnblogs.com/tencentdb/archive/2022/09/28/16737183.html
-Advertisement-
Play Games

作為國民經濟的命脈和樞紐,金融行業對底層資料庫的能力要求正在不斷提高。在眾多要求中,數據一致性無疑是重中之重,即數據不能出錯,最好還能提高併發效率。 TDSQL採用MC(輕量級GTM)+全局MVCC的全局讀一致性方案。如果只使用全局事務管理器GTM,除需維護全局序列外,還需要維護全局的事務衝突,這個 ...


作為國民經濟的命脈和樞紐,金融行業對底層資料庫的能力要求正在不斷提高。在眾多要求中,數據一致性無疑是重中之重,即數據不能出錯,最好還能提高併發效率。

TDSQL採用MC(輕量級GTM)+全局MVCC的全局讀一致性方案。如果只使用全局事務管理器GTM,除需維護全局序列外,還需要維護全局的事務衝突,這個過程的通信量及與GTM之間的通信頻率都會成為瓶頸。TDSQL引入全局MVCC,將每個分片上MVCC版本和全局GTS做映射,通過全局GTS和全局的MVCC映射來管理每個分片上的鏡像,進而實現全局的MVCC,從而極大減少和GTM 之間的通信量及避免全局的衝突事務檢測。

上述方案確保了TDSQL無任何數據異常,且具備高性能的可擴展性,解決了分散式資料庫在金融級場景應用的最核心技術挑戰,使得國產分散式資料庫實現在金融核心系統場景的可用、好用,進而推動國產基礎軟體產業化。基於此,TDSQL是當前國內率先進入國有大型銀行核心系統正式投產的國產分散式資料庫。

在WOT全球技術創新大會2022的騰訊雲資料庫專場中,騰訊雲資料庫專家架構師汪泗龍分享了金融級分散式資料庫TDSQL的一致性技術及應用實踐,以下為詳情內容:

一、TDSQL產品介紹

1.1 發展歷程

騰訊雲資料庫TDSQL誕生自騰訊內部百億級賬戶規模的金融級場景。從內部自研蛻變成規模化商業產品,TDSQL的發展歷程可分為四個階段:

第一階段是2007-2009年,當時開源的MySQL已經越來越難以應對騰訊爆髮式增長的業務,研製服務於計費、定位於金融場景的分散式資料庫TDSQL逐漸提上日程。

第二階段是2009-2012年,騰訊進入開放時代,海量業務群雄並起,以開心農場等為代表的眾多億級應用比比皆是。TDSQL逐漸在性能瓶頸、數據可靠性保障、高可用等“不可能三角”的技術難題上取得突破。

第三階段是2012-2014年,雲計算興起,資料庫上雲、多租戶、標準化成為標配。騰訊雲資料庫的能力逐漸外溢,TDSQL因其優異的性能已經擁有眾多外部客戶。在經過公有雲的海量數字化、大規模高併發業務場景打磨以及內核級的深度自研優化後,TDSQL逐漸形成標準化的國產分散式資料庫產品,包括金融級分散式TDSQL、計算與存儲分離的雲原生資料庫TDSQL-C 等產品,獲得了雲原生技術、多租戶隔離能力。

第四階段是2014-2020年,數字化升級成為行業趨勢,TDSQL深入金融核心,走向大規模應用階段,比如作為微眾銀行分散式資料庫底座承擔核心作用,幫助張家港農商銀行上線新一代核心業務系統,助力平安銀行打造信用卡“A+”新核心系統等等。

file

目前,TDSQL已服務金融、政務、工業製造等行業超過50萬家客戶,幫助20餘家金融機構完成核心替換,國內TOP 10銀行機構服務占比超過60%。同時TDSQL也支持了第七次全國人口普查,以及騰訊會議、健康碼等關係國計民生的數字化應用,有力推進國產資料庫的技術創新和發展。

1.2 核心特性

隨著雲計算和數字化業務的發展,針對新型企業級信息化以及實現國產化的轉型升級需求,TDSQL逐漸形成6大核心特性:

  • 數據強一致性:確保多副本架構下數據強一致,避免故障後導致集群數據錯亂和丟失。
  • 金融級高可用:確保99.999%以上高可用;跨區容災;同城雙活;故障自動恢復。
  • 高性能低成本:軟硬結合;支持讀寫分離、秒殺、紅包、全球同服等超高性能場景。
  • 企業級安全性:資料庫防火牆;透明加密;自動脫敏;減少用戶誤操作/黑客入侵帶來的安全風險。
  • 線性水平擴展:無論是資源還是功能,均提供良好的擴展性。
  • 便捷的運維:完善的配套設施,包括智能DBA、自助化運營管理台。

1.3 產品架構

TDSQL的架構主要分為三層。最上層是管理層,包含赤兔管理平臺、MC以及Keeper。中間層是SQL引擎,可以選擇使用TDSQL附帶的接入層,也可使用傳統意義上的F5等接入層來進行接入。最下層是存儲引擎層,即TDSQL內核。

file

下圖是實現 GTM 全局唯一序列的圖簽。這裡是TDSQL在實現分散式事務後在全局一致性讀方面的優化點,該插件實現了輕量級的GTM。

file

二、分散式事務處理

事務處理面臨的挑戰有兩點:保障數據正確性及提高併發效率。這兩點都是事務處理的關鍵點,如果為了提高併發效率而犧牲數據正確性,就背離了初衷,反之也是如此。為瞭解決這兩個問題,我們需要用到很多技術,比如讀寫分離、物理時鐘、時間戳機制、GTM等。

file

2.1 分散式事務模型

不管是分散式資料庫還是應用,都是在分散式事務模型下,進行分散式事務的實踐和開發。對資料庫而言,常用的分散式事務模型是XA模型;對應用而言,主要是TCC、SAGA、AT等模型。

file

Oracle、MySQL、TDSQL等資料庫,通常使用XA模型來進行分散式事務處理。在XA模型里,事務主要採用兩階段提交方式,先進行PREPARE,再進行COMMIT,也稱之為兩階段事務。

file

2.2 數據異常問題

事務模型簡化後劃分為讀寫兩類操作,組合下來有四種場景,即讀寫、寫讀、讀讀、寫寫。存在衝突(數據異常)的場景主要是寫寫、寫讀、讀寫,具體的衝突如下:

  • 寫寫衝突:會出現臟寫、丟失回滾。
  • 寫讀衝突:會出現臟讀、幻讀、不可重覆讀、讀偏序等。
  • 讀寫衝突:會出現臟寫、丟失更新等。
  • 其他異常:主要是寫偏序,即違背語義(約束)的異常。兩筆事務同時發生,每筆事務都滿足約束。但在分別進行的過程中,因為沒有提前加鎖,沒有滿足語義,導致最終事務完成後違背了語義約束。

file

針對上述問題,我們可以通過資料庫的併發控制演算法來解決:

  • 基於鎖(兩階段鎖)進行控制:兩階段鎖除我們常用的2PL外還有S2PL、SS2PL,主要是鎖定階段的不同。在種類上主要有S鎖、X鎖、U鎖、間隙鎖。
  • 基於MVCC的方案:將讀寫進行分離,支持多版本和快照。
  • 基於時間戳進行控制:主要有三個時間戳,即事務啟動時的時間戳、數據讀的時間戳以及數據寫的時間戳。
  • 基於有效性確認來進行控制

file

我們需要根據不同的場景來使用不同的演算法。在分散式事務處理方面,TDSQL使用的是2PL加上MVCC特性。

2.3 全局讀不一致問題

我們以下圖為例說明全局讀不一致問題。有A、B兩個賬戶,賬戶餘額均為100元。有兩個事務,事務X和事務Y,事務X是A給B轉100元,事務Y是讀取A和B的餘額。當事務Y發起查詢時,事務X中(NA分片屬於COMMITting狀態,NB分片屬於COMMITed狀態),這時讀到兩人餘額總和為300元,這就是分散式事務進行過程中的全局讀不一致問題。

file

出現這種全局讀不一致的情況,主要原因在於這裡沒有全局一致的MVCC版本,而是依賴每個分片各自的MVCC特征進行實現,我們讀到的NA片還沒提交,因此讀到的數據是不一致的數據。針對上述異常情況,主要有以下幾種解決方案:

  • 利用全局事務管理器GTM,GTM會提供一個全局序列來滿足使用,還會維護全局的事務衝突列表。
  • 以封鎖機制實現全局可串列化,將所有的讀寫都變成相關的邏輯上的DML操作,實現全局封鎖。這個過程可以解決所有的讀寫衝突,從而實現全局讀一致性。但這種模式會帶來性能上的問題,導致效率降低。
  • 採用物理時鐘排序,其缺點在於成本高,且效率比全局封鎖的效率低。
  • 採用混合時間戳機制實現局部偏序排序,但這個方案只限於特定場景。
  • 兩次讀機制,第一次讀發現數據不一致就會發起第二次讀,直到可以給到客戶一致性的版本。

file

TDSQL的全局讀一致性方案是MC(輕量級GTM)+全局MVCC。只使用全局事務管理器GTM的方案,除需維護全局序列外,還需要維護全局的事務衝突,這個過程的通信量及與GTM之間的通信頻率都會成為瓶頸。因此需要引入另一個特性——全局MVCC,這時的讀寫衝突可通過undo的前鏡像完成一個全局的MVCC來實現,解決各副本間的讀寫衝突。

完全重新開發一套全局MVCC的成本較高,且和InnoDB的相容性是個問題。因此我們採用了折中方式,我們將每個分片上MVCC版本和全局GTS做映射,通過全局GTS和全局的MVCC映射來管理每個分片上的鏡像,進而實現全局的MVCC。這樣就可極大減少和GTM 之間的通信量及避免全局的衝突事務檢測。

三、TDSQL分散式事務實踐

3.1 TDSQL分散式事務模型

下圖為TDSQL分散式事務的實現模型,主要有三個角色:

  • TM:SQLEngine充當事務管理器角色,負責發起分散式事務。
  • RM:DB節點相當於分散式事務的資源節點(RM),作為分散式事務的重要參與者。
  • TC:XID_LOG作為分散式事務協調者的角色,確認PREPARE狀態的完成。

file

通過Client發起一個事務BEGIN後,會往後端發起一個插入語句到Proxy,此時Proxy發起XA Start,到後端的兩個SET上,兩個SET返回正常後則插入成功。獲取到XID後,開始正式進入COMMIT階段。Client發起COMMIT後,Proxy往後端發時就會帶著全局的XID往後提交,這時進入PREPARE和COMMIT階段。

當所有參與者PREPARE成功後,會插入全局的XID_LOG。XID_LOG是PREPARE階段的一個平衡點,解決懸掛等待的高成本及超時回滾等問題。一旦事務進入到這個階段,寫入全局的XID_LOG成功後,即使後面的操作失敗,我們依然會認為事務是成功的。針對沒有提交成功的事務,Agent參與進來,掃描XID_LOG表進行後續處理;如果執行超時,Agent會參與進來,終止掉超時的事務,之後Agent會更新XID_LOG的狀態。

Proxy和Agent是協作模式,XID同一時間點只能有一種狀態,我們可以通過這種狀態來協調Proxy和Agent。如果Proxy Crash掉,Agent進行任務接管,根據XID_LOG的信息決定對事務進行補提交或回滾。在此過程中,Proxy本身是無狀態的,這就使得TDSQL具備良好的業務體驗。

如果在主備過程中,一個SET發生主備切換,另外一個SET正常,這時Agent會根據全局XID_LOG的狀態進行相關補償或者回滾。如果XID_LOG寫成功,我們會進入到最終的COMMIT階段,兩個分片分別COMMIT成功後,會正常反饋給Client端。以上就是TDSQL基於XA兩階段提交的分散式事務模型和原理。

3.2 TDSQL全局一致性讀實現方案

分散式資料庫,不僅要解決分散式事務的問題,還要解決全局寫讀衝突,從而實現全局的一致性讀。TDSQL具體的實現方案如圖所示:

file

與前面提到的TDSQL分散式事務模型相比,整體架構較為相似,區別在於多了一個MC組件。

MC是全局的輕量級GTM,負責生成全局的唯一序列。以上述兩個SET的插入的事務模型為例,整個過程中只是多了兩次和GTM之間的獲取步驟,其他流程是一致的。

當我們發起一個分散式事務,在CLIENT啟動及提交時,我們會在這裡再加入一個階段,獲取全局最大的GTS。GTS是標識的全局唯一序列,XID是唯一標識全局事務的標簽,兩者相互獨立分別保證分散式場景下讀取一致性和事務一致性。在COMMIT發起後進入兩階段提交,這裡需要對PREPARE階段進行判定,通過XID_LOG日誌來作為全局提交成功的標識。在PREPARE成功後,PROXY和MC會進行第二次交互,重新獲取COMMIT_GTS,並伴隨事務的COMMIT寫入到TDSQL REDO日誌和緩存中。相對於XA的START和COMMIT,TDSQL為了實現全局的MVCC特性,改寫了XA的語法,增加部分關鍵詞,同時對內核做微量調整,以上就是TDSQL實現全局一致性讀的方案。

在該方案中,我們和MC的通信量非常少,整個過程中基本只有2次非常輕量的通信,某些場景下當我們進行一個不涉及多分片的事務時,即如果只涉及一個分片,我們會對第二次獲取COMMIT_GTS進行優化,進一步減少和MC通信。實際上,TDSQL實現分散式事務和分散式全局一致性的方案,是把InnoDB自身的MVCC和全局GTS進行全局映射,從而實現全局輕量級的GTM+全局的MVCC。

下圖是InnoDB的MVCC模型,共有六個事務,當前事務ID是trx6,為活躍狀態。眾所周知,InnoDB會將trxid直接排序,通過全局事務鏈表管理維護。我們以下圖為例來說明可見性演算法是如何對外可見的。

file

我們過濾時需要過濾事務本身的可見性情況,要看哪些事務對外已經能看到屬於活躍事務。我們可以過濾掉trx7和trx5,活躍事務為trx8、trx4、trx3。根據活躍的trxid,我們可以獲取到兩個id,一個是比較舊的快照即up_limit_id;另一個是比較新的快照地址即low_limit_id。如果當前事務的id小於up_limit_id,說明這屬於比較老的快照地址,對當前查詢來說事務可見;如果當前事務的id大於等於low_limit_id,說明是非常新的快照地址,事務不可見。當處於兩者之間時,就需要判斷是否為活躍狀態。

我們以下圖為例,來說明如何把全局可見性視圖串起來。有四行記錄,分別是ROW0到ROW3,需要查詢一個比較老的快照(up_limit_id:76),我們可以看下每一條記錄的查詢情況。ROW0行有兩個版本,trxid:100和trxid:62。ROW1行有trxid:80、trxid:75、id32三個版本。ROW2只有trxid:20一個版本。對於ROW0,滿足條件的是trxid:62。對於ROW1,滿足條件的是trxid:75和trxid:32,因為我們找快照時是根據列表找到滿足條件的第一個快照,而非找到最老的trx:32,要找的是trx75。另外對於ROW2,當前只有一個版本,且只有20,這時已經滿足條件。

file

InnoDB本身是使用MVCC機制來解決讀寫併發問題,通過Undo log來對應事務中的讀寫語句。Undo log記錄的是每個舊的鏡像版本,當事務需要讀取舊版本時,可以通過鏈表去回溯舊的版本。當需要回滾時,也可以基於Undo來進行相關的數據回滾。

TDSQL實現全局MVCC的原理與InnoDB相似,將全局的trxid和全局事務序列對應,將trxid和全局GTS進行關聯,從而實現全局的MVCC。如下圖所示,全局場景下會存在全局序列GTS。對於trx6,其GTS值為150,對它可見的GTS必須小於等於150,如果比它大則不可見。因此trx7和trx8對其不可見;trx5的GTS是100,小於150,因此可見;trx4是大於100,在100-150之間因此可見;trx3的GTS值是300,也不可見。

file

對於trx8、trx7、trx4和trx3,我們要分別找到對應記錄行的Undo歷史版本。如果找到的Undo項的GTS值依然大,就繼續往前找。對於trx8關聯的記錄行通過undo鏈的回溯,最終找到的記錄所綁定的GTS是30,以此類推對於trx7“最終記錄行”是70,trx4是40,trx3是20。這樣trx6,trx8、trx7、trx5、trx4、trx3對應“可見的記錄行”的GTS值分別是30、70、100、40和20。

回到前文流程,這時全局事務還在COMMTTING過程中,一個事務已經提交,另一個事務沒有提交,在另外一個讀事務掃描記錄行的過程中,讀取到前兩個寫事務時,我們可能都要通過undo獲取他們的歷史版本。TDSQL的全局可見性演算法是把節點局部的trxid和全局GTS進行映射關聯,實現全局MVCC,從而消除讀寫衝突和一致性問題。

我們以一個寫事務和讀事務的場景為例,開啟MC後,TDSQL對PREPARE狀態進行了相關處理。當寫事務進行UPDATE操作後,這個事務可能為ACTIVE、PREPARE或COMMIT狀態,此時需要判斷這些狀態是可見還是不可見。

file

對於處於ACTIVE狀態的事務,InnoDB下對非當前事務不可見,轉換為COMMIT狀態後,通過比較GTS,再根據全局層面的可見性來進行判定。同樣地,一個PREPARE中的事務,對於InnoDB或TDSQL都處於等待狀態。如果等的時間久了,則全局的分散式事務效率會降低,需要進行優化。所以每筆請求時,SELECT都會帶上GTS,當掃描到這一行時,會比較數據行的GTS和當前SELECT的GTS,如果SELECT的GTS大於數據行的GTS則可見,否則不可見。當數據行處於PREPARE狀態時,我們還不知道它提交的GTS,此時可見性無法判斷,需要等到進入到提交狀態,才能進行可見性判斷。

下圖所示的場景中,存在兩個UPDATE事務,當第一個節點COMMIT之後,另一個節點仍處於PREPARE狀態,這時我們需要等它提交及返回結果。這個過程中它的狀態不可知,因此無法比較GTS值,則需要等待,不會讀取到中間狀態。

file

3.3 TDSQL全局一致性讀的設計優化

TDSQL主要從三個方面針對全局一致性讀進行設計優化:

  • 在全局的trxid到GTS進行映射後,每次訪問都需要獲取一個MAXGTS和COMMIT GTS,對事務來說需要增加兩次訪問。訪問頻次提高後,如何實現高效映射這是首先需要考慮的事情。
  • 處於PREPARE狀態的記錄,會觸發等待機制導致吞吐量下降,需要想辦法降低等待開銷。
  • 對於沒有走兩階段提交的非分散式事務,需要儘可能減少和MC的交互,在提交階段可以將操作進行合併,合併後只獲取一次COMMITGTS。

file

下圖主要介紹TDSQL在開啟MC之後的優化。首先是tlog,tlog實現了本地MVCC和全局MVCC之間的映射關係,主要存儲的是GTS和trxid。tlog的整體設計非常簡潔,一個tlog里包括4K的數據頁,每一頁包含4K個位元組,一個GTS是64位的無符號整型,占8位元組,整個頁面是128個位元組,128位元組中最後的111位元組是checksum值。因此每個頁面能存儲約496個GTS。

file

第二是trxid和GTS映射。要實現高效的映射,就需要有快速定位的方法。實際上,每個trxid對應到tlog時都有偏移,文件起始的trxid稱為startid,當前的trxid減去stardid乘以8,就是偏移值。基於這個演算法,我們可以快速定位到文件的地址和偏移值,實現快讀定位。

file

第三是tlog和redo。tlog可實現了全局MVCC和GTS映射,這個過程中也需要對XA語句進行調整。我們對這塊進行了微調相容XA語法,每次XA Start和XA COMMIT時,都會攜帶GTS值,把GTS寫到redo的同時也寫到tlog中。為了避免tlog刷新帶來頻繁的隨機讀寫問題,TDSQL採用WAL機制,tlog文件以記憶體映射方式提供讀寫能力。

如圖所示,左側是tlog的buffer,其中tlog buffer和tlogdatafile對應。每次讀GTS時,其實是從tlog buffer頁面去讀。寫GTS時也是寫tlog buffer同時寫入Redo,這樣可以保證tlog的持久化。同樣當實例crash後,可以在啟動階段構讀取到tlog buffer,整個tlog也能構造出一致性。

file

第四是針對PREPARE的優化。以下圖中的場景為例,在T1啟動後,當前MySQL節點已經提交的最大GTS為99,所以PREPARE的GTS一定大於99,至少為100,所以此時為PREPARE的記錄行綁定了100的GTS。

同時又有活躍事務T2進行了COMMIT操作,其COMMIT的GTS為150和200,所以T2提交後把SET1、SET2兩個節點局部緩存的MAX_COMMIT_GTS推進到了150和200。

同時存在的活躍事務T3為一個只讀事務,其GTS為250,那麼它讀取到T1的PREPARE的記錄行時事務將會被阻塞,但是如果T3啟動時綁定的GTS為99,那麼它將直接跳過PREPARE記錄,因為通過PREPARE綁定的100 GTS就可以確定,即使將來該記錄提交也一定對T3事務不可見。

綜上所述,TDSQL針對該流程進行了優化,在進行查詢時,如果當前讀事務綁定的GTS值比PREPARE的GTS值要小,這時我們不用等PREPARE完成,可以直接去找其undo前鏡像,因為該記錄“將來的”COMMIT_GTS一定比當前PREPARE的GTS要大。

file

第五是針對XA的優化。以下圖為例,有SET1和SET2,SET1進行單機事務插入,SET2也在進行單機事務插入,即SET1和SET2插入的事務並沒有任何因果關係。如果在同一SET上同時發起三筆單機事務,需要為這三次COMMIT請求三次MC獲取全局GTS嗎?

TDSQL採用了一個優化措施,此時沒有請求三次MC獲取COMMIT_GTS,而是復用當前MySQL節點上最大的“快照GTS”。如下圖第三階段所示,三個先後開啟的非分散式事務,“同時”提交,此時不再請求MC而是本地獲取全局最大的快照GTS 253。SET1的GTS與SET2本身沒有依賴關係,對SET1而言,發生的是自身的一階段的分散式事務,所以這裡無需通過MC獲取全局最新GTS只需要保證事務的局部時序性,這樣可以減少和MC之間的通信的開銷。

file

TDSQL在MC開啟之後進行多種優化來提升性能。我們在內外部進行多次測試、驗證,得出的結論是MC開啟之後有一定損耗,但可以有效的控制在10%左右,對業務來說影響比較小。在一些INSERT和UPDATE場景下我們對相關模型也進行了優化調整,所以帶來的性能提升非常高。

圖中可以看到,我們在一些混合的TPMC場景測試下,在一臺16C 64G的機器下測試模型,開啟和關閉GTS對性能影響較小。TDSQL使用全局MVCC,再加上輕量的MC特性,可以將GTS的通信次數降低,從而帶來較大的收益。

file

四、TDSQL應用實踐

分散式事務或分散式一致性,不僅僅是資料庫要去解決的問題,很多場景下應用下也會面臨相同的挑戰。對於熱點賬戶的入賬或者面對面收賬等高併發的場景,資料庫仍然存在自身極限,我們認為需要結合應用資料庫一起做優化。

常規方案是將賬戶系統進行切割,包括做單元化、大小賬戶分離等。但是在這些場景中,一個比較極端的場景是:熱點賬戶,只有一行記錄,怎麼進行拆分?這種場景下,我們就要結合應用優化配合TDSQL來實現。

以下圖為例,有兩個賬戶,賬戶C和賬戶B之間進行轉賬,這個過程中一個減少、一個增加。如果我們通過資料庫的分散式事務來進行實現,就會有上限值。如果要謀求更低的處理時效,就需採用非同步消息的方式。

file

比如熱點商戶賬戶收單等場景下,僅靠資料庫層分散式事務已經不能滿足海量的併發場景,採用非同步消息優化的同時我們也會採用多級對賬機制。應用層會有一個交易訂單,交易訂單標記著這筆分散式事務成功與否。當交易訂單形成後,即使該事務在過程中出錯,也可以通過應用層的補償機制對這個事務進行處理。從而實現實時出賬+非同步批量入賬,減少行鎖競爭。

在下圖的紅包轉賬場景下,還需要分散式緩存+全局緩存來進一步深入優化。這種場景下,除了採用非同步賬戶外,我們還需要將一個熱點賬戶拆成多個平行子賬戶,使用消息隊列和分散式緩存,通過多級緩存機制,分別實現多級對賬、多級緩存、平行熱點賬戶、單元化等實現實時出賬、批量非同步入賬。這樣可以將轉賬邏輯從頻繁的網路之間的交互變成一次批量請求,也極大提高了系統的併發能力和事務處理的響應速度。

總的來說,在上述這些極限的高併發場景下,我們需要在應用側和資料庫側做優化和結合,包括採用非同步消息、多級緩存機制等。

file

作為領先的國產分散式資料庫,TDSQL針對新型企業級信息化以及快速實現國產化的轉型升級需求,具備數據強一致、金融級高可用、高性能低成本、線性水平擴展、企業級安全、便捷智能運維等核心特性。

目前,TDSQL已服務金融、政務、工業製造等多個行業領域。未來五年,TDSQL將幫助1000家金融機構實現核心系統國產化轉型,持續助力國產資料庫未來發展。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、初衷 開發中經常需要做一些介面的簽名生成和校驗工作,最開始的時候都是每個介面去按照約定單獨實現,久而久之就變的非常難維護,因此就琢磨怎麼能夠寫了一個比較通用的簽名生成工具。 2、思路 採用鏈式調用的方式,使得簽名的步驟可以動態拼湊組合。 3、直接看效果 //設置數據源 var signSourc ...
  • 在整理 GCC Arm 工具鏈的Bluepill代碼示例, 常用外設都差不多了, 接下來是 FreeRTOS, 網上查到的基本上都是基於舊版本的集成, STM32 SPL版本3.5.0, FreeRTOS版本9.x或者10.x, 不如自己用新版本集成一下. 順便做個筆記. STM32F10x_Std... ...
  • 一、文件目錄類 pwd指令 基本語法:pwd 功能:顯示當前工作的絕對目錄 ls指令 基本語法:ls [選項][目錄或者文件] 常用選項 -a 顯示所有文件及目錄 (. 開頭的隱藏文件也會列出) -l 除文件名稱外,亦將文件型態、許可權、擁有者、文件大小等資訊詳細列出 cd指令 基本語法:cd [參數 ...
  • SourceTree 是 Windows 和Mac OS X 下Git 和 Hg 客戶端管理工具,同時也是Mercurial和Subversion版本控制系統工具,需要的朋友趕快來看看吧! 詳情:SourceTree for Mac(Git客戶端工具) SourceTree Mac是一款針對mac平 ...
  • Haproxy haproxy簡介 HAProxy是一個使用C語言編寫的自由及開放源代碼軟體,其提供高可用性、負載均衡,以及基於TCP和HTTP的應用程式代理。 HAProxy特別適用於那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。HAProxy運行在當前的硬體上,完全可以支持數以 ...
  • 一. 題目: 給如下兩個表,寫一個查詢語句,求出在每一個工資發放日,每個部門的平均工資與公司的平均工資的比較結果 (高 / 低 / 相同)。 工資表:salary | id | employee_id | amount | pay_date | | | | | | | 1 | 1 | 9000 | ...
  • 設置全局 set global collation_connection = utf8mb4_general_ci 設置會話級別 1.配置文件方式,給每個新的連接配置 [mysqld] init-connect='SET NAMES utf8mb4 COLLATE utf8mb4_general_c ...
  • 今天我們來和大家聊一聊一個新話題,一個對於企業業務發展十分關鍵的東西——指標。 指標建設是衡量企業業務效果的主要依據,本文結合自身實踐經驗和大家分享指標的設計與加工過程,講述其基礎概念和設計加工方法,以及設計加工過程中的註意點,希望對感興趣的同學有所幫助。 一、指標建設的必要性 1、什麼是指標 指標 ...
一周排行
    -Advertisement-
    Play Games
  • public static void GetRegistData() { string name = "huishuangzhu"; //搜索到註冊表根目錄 RegistryKey hkml = Registry.ClassesRoot; //搜索到註冊表根目錄下的XXX文件夾。 RegistryK ...
  • 用acme.sh自動部署功能變數名稱證書 安裝ACME 目前使用量最大的免費SSL證書就是Let’s Encrypt,自2018-03開始,Let’s Encrypt官方發佈上線了免費的SSL泛功能變數名稱證書,目前通過DNS方式獲取比較快,國內可以通過鵝雲的DNSPod功能變數名稱API或者貓雲功能變數名稱API自動簽發Let’ ...
  • 經常看到有群友調侃“為什麼搞Java的總在學習JVM調優?那是因為Java爛!我們.NET就不需要搞這些!”真的是這樣嗎?今天我就用一個案例來分析一下。 昨天,一位學生問了我一個問題:他建了一個預設的ASP.NET Core Web API的項目,也就是那個WeatherForecast的預設項目模 ...
  • 1、環境搭建 1.1 依賴 <!-- nacos註冊中心 註解 @EnableDiscoveryClient --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba- ...
  • ULID:Universally Unique Lexicographically Sortable Identifier(通用唯一詞典分類標識符) UUID:Universally Unique Identifier(通用唯一標識符) 為什麼不選擇UUID UUID 目前有 5 個版本: 版本1: ...
  • 虛基類/抽象類 抽象類:有純虛函數的類 虛繼承 通過修飾繼承方式, 如代碼2是虛繼承,被虛繼承的類稱為虛基類 虛繼承派生類的記憶體佈局方式 先是vbptr => 派生類的數據 =>基類的數據 , 對比代碼1和代碼2,發現原本基類數據在前面,派生類數據在後面,但是在虛繼承的時候 基類數據方式放到了後面, ...
  • 下麵給出 Kafka 一些重要概念,讓大家對 Kafka 有個整體的認識和感知,後面還會詳細的解析每一個概念的作用以及更深入的原理 • Producer:消息生產者,向 Kafka Broker 發消息的客戶端。 • Consumer:消息消費者,從 Kafka Broker 取消息的客戶端。 • ...
  • 前面介紹了對稱加密演算法,本文將介紹密碼學中另一類重要應用:消息摘要(Digest),什麼是消息摘要?簡單的定義是:對一份數據,進行一個單向的Hash函數,生成一個固定長度的Hash值,這個值就是這份數據的摘要,也稱為指紋。 ...
  • 弟弟最近要考試,臨時抱佛腳在網上找了一堆學習資料複習,這不剛就來找我了,說PDF上有水印,影響閱讀效果,到時候考不好就怪資料不行,氣的我差點當場想把他揍一頓! 算了,弟弟長大了,看在打不過他的份上,就不打他了~ 稍加思索,我想起了Python不是可以去水印?說搞就搞! 去除水印原理 去除方法: 用 ...
  • 作者:陳昌浩 1 導讀 if…else…在代碼中經常使用,聽說可以通過Java 8的Function介面來消滅if…else…!Function介面是什麼?如果通過Function介面介面消滅if…else…呢?讓我們一起來探索一下吧。 2 Function介面 Function介面就是一個有且僅有 ...