日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

支持自动水平拆分的高性能分布式数据库TDSQL

發(fā)布時間:2023/11/29 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 支持自动水平拆分的高性能分布式数据库TDSQL 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

隨著互聯(lián)網(wǎng)應用的廣泛普及,海量數(shù)據(jù)的存儲和訪問成為系統(tǒng)設計的瓶頸問題。對于大型的互聯(lián)網(wǎng)應用,每天幾十億的PV無疑對數(shù)據(jù)庫造成了相當高的負載。給系統(tǒng)的穩(wěn)定性和擴展性造成了極大的問題。通過數(shù)據(jù)的切分來提高系統(tǒng)整體性能,擴充系統(tǒng)整體容量,橫向擴展數(shù)據(jù)層已經(jīng)成為架構(gòu)研發(fā)人員首選的方式。

2004年,騰訊開始逐步上線互聯(lián)網(wǎng)增值服務,業(yè)務量開始第一次爆炸。計費成為所有業(yè)務都需要的一個公共服務,不再是某個服務的專屬。業(yè)務量的爆炸給DB層帶來了巨大的壓力,原來的單機模式已經(jīng)無法支撐。伴隨計費公共平臺的整合建設,在DB層開始引入分庫分表機制:針對大的表,按照某個key預先拆成n個子表,分布在不同的機器節(jié)點上。邏輯層在訪問DB時,自己根據(jù)分表邏輯將請求分發(fā)到不同的節(jié)點。在擴容時,需要手工完成子表數(shù)據(jù)的搬遷和訪問路由的修改。DB層在業(yè)務狂潮之下,增加各種工具和補丁來解決容量水平擴展的問題。2012年TDSQL項目立項,目標為金融聯(lián)機交易數(shù)據(jù)庫。

TDSQL(Tencent Distributed MySQL,騰訊分布式MySQL)是針對金融聯(lián)機交易場景推出的高一致性、分布式數(shù)據(jù)庫解決方案。產(chǎn)品形態(tài)為一個數(shù)據(jù)庫集群,底層基于MySQL,對外的功能表現(xiàn)上與MySQL兼容。截至2017年,TDSQL已在公司內(nèi)部關鍵數(shù)據(jù)領域獲得廣泛應用,其中之一作為Midas(米大師)核心數(shù)據(jù)庫,經(jīng)受了互聯(lián)網(wǎng)交易場景的考驗。Midas作為騰訊官方唯一數(shù)字業(yè)務支付平臺,為公司移動App(iOS、Android、Win phone等)、PC客戶端、Web等不同場景提供一站式計費解決方案。

TDSQL規(guī)定shardkey為表拆分的依據(jù),即進行SQL查詢時,shardkey作為查詢字段指明該SQL發(fā)往哪個Set(數(shù)據(jù)分片)。在分庫分表之前需要Schedule初始化集群,我們這里稱作一個Group。在初始化Group時要確定最初的分片大小,因而需要確定準備幾套Set。例如,我們需要對邏輯表拆分成四張子表,需要我們在初始化集群時準備四個Set,同時指定每個Set的路由信息,并將這些路由信息寫入ZK,如圖1所示。

圖1 TDSQL分庫分表

完成集群初始化后,Proxy監(jiān)控ZooKeeper中的路由節(jié)點,當發(fā)現(xiàn)新的路由信息后,更新新的路由到本地。當用戶通過Proxy創(chuàng)建表時,一個建表語句發(fā)給Proxy必須指定shardkey,例如create table test_shard(a int, b int) shardkey=a。然后,Proxy改寫SQL,根據(jù)路由信息,在最后增加對應的partition clause,然后發(fā)到所有的后端Set,如圖2所示。

圖2 Proxy建表語句

這樣,就完成了一次建表任務,用戶看到的是一張邏輯表test_shard,但是在后端創(chuàng)建了4個實體表test_shard,后續(xù)用戶通過網(wǎng)關進行帶shardkey的增刪改查時,Proxy便會根據(jù)shardkey的路由將SQL發(fā)往指定Set。

在單實例MySQL中,用戶可以通過auto_increment屬性生成一個唯一的值,在分布式數(shù)據(jù)庫下,利用MySQL的自增屬性,只能保證在一個后端實例內(nèi)實現(xiàn)自增和全局唯一,無法保證整個集群的唯一。

為了保證整個集群的唯一性,很顯然不能依賴于后端的數(shù)據(jù)庫,而需要Proxy生成對應的值。同時在實際運行中,Proxy可能有多個,并且可能有重啟等操作,通過Proxy自身也很難做到全局唯一,因此選用了ZooKeeper作為唯一值的生成工具。

通過ZooKeeper的分布式特性,可以保證即使多個Proxy同時訪問,每次只會有一個Proxy能夠成功拿到,使得生成的值是全局唯一。從性能上考慮,不可能每次都與ZooKeeper進行交互獲取,因此每個Proxy每次都會申請一段值,都用完后才會向ZooKeeper進行申請。

圖3 全局唯一字段表創(chuàng)建過程

這種設計方式實現(xiàn)了分布式環(huán)境下的自增屬性全局唯一。每個Proxy緩存一定數(shù)量的值,并且增加單獨線程負責向ZooKeeper申請值,使得性能影響降到最低,同時具有容災特性,即使Proxy掛了或者重啟,都能保證全局唯一。但是缺點是:多個Proxy一起使用的時候,只能保證全局唯一,不能保證單調(diào)遞增。

全局唯一字段的創(chuàng)建方式和普通的自增字段一樣:

create table auto_inc(a int auto_increment,b int) shardkey=b;

使用方式也相同:

insert into shard.auto_inc ( a,b,d,c) values(1,2,3,0),(1,2,3,0);

對應的字段如果賦值為0或者NULL時,由Proxy生成唯一的值,然后修改對應的SQL發(fā)送到后端。同時也支持select last_insert_id(),返回上次插入的值,每個線程互相獨立。

在分布式數(shù)據(jù)庫中,數(shù)據(jù)根據(jù)shardkey拆分到后端多個Set中,每個后端Set保存的都只是一部分數(shù)據(jù)。我們可以方便地在一個Set內(nèi)做各種復雜的操作,如JOIN、子查詢等。分布式JOIN依賴于網(wǎng)關的語法分析,何為語法分析?簡單來說,語法分析主要做兩方面的事:判斷輸入是否滿足指定的語法規(guī)則,同時生成抽象語法樹。對于詞法分析以及語法分析,開源有多種現(xiàn)成的工具,不需要從頭開始做,Linux下用的比較多的是Flex和Bison。

圖4 語法分析過程

有了語法分析的支持,對于涉及分布式JOIN的查詢,例如表t1和t2要做JOIN操作,可能使用不同的字段作為shardkey,這樣根據(jù)shardkey路由后,相關記錄可能分布在兩個Set,網(wǎng)關分析后先將數(shù)據(jù)表t1數(shù)據(jù)取出,然后再根據(jù)t1的shardkey去獲取t2的數(shù)據(jù),網(wǎng)關在這個過程中先做語法解析再進行數(shù)據(jù)聚合,最后返回給用戶結(jié)果集。此外,在實際業(yè)務中,有一些特殊的配置表,這些表都比較小,并且變動不多,但是會和很多其他表有關聯(lián),對于這類表沒必要進行分片,因此支持一種叫做全局表的特殊表。如果用戶創(chuàng)建時指定是全局表的話(g1),該表全量存放在后端的所有Set中,查詢時隨機選擇一個Set,修改時修改所有Set。如果對全局表進行JOIN的話,就不需要限制條件,即支持select * from t1 join g1。

針對分布式事務,TDSQL采用兩階段提交算法來實現(xiàn)分布式事務,其中Proxy作為協(xié)調(diào)者,狀態(tài)數(shù)據(jù)持久化到全局事務管理系統(tǒng)中,目前選用的是TDSQL本身的一個InnoDB表來保存(gtid_log);所有的Group作為參與者來負責具體子事務的執(zhí)行。

圖5 分布式事務

Begin;

Statment1;

Statment2;

Proxy為該事務分配一個ID,并將SQL轉(zhuǎn)為:

Xa begin “id”

Statment1;

Statment2;

Client最終向Proxy發(fā)送commit。

Proxy向所有參與該事務的Set發(fā)送:

Xa end “id” 標識該事務的結(jié)束;

Xa prepare “id” mysql將事務計入Binlog,并通過Binlog傳遞給Slave,不同于普通事務,寫入Binlog之后該事務仍然沒有提交;

如果任意Set在 prepare過程中失敗或者超時,由于此時還沒有寫存儲引擎日志,MySQL自動rollback這個事務,并向Client返回相應錯誤信息。

當Proxy收到所有Set的prepare響應之后,Proxy更新gtid_log表將對應XID的事務置為commit狀態(tài);Proxy隨后向所有Set發(fā)送Xa commit “id”,Set收到該請求之后提交該事務。

Proxy等待所有Set的commit響應,當所有Set返回成功,Proxy返回前臺成功。若其中一臺返回失敗(當Set發(fā)生重啟等故障時,需要等待Agent補提交該事務,因而當前屬于未提交狀態(tài)),Proxy返回前臺狀態(tài)未知,稍后請繼續(xù)查詢事務狀態(tài)。

當Proxy在第四步寫完commit后,開始逐個Set提交事務,當還沒有完成所有Set提交時Proxy發(fā)生宕機,剩余Set中未提交的事務由Agent來提交,以此來保證事務的一致性。Agent會定期通過命令Xa recover查詢MySQL中處于prepare狀態(tài)的事務,再對照gtid-log表查詢該事務是否處于commit狀態(tài),如果是則comimt。否則可能由于prepare成功后寫gtid_log失敗,因而Agent需要將該事務abort。

TDSQL支持三種模式的讀寫分離。第一種模式下網(wǎng)關開啟語法解析的配置,通過語法解析過濾出用戶的select讀請求,默認把讀請求直接發(fā)給備機。這種方案的缺點有兩個:1. 網(wǎng)關需要對SQL進行分析,降低整體性能;2. 當主備延遲較大時,直接從備機獲取數(shù)據(jù)可能會得到錯誤的數(shù)據(jù)。

除了上述模式,TDSQL支持通過增加Slave注釋標記,將指定的SQL發(fā)往備機。即在SQL中添加/slave/這樣的標記,該SQL會發(fā)送給備機,即用戶能夠根據(jù)業(yè)務場景可控地選擇讀寫分離,即使主備延遲比較大,用戶也能夠根據(jù)需要靈活選擇從主機還是備機讀取數(shù)據(jù),這種模式下網(wǎng)關不需要進行詞法解析,因而相比第一種方案提高了整體性能。但是,這種方案的缺陷是改寫了正常SQL,需要調(diào)整已有用戶代碼,成本較高,用戶可能不太愿意接受。

表1 三種讀寫分離模式比較

針對前兩種讀寫分離的不足,最新版本的TDSQL增加了基于只讀帳號的讀寫分離模式。這種模式下,由只讀帳號發(fā)送的請求會根據(jù)配置的屬性發(fā)給備機。有兩種可配屬性,IDC屬性和備機延遲屬性。IDC屬性可配置三種屬性:1. 為同IDC屬性,即只讀帳號的請求必須發(fā)往同IDC的備機;2. 優(yōu)先發(fā)給同IDC的備機,但當同IDC的備機不存在或宕機時,發(fā)往不同IDC的備機;3. 如果找不到滿足條件的備機,則發(fā)往主機。延遲屬性:如果延遲超過閥值,認為該備機不可用。只讀帳號能夠在既不改變原有用戶代碼,又不影響系統(tǒng)整體性能的前提下,同時提供多種可配參數(shù)解決讀寫分離的問題,更具有靈活性和實用性。

2014年微眾銀行設立之初,在其分布式的去IOE架構(gòu)中,TDSQL承擔了去O的角色,以TDSQL作為交易的核心DB,承載全行所有OLTP業(yè)務。2015年,TDSQL和騰訊云攜手,正式啟動“TDSQL上云”的工作,接入了一系列傳統(tǒng)以及新型金融企業(yè),覆蓋保險、證券、理財、咨詢等金融行業(yè)。目前,分布式TDSQL正作為騰訊日益重要的金融級數(shù)據(jù)庫,搭建著上百個實例,部署于上千臺機器,日均產(chǎn)生TB級數(shù)據(jù),承載著公司內(nèi)外各種關鍵業(yè)務。

在未來,TDSQL重點會在數(shù)據(jù)庫性能、分布式事務、語法兼容三個方面做改進。目前TDSQL基于MariaDB 10.1.x、Percona-MySQL 5.7.x兩個分支版本,后續(xù)我們會緊密跟進社區(qū)并及時應用官方補丁,同時不斷針對金融場景的特性對數(shù)據(jù)庫內(nèi)核進行優(yōu)化,以此來提升數(shù)據(jù)庫性能和穩(wěn)定性。當前分布式事務處于初級階段,對ZooKeeper的依賴性較強,后續(xù)可能針對分布式事務的可靠性做持續(xù)改進。由于TDSQL在分表環(huán)節(jié)對語法層做了一些限制,將來我們希望通過對網(wǎng)關解析器的改進,使其能夠支持更豐富的語法、詞法。

轉(zhuǎn)載于:https://www.cnblogs.com/jellyru/p/6894778.html

總結(jié)

以上是生活随笔為你收集整理的支持自动水平拆分的高性能分布式数据库TDSQL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。