您好,登錄后才能下訂單哦!
騰訊云數據庫國產數據庫專題線上技術沙龍正在火熱進行中,3月5日林曉斌(丁奇)的2020首場分享已經結束,沒來得及參與的小伙伴不用擔心,下面就給大家奉上直播視頻全程回顧,流量傷不起的小伙伴們也可以看由騰訊云數據庫整理好的文字稿,干貨滿滿,保證讓你有所收獲。
關注“騰訊云數據庫”公眾號,回復“0305丁奇”,即可下載直播分享PPT。
點擊查看完整直播回放
大家好!我是騰訊云數據庫的林曉斌,在社區活動的時候網名叫丁奇,跟比較多的同學互相認識,今天跟大家就是找個機會聊一下數據庫的基礎,還有騰訊自研數據庫的技術演進,我相信來聽的同學應該都是對數據庫都比較熟悉,前面的內容會比較快地過,主要還是講我對數據庫典型架構的一些理解,當然我知道MySQL的分享有很多,所以今天的大部分內容可能很多人都比較熟了,但是如果有一兩個點,你覺得好像是個新東西,我覺得我們就成功了。
首先先說數據庫的基本概念,實際上其實如果我們只是要一個數據庫的話,數據庫就是拿來存東西的,存跟取就是它的基本功能。
在這里可以舉一個暴露年齡的例子——就是我21世紀初讀大學的時候,給老師課程網站和外面公司做信息管理系統都用的是Access,那個時候就覺得只要我會建了索引數據庫就都掌握了,數據庫挺簡單的。當然后面事實證明是我自己太簡單了,后來工作有機會接觸Oracle和MySQL這些工業數據庫,才算是知道了什么是真正的數據庫。
實際上我們說數據庫發展到現在,一直會有這么幾個挑戰——可靠性、可用性、安全性、性能和成本等,因為今天時間的關系也很難全部講,所以今天我們就講一個點—— 性能。
那么性能的問題是怎么來的?
如果數據量很小,訪問量也很小,其實一個Access就夠了,甚至如果更小一點,搞不好一個Excel就夠了是吧?實際上真正給性能問題帶來挑戰的,主要是以下3個方面的原因:
1.大數據量。數據量特別大,存跟取影響了性能;
2.大并發。比如有很多個請求或者很多個客戶端一起來訪問;
3.讀寫模式。讀寫模式什么意思呢?雖然是同一份數據,但是我們在查詢的時候,會有不同的查詢需求,比如說以前論壇的帖子列表,如果你只是按順序顯示出來,那是比較簡單的;如果你要在里面搜東西那會難一點;如果你還要做一些統計和做一些分析,那就更難了。不同的讀模式,對數據庫的查詢壓力是不同的。越復雜的,比如剛才說的搜索或者說分析等這樣的操作本身對數據庫的讀的壓力就跟普通的按行讀取不一樣,所以這些是我們真正需要去解決的數據庫性能問題。
說到這里就需要談到MySQL的基本架構,它在解決不同的讀寫模式上面剛好有優勢。下面這個圖大家應該比較熟悉了,這是MySQL的基本架構。MySQL是分成上下兩層的,上面這個框我們叫做server層,就是服務器層,負責跟客戶端做連接,做分析器、優化器、執行器,下面會分成多種類型的引擎,這是MySQL相比于其它的數據庫特有的一個特性, 可以接不同的引擎,每一種引擎可以設定自己的讀寫存取模式和索引的構建方式,來應對不同的查詢需求。
常見的MySQL引擎有很多,比如說MyISAM,就是MySQL原生的一個引擎,在MySQL5.5之前是默認的存儲引擎,但是它的問題是不支持事務,也不支持crash-safe,就是主機斷電的時候可能會丟數據,所以后面用得越來越少了。
Innodb現在是最主流的關系數據庫引擎,它解決了什么問題呢?首先它能支持事務的ACID特性,也支持崩潰恢復,所以變成現在最主流的MySQL引擎了。
Memory引擎用得也挺多的,早期版本Innodb的性能還沒那么好的時候,我們有時候會想用內存引擎來替代Innodb,這樣的話可能會快一點。當然我們知道Memory引擎重啟以后數據會丟失,但是有時候純粹就把它拿來當緩存服務用,有些公司的dba會喜歡用Memory,實際上Innodb發展到現在,其實已經可以不需要Memory引擎了。數據量小的話,放在Innodb里面基本上都是可以全部緩存的。
那寫的能力呢?如果說Innodb是磁盤型的,寫的時候要落盤,其實性能一方面是現在的SSD硬盤普及也快了,另外一個很重要的原因是因為Memory不支持并發,你看上去單個線程的讀寫很快,但是如果你有兩個線程一起要更新同一張表的時候,它就要排隊,不像Innodb一樣支持行鎖。所以現在從總體看通用的使用場景的話,Memory其實是不如Innodb的,所以慢慢用的比較少,像騰訊云的CDB現在直接不建議也不允許用戶創建內存引擎了。infobright可能也是老玩家才知道的,就是一個列存引擎,可以做OLAP業務的一個引擎。
blackhole是一個黑洞引擎,是什么意思呢?只有表結構,往里面寫的數據都不存,直接就沒了,也不會給你訪問報錯,只會告訴你執行成功,看上去像個黑洞,一會我們也會介紹一下這種引擎的使用場景。
federated是一個遠程鏈接的引擎,你在這邊建一個表,但實際上數據不是存在本地,可以讓你定義數據源在哪里,然后到另外一個地方去取。
還有RocksDB和TokuDB引擎,是基于LSM或者fractal tree,不是基于B+tree的一個支持事務的引擎,這兩個引擎比較明顯的特點是壓縮率比Innodb高,主要原因是壓縮塊比較大,我們知道Innodb里面16K一個塊來壓縮的,越大的單位數據壓縮效果會越好,像TokuDB是4M一個塊來壓縮的,所以它的壓縮比高,當然它帶來問題就是讀的時候CPU消耗多一點。
比較常見的是這些引擎,當然你可能還可以列出別的,但基本上社區用的比較多的是這一些。
那么MySQL有這種多引擎的架構,有什么好處?剛才我們說了,當一個業務既需要TP型的業務,但是又需要做列存和分析時,如果是換別的數據庫,比如說postgresql或者Oracle,本身就很難同時兼容這兩種能力。而MySQL可以不走引擎,我可以表A創建出一個Innodb表,表B創建一個infobright表,然后數據在里面做同步,以后我如果要做oltp的查詢,就找Innodb表查,AP的查詢就找infobright查,至少它的架構可以這么做。有的同學會覺得很奇葩,混合引擎這種是不是很少見?其實并不是,MySQL天然就這么干的,默認的存儲引擎我們現在都用Innodb,實際上MySQL自己的系統庫在5.6和5.7及以前的版本都是用的MyISAM,如user表,這個是存用戶的表、還有存庫名的表等,其實就是放在MyISAM里面,所以MySQL本身就在踐行混合引擎,當然是需要特別謹慎的。
舉個例子,比如跨引擎事務的一致性問題。我們知道Innodb是支持事務的,而MyISAM是不支持的,假設說現在有一個庫,里面有兩個表,T1是MyISAM表,T2是Innodb表,如果你分別使用是沒有問題的,如果我們想要事務,begin啟動一個事務,往T1表里面插入一行,再往T2表里插入一行,然后執行一個rollback,我們認為既然begin后面沒有提交,然后最后執行的一個rollback,那就應該T1跟T2這兩個插入都撤銷,這就是事務的原子性,要么都成功,要么都失敗。
但是因為MyISAM不支持事務,也就是說insert into T1執行完以后,馬上就持久化了,就寫到數據里面去了,所以這一個序列執行完成以后,在數據庫里就會看到T1里的那條數據還在,T2里面的這條又不在了,這個是違反了事務的原子性規則的,對,但不是引擎的問題,這是因為我們寫法本身有問題。這樣你也會更明確知道:原來事務的特性是實現在引擎里的,支持的引擎就支持,不支持的引擎它就只好忽略。我自己之前在應用的一些場景里面也用過,同一個數據庫里面有不同引擎的表是OK的,但是當你要用到一些引擎的特性的時候,像事務,或者說savepoint、全文檢索這種比較特殊的特性,或者全文檢索的時候,就要去關注引擎到底支不支持,如果不支持那就不能做,不能混用。
這種場景大家可能會說好像用的不太多,我們再看下面這個圖,把Innodb跟infobright放到一起,雖然MySQL天然就支持,但是它有個問題,感覺看上去不是很專業,還有比如說你在infobright上面跑AP的請求,雖然也可以,但是畢竟我們知道它們共用的server層是同一份,這樣的話會不會導致它們互相爭強CPU?其實是會的,那如果想要想剝離出來可以怎么做?那就是下面這個圖。
就是說你可以搭建兩個不同的MySQL實例,然后主實例用Innodb引擎。slave實例用infobright引擎。因為MySQL的主從同步是可以支持跨索引跨引擎的,也就是說假設左邊有一個表T1,它是Innodb表,而同步過來,slave上面的T1,手動把它改成infobright或者別的引擎的表,這樣是可以同步的。也就是說往主庫里面做增刪改,都可以同步到從庫的infobright相同的表名里面,之后你要做AP型的查詢,就直接到從庫這里面來查,它是列存的,這種OLAP的請求就足夠快,這是其中的一種用法。
另外這種用法其實還是有比較多的引申版本,比如說中間這個通道,現在圖里面看到我這樣畫,其實就是MySQL天然的主從同步機制,當然我們可以中間放一個數據傳輸組件DTS,然后從主庫拉日志到從庫去應用,這個是類似的,這是一種場景,這種場景下面解決的是什么問題?主庫跟備庫的數據是一樣的,查詢的邏輯不太一樣,需要備庫提供更強的不同于Innodb的能力,這個時候就可以換一個引擎來用,這種場景還是偶爾會見到。
還有另外一個場景,黑洞引擎有什么用?
我們還是回到圖的左邊,左邊是一樣的,TP這個業務MySQL里面寫,里面是Innodb表,然后傳到從庫去,從庫把它改成blackhole引擎。我們剛才說到了blackhole引擎只有表結構,數據寫進來以后數據就沒了,那么你傳過來干嘛呢?傳過來存binlog。MySQL的機制是當左邊寫了數據跟日志以后,如果要同步給從庫的話,它一定要把binlog傳過來給從庫,從庫收到日志以后做什么事?做兩件事,先把日志存在本地,再把本地的日志拿來應用,應用完以后,再從庫里面生成出一份相同的日志。如果你把它改成blackhole引擎,那后面那一步就沒有用了,拿到日志,后面的執行就是空執行, 表雖然沒有,但是日志還在,那簡單來說這個就可以用來存binlog,這樣話要備份binlog就不需要到主庫上面去拷了。去主庫上面拷也不實時,通過這種方式就可以實時拿到binlog。當然現在這只是說MySQL天然支持這樣的機制,實際上現在社區也有不少比較優秀軟件本身也可以做相同的事情,可以模擬binlogserver的行為,找主庫要binlog,要完以后也不應用,就存在本地,只是說如果我們要搭建一個簡單的binlog server,就可以讓從庫用blackhole引擎,其實用的也還挺多的。
有的同學說這看上去有點傻,還不如用像社區的那些方案,實際上如果可以再往前擴展一下,還可以想到別的場景,比如說我們要做分布式的場景,一般要多個節點,因為要做選舉對吧?比如說我們要做跨中心跨城市的高可用集群時候,集群節點可能很多,比如說在A城市有5個節點,B城市有4個節點,9個跑起來特別爽,是吧?掛了一個以后都可以選舉選出來,它有個問題是什么?成本比較高,因為你每個地方都要放數據,這樣的話有沒有節約成本的方法?之前也有人踐行過這樣的方案,就是說這9個節點也不是真的要那么多數據,其中有一部分純粹就只是想參與選舉而已,甚至于你自己都不想被選成,只是參與投票而已,那就可以用blackhole引擎,它可以同步數據跟大家形成交互,然后參與投票,當然它要把自己標志成不能被選成主,這樣雖然你有9個節點的成本,但實際上你真正需要的存儲可能只有5個或者4個就可以了,其它的用binlog server來模擬,這個也是之前有踐行過的架構。
反正在中國大批量使用MySQL到現在有十二三年了,中間各種各樣的架構都出現過。再說到另外一個場景,誤刪了數據,然后這時候你要恢復,恢復有一種場景是這樣的,假設這個庫里面有業務數據表A,還有業務日志表B,一般來說日志表都比數據表比較大很多,因為中間記了各種流水,我想恢復出一個庫,恢復數據是拿昨天的備份恢復的,然后拿到全量數據后應用binlog追到我要的時間點。而如果現在特別著急的想要,又剛好昨天業務壓力大,所以日志表的更新量特別大,恢復出去全量備份以后,接下來你拿日志不停地應用,然后你會發現多時間都在等日志表的回復,因為日志表更新多。如果我現在很明確,先暫時不要日志表,先把這個數據表給恢復出來,有什么方法?當然方法有好多,我只是說如果用blackhole可以這么干,你就把日志表給它清空掉,或者說移走,然后創建一個同名的,引擎叫Blackhole的表,放在那邊是一個空表。接下來它開始追日志,它的好處是現在日志表追的特別快,因為這個引擎的特性是什么?你寫的時候它就一看我是blackhole引擎,命令過來,就直接跳過,這樣應用就非常快,這樣話你就可以快速達到恢復數據表的目的。所以支持引擎其實還是有點有趣的,雖然說它不是主流的應用,但在單機的MySQL里面支持這樣的能力。
我們接著往下說MySQL的高可用架構,大家都知道怎么做高可用,一般是一主兩備或者至少一主一備,然后往主庫寫,主庫掛了就切到從庫去。從左邊切到右邊就實現了一個HA,除非AB兩個一起掛,運氣不好,但是概率小很多。如果一臺機器掛了是千分之一的概率,兩個一起掛就是百萬分之一的概率,這個已經很小了,所以一般是這么做的。然后A跟B之間比較主流的實現會設置成互為雙組,這樣話切換的時候快一點,你只要把客戶當成左邊切到右邊就可以了,這是典型的MySQL的高可用架構,但這個不是我們今天描述的重點,只是說我們后面要講的時候,每講一個數據庫節點的時候,它默認是帶著主從。
我們還是回到性能這個問題,我們怎么解決讀性能的問題?加機器!DBA的核心技能兩點,第一個是重啟,第二個是加機器。(笑)
那么加機器加成什么樣的?我們看到一主好多從,圖中除了A跟A′是用來做主備做高可用的以外,像BCD本身沒有業務直接給它們寫數據,但是是從A這個節點里面把數據同步過來的,就是你寫一份A它會同步給A′做高可用,同時同步給BCD,BCD拿到日志應用完以后,我們認為BCD的數據跟A是一樣的,接下來客戶端就可以來找BCD來讀了。這樣如果A撐不住讀壓力,可以把讀請求分流分給BCD,這算是比較樸素的方案,在騰訊云MySQL里面有功能叫做RO組,比如說我現在有三個只讀實例,三個只讀節點,如果再創建一個,客戶端得改配置。實際上一般云服務都會提供這種能力, 把這些只讀實例設置成一個RO組,接著它們共享同一個訪問方式,或者同一個域名,或同一個IP,接下來寫只要寫一個,讀也只要讀一個,RO組會幫你做查詢的輪巡和流量的分擔。
但有的同學說看著還是麻煩,寫和讀難道就不能也湊成同一個IP嗎?這樣我還得知道寫是寫哪個,讀是讀哪一組,讀跟寫畢竟兩個IP,有沒有偷懶加機器的方法或者說透明加機器的方法?有!就是下面可以加個proxy。
下面加一個中間層以后其實底層的架構是一樣的,只是說往proxy里面訪問的時候,proxy幫你做分流,如果是一個寫操作發給主庫,如果是讀操作發給下面其他讀節點,所以本質上是差不多的,好處就是你可以省得自己去管了,并且也不需要考慮擴容。
比如說騰訊的TDSQL就支持這個讀寫分離的模式,你要加節點的話,你也不用管了,就是下發一個加節點的需求,內部它自己幫你復制出一個E節點,然后把數據全量的恢復完以后追日志,然后再跟A建立主從關系等等,做完以后你就做了一個節點了,這種方式可以解決我們的讀性能問題,那讀性能解決了,寫性能怎么辦?我們看到剛才這兩種模式,它們有個共同的特點——讀是可以讀好多個,能寫只能寫一個,如果寫A撐不住了怎么辦?分庫分表。所以我們說 寫性能就只能靠分布分表了,TDSQL也支持分庫分表的模式,就是你寫下來,然后做路由,當然這個路由要事先和數據庫約定好分表的方式和分片的方式,比如說創建一個表,然后用戶ID取模,這樣的方式也是比較常見的分庫分表的模式。
現在還有一些比如計算存儲分離等模式,思路其實是差不多的,都是用來解決同一個問題,就是通過水平擴展節點的方式來分攤讀壓力或者寫壓力,然后提升我們整個系統的吞吐量。但是實際上MySQL也不是全能的,其實你想了各種方案,但是還是有支持不了的場景的。
舉個例子,比如說OLAP就不支持,像剛我們說的infobright還可以,但實際上infobright現在用的也不是那么多,真的做OLAP實際上是有專門的系統來做的,一會兒我們可以舉一個例子。
像圖這種關系數據庫,比如說MySQL,我們大家都知道是標準的二維表,要描述一個圖只能用這種遞歸查詢的方法,性能天然就有問題,你可以做,所有關系最后都表達一個二維表的關系,無非是這個關系處理比較蹩腳而已,速度會慢。
時序數據庫,能不能用一個InnoDB表來存時序表?當然也可以,insert從一開始往后追加,然后查的時候也是,讀的時候也是,從一開始往后刪也是,看上去就是一個先進先出的隊列,可以這么做,但是是浪費的,因為一個時序的場景只需要先進先出這個功能,所以InnoDB提供了那么多中間數據的讀寫能力,其實是一個浪費,而這種浪費體現在時序數據庫應用場景上面來說,在最簡單的場景里,就是性能不行。
還有一個是搜索,雖然大家也知道最早MyISAM的引擎還支持一些全文檢索,后來Innodb為了替換掉MyISAM,官方也給Innodb加上了全文檢索的能力,但是據我所知,也沒有哪個公司真的要使用全文搜索能力的時候會大批量使用Innodb,而是會去搭建真正的像ES這樣的全文檢索引擎,圖也是一樣,OLAP有OLAP自己的系統,所以MySQL還是有它不適用的場景,核心的原因其實是數據結構,我之前在《MySQL實戰45講》里面跟大家有提到,當我們去 分析要選擇哪一個數據庫的時候,核心的點是要先考察數據結構,如果它是一個列存的需求,每次查詢可能要查詢一個一億行,但是我就是要只查詢于其中一列,這種場景特別多,MySQL能不能做?能做,但是MySQL是行存,每次你要取一個一億行的第一列的時候,它就必須把那一行全部讀進來,然后就浪費了很多IO資源和不必要的CPU消耗。這個時候如果有一個專門做列存的,它有一個文件專門存了這一個表第一列的數據,讀的時候就直接讀出來,就減少了大量的IO消耗跟CPU消耗,這就是數據結構帶來的優勢。
MySQL雖然也支持,也有說往MySQL里面加一些引擎來支持,但是如果我們主流用Innodb,它就不適合做這個事。還有比如說搜索也是,我明明要的是一個倒排表,可是你非得給我個關系數據庫,所以它本質一樣是一個數據結構的問題。我覺得這樣才好,MySQL就要有這么多不適用的場景,不能有哪個數據庫可以通吃所有的場景,那樣才麻煩。我們舉個例子,比如HTAP這種場景,剛才我們前面有個圖說了,我用一個MySQL加了一個infobright也可以,但是不是最專業的,它畢竟還是一個單機版,其實現在比較主流的方式,把這里替換成一個專門做AP,在AP上面有很強能力的一個產品,這樣它天然就可以支持,而且中間的比如說往這里寫的TP還可以自己寫,然后數據傳輸留的通道也可以保持,只是你把下面這個核換成一個可以專門支持這種場景能力的產品,比如騰訊云TBase,它就可以專門支持這樣的場景然后來解決,這樣才好。
做一個小結,我們雖然只討論了性能問題,性能問題其實只是數據庫發展過程中碰到的各種復雜問題其中的一個,而且目前看來,甚至于它大多數時候不是最嚴重的,是吧?安全性、可靠性那些才是挺難的。另外,每一個方案都是妥協的結果,讀寫分離看上去很美,實際上它不能解決寫的問題,分庫分表看上去更美,但是中間proxy往往要處理SQL兼容性的問題,因為那個時候你的proxy就需要做很多數據本身的操作,就會碰到語法兼容性的問題。數據庫后來就會碰到更多的挑戰了,在我看來接下來智能化運維是重點方向之一,當然現在大家基本上也是每個系統也做到了智能輔助,做到智能輔助就算不錯了。現在業務量越來越大,像我們在疫情期間支持騰訊會議的時候,我們一些智能化的能力會減少DBA的工作量,并且提升線上的服務質量,DBA的精力可以解放出來去做更有價值的事情。
Q1:講講微盟的刪庫事件?
A1:我覺得只是微盟這次運氣不好,碰到這個事情比較嚴重。說回我們在騰訊運營的服務過程中,經常碰到這種客戶,需要回滾,恢復誤刪的數據。另外一個公司,也是比較有名的互聯網公司最近也碰到一個誤刪庫了,那這個怎么辦?如果你用云數據服務,碰到這種情況,之后就是一個常規操作,找一下昨天的備份,然后把日志下載再應用就行了。有同學會說你放在云上,我是個黑客想惡意操作,進去把數據和備份刪了,你不是一樣蒙圈?其實實際上云會考慮更多的點,騰訊云這邊假設你真的有操作數據庫、生產庫的權限,那么或者你可以把庫刪掉,但是備份是刪不了的。我們的備份有兩種,一個是定期備份,一個是用戶主動生成的備份,定期備份的備份是不讓刪除的,比如說你配置了一天備一次保留7天,你只能把數據刪掉,這固定保留7天的備份是不能刪的,如果真的出現了這種情況的時候,我們會保證一定能夠恢復出來。那我們在內部的工程師會不會有這樣的權限?也沒有。其實我們是分開的,可以管理生產服務器的工程師訪問不了備份。其實發展到現在每個公司對數據庫能力的理解不會差很多,尤其人才流動,所以各個公司數據庫的leader其實我覺得水平都是差不太多的,而云的一個好處是以前碰到過各種突發情況的訓練,通過不斷迭代,終于構建出一個可以cover住大部分場景問題的解決方案。
Q2:TBase是基于PG演進出來的HTAP數據庫,為什么不考慮在TDSQL中加入OLAP的能力呢?
A2:TDSQL我們會考慮,因為剛才說了TDSQL本身上面的框架就可以支持讀寫分離,也可以支持分庫分表,中間那一層proxy,其實已經可以認為它已經完全兼容了MySQL的協議,接下來下面如果要AP的,其實換成AP節點是可以的,實際上也在我們的路線里面,只是說目前還沒有把它產品化出來,就放到云上而已。
Q3:MySQL的分布分表有哪些成熟的可靠的方案?
A3:其實我看到最成熟就是找個維度分表,取決于你的查詢模式。舉個例子,如果你是做在線教育的,然后假設你是一個學生表,你就按學生ID或者按學生城市做這樣的分表,基本上這樣就可以了,我感覺沒有很復雜的點。當然你需要解決的問題是如果你按城市分的表,按城市分庫,這時候你要做一個查詢,這個查詢要統計所有9歲學生的情況,這個時候你就不得不給每一個分庫下發查詢,這樣成本消耗比較高,性能會差一點,當然對應的有一些解決方案了。你業務做了分布分表,假設一些統計類的需求,需要做這種不是基于分表索引的查詢的時候,你可以怎么做?可以有一個匯總的大庫,要把數據匯總回去,大庫里面就可以建各種索引,具體實施上可能有差異,大方向上場景就是這類架構,好像發展這么多年也沒有搞出新花樣。
Q4:TDSQL的分庫分表模式,對MySQL語法支持如何?
A4:是這樣的,所有只要你用了分布分表模式的,我都會建議上來之前一定要做一次業務回歸,目前看來90%以上的客戶都是直接遷上來就能用,但如果你的語句里面有那種groupby大量數據的時候,其實也兼容,但是它的性能會差一點,或者說性能跟你在本地的時候不太一樣,這個時候就要經過測試,而兼容性以我們目前的情況來說改造量還是比較小。
Q5:為什么基于中間件的分庫分表的方案,各家公司很少會去實現分布式事務 和 數據resharding ?
A5:不會啊,我們做得很多啊,實際上分布事務我所了解的幾個大的公司都在做,因為這個是繞不開的,畢竟分布分表是一種方向,而下面的節點之間做分布式事務是另外一個方向,而這個方向確實理論挑戰會更大一點,它有它的好處,就是proxy這一層可以做得很輕,甚至于proxy的兼容性問題就直接徹底被解決了。然后選主等就可以在底層自己做,實際上有在做像比如說目前在研發中的TDSQL3.0。我們現在在線上使用的TDSQL2.0其實就是標準的分庫分表的方案。
Q6:可以教教調試MySQL?
A6:調試MySQL要看碰到什么問題,如果是比較簡單的,比如說索引,那比較簡單,如果說是碰到語句都對但是性能慢的,這種比較偏于操作型的操作。如果是MySQL這種自己調優的話,其實可以做一些基本的診斷、開慢查詢日志,像percona toolkit有一些工具,可以直接跑這個工具看到結論。當然慢查詢日志分析存在一個問題,可能很多語句不是慢查詢,就是還不到高峰期的時候,它可能執行200ms,一看慢查詢設置的是1s,所以會以為沒什么問題。但是呢,如果壓力一大就撐不住。這個時候如果能夠有個系統,把所有的語句執行的情況都記錄起來,然后再去做診斷,那肯定比只有慢查詢要好。比如騰訊云MySQL就支持審計日志,你只要開了審計日志,那里面就會有所有的信息,當然你也可以使用DBbrian直接去診斷一下,看看現在的數據庫里有什么問題,一般DBbrain會告訴你存在什么問題,應該怎么加索引,可以通過這種方式去了解為什么要這樣做,了解它的原理。
Q7:TDSQL適用的行業和場景可以舉例說明一下嘛?
A7:MySQL高可用架構可以適用很多場景,底層的安全配置也會在不同的場景不同的應用。舉個例子,比如說TDSQL放在游戲里面,可能只要開啟一個異步就可以了,不用開全同步,但是像張家港銀行這種案例,TDSQL要放到銀行的核心系統里面去的時候,能不能用呢,可以。我們有個配置,必須是全同步,至少一主兩從,數據寫進去后,另外兩個節點都不給我返回,我就不寫了,就會直接報錯,至少有一個給我反饋說成功了,它才會往里面寫,所以現在像TDSQL,我們是定位在做金融數據庫上面的。那我想用普通的讀寫分離方法,能不能用TDSQL呢?可以,也沒有問題,最后由你來決定了,比如我不希望當有兩個從節點都壞了,就不能寫。我希望還是可以正常讀寫,那你可以設置成退化的異步模式。適用場景還是蠻多的,行業不限,還是取決于數據的定位。
Q8:怎么判斷MySQL當前需要分庫分表?通過什么參數可以看到嗎?
A8:一般說我們什么時候需要分庫分表,第一個很明顯的,如果你的數據量大,撐不住了可以使用,比如說一臺機器只有10T,但是一個庫快滿了,這時候分庫分表比較好理解,那如果是空間還沒到,但是性能撐不住了呢,就可以有幾個指標,比如說一個是寫的RT,還有一個是讀寫的RT,還有一個是讀的命中率,因為我們知道MySQL是B+樹的結構,那如果是層數比較少的時候,就是大多數的索引都在內存里,那你每一次查詢都可以在內存里完成,最后,隨著數據量的增大那是不可能了,所以你有1T的數據,100G的內存,那么會有十分之一的數據直接在內存里面,假設再更大一些,那你的命中率就會降低,這里有什么參數可以看呢,就是show engine innodb status這個命令里面有個內存命中率,你一般看正常線上業務的命中率,如果是線上的OLAP,正常的命中率要為99%以上,99.2%、99.3% 這樣才算正常,比如說如果掉到了97%、95% 這種,那就可能就要考慮一下了,可能你還沒有發現這個問題,業務線來找你了,說為什么我的這個請求慢了。為什么會出現這種情況呢,就是因為我們知道InnoDB是B+tree組織的,你要訪問一個數據的時候,你從樹根開始找,要找好幾層才能找到,找到最下面那個葉子節點。雖然現在ssd快了,但是如果IO壓力大了,比如說10ms,那你有一次IO加載10ms還好點,如果樹很高,在索引遍歷的過程中需要去訪問磁盤了,那這個時候性能就慢下來了,所以呢,內存命中率是一個比較重要的參考指標,其實核心是慢查詢,就是業務的反饋。
Q9:您認為目前云數據庫的痛點和難點分別是什么呢?
A9:我們分兩塊,先說用戶。比如說我是一個用戶,我用云數據庫,覺得首先的痛點就是要提升用戶使用這個產品的易用性。我是一個專業的DBA用這個數據庫能不能把我的能力發揮出來,在騰訊云數據庫現在可以看到好多監控信息,但是我能不能更多一些?這個系統有沒有辦法幫我更多的去提供診斷能力?讓我能夠更快的定位問題?然后把精力省下來去解決我們公司內部這種業務架構問題、數據架構問題,把我從一個DBA變成一個數據架構師。
另一部分說云服務商,比如說騰訊云現在有很多的客戶,那每個客戶都來問數據庫為什么慢了,我們團隊那十幾個DBA同學早也瘋了,我們系統要有這樣的能力,能夠不只是DBA能解決的了,我們的一線架構師、售后甚至客服的同學用一套工具就能解決大部分的問題。有這個可診斷性,可以能讓很多能力發揮出來,可以讓后端解放,可以讓一線輕松,然后可以讓我們的客戶有工具了,可以診斷了,可以發揮個人的專業技能。
Q10:除了云數據庫平臺自己的備份,云主機自建數據庫的情況,平臺會自動備份數據嗎?
A10:如果你是在云主機上面,就是虛擬機上面創建數據庫的話,虛擬機本身會有快照備份,但是這個快照只有點的快照。舉個例子,我今天下午五點不小心誤刪了數據,那我拿到今天凌晨12點那個備份可能不夠用,那我還需要中間的binglog,那這個時候呢,你做一個磁盤級別的鏡像未必有能力真的精確追到五點,如果你用數據庫就沒有這個問題,因為我們是天然以實例級別和日志級別來備份的數據。
Q11:TDSQL考慮加入AP功能,那么TBASE和TDSQL的定位有什么不同?
A11:TDSQL加入AP能力就是看你要解決的問題有多大,我舉個例子,假設我要在TDSQL加一個搜索能力,那我除了用Innodb的全文檢索以外,還可以在里面放一個sphinxSE引擎,后面掛一個sphinx,也可以跑,但是你說我要用它來支撐,比如說這個騰訊首頁的搜索,那肯定撐不住。那時候就需要搭建一個專門的搜索引擎來支持。所以我們往TP系統里面加這種能力,它只能是解決跟我TP很接近,但是不需要那么大的計算量的搜索,我可以支持一下,其實這種場景使用已經很多了,因為它有一個好處是數據閉環,就是數據進去TDSQL以后你不用出去,你在這里寫完后,我在這里分析,分析完以后,你直接拿走,這樣用戶的易用性高,但是這個方案會這樣設定為小型的AP系統,像這種AP系統場景有很多的,比如你要給老板做一個報表,日報啊,運營分析系統啊,像這種在關系數據TP里面加上AP的能力這是可以的,那你說我想把它構建成一個超級搜索引擎,那就不是來干這個的。
Q12:proxy 會不會有單點問題?
A12:不是一個,其實可以是有很多個,proxy其實是最不容易成為單點了,舉個例子,比如像我們的TDSQL默認是三個proxy,騰訊云Redis默認是五個proxy,實際上你會發現proxy才更好加節點,proxy沒有狀態,掛了一臺, 我直接找另一把它啟動起來就行了,所以proxy不太會容易成為單點的。
Q13:TDSQL在一主一備模式下通過網關訪問數據庫,進行查詢壓測時主節點的cpu使用率很高 備節點很低,可能是什么原因導致的呢?
A13:如果你只有一主一備,你要確認一下你的分庫規則,你可能把所有的請求都發給主庫了,但TDSQL是有監控的,你可以看哪個主節點和備節點上面分別查詢的請求,舉個例子,如果查詢全在主節點,備節點沒有,那你可能要配置下你的路由規則。
Q14:MySQL雙主模型時,數據不一致怎么解決?
A14:我每次說到這個就要特別講一下,我們這個圖里面,說的雙主其實是,你在任何一個時刻一邊都是Readonly的,狀態1的時候B節點是Readonly然后狀態2的時候A是Readonly,這種就是比較常見的做法,但是有沒有這種多節點寫入的方案呢?有幾個,比如說像這種方案也可以多寫,也就是說客戶端既可以往A寫也可以往B寫,這種如果你用傳統的,比如說現在的MySQL的能力,那就要由業務方來保證我寫入的數據量兩邊不沖突,左邊都寫一個城市數據,右邊都寫一個城市的數據,然后兩邊去同步,這樣不沖突,這是一種。那當然有MRG還有比如Innodb cluster,它自己會做事務之間的沖突檢測,據我了解這個在國內用的并不多,或者說不會把它當為常態互相寫,畢竟你兩邊寫,即使你能做到兩邊不沖突,但是成本會很高。每次要寫一個事務的時候,都要去問下另外一個節點能不能寫,它告訴我能寫才寫,不能寫我就放棄,那這樣的話這個性能就會降下來,所以真正多寫的結構,據我了解,有的公司是用在做切換的時候,當我從A切換到B的時候,比如看圖中架構,如果我從A切換到B的時候有一段時間內是不可寫的,我要把A停寫,然后B同步完后,把請求連到B這邊,那如果你可以支持多寫,中間成本會高些,但是畢竟能寫,這樣的話我就可以同時往A和B同時寫,在很短的時間內把A的更新去掉,這樣的業務的好處就是,業務發現完全不停機,不停寫,但是也只是用在這么一個短暫的時候,它本身天然就與物理規律有點沖突。
Q15:現在推不推薦上MYSQL8呢?
A15:推薦,已經一年多了,我們自己在騰訊云測試環境上測試8.0的性能還是比5.7好不少,所以今年上半年我們應該會推出MySQL8.0的版本。
Q16:原來業務用Oracle,單機能力很強,現在可以用TDSQL或TBase來替換嗎?
A16:我覺得ok,把oracle換成MySQL體系,這個事情呢已經經過證明了,能這么做。
Q17:主從復制是異步的,怎么保證讀取數據的一致性?
A17:這是個大問題,因為今天我們確實沒有時間提到這個,《MySQL實戰45講》里面有一篇專門講這個的,有一些方法,比如說,故意慢一點去讀,或者說查詢的時候有些請求有一定敏感請求放主庫等有各種方法,還有一些可以用GTID來解決。
Q18:怎么入門MySQL源碼?
A18:如果你真的想入MySQL源碼的話,你可以這樣,首先你得有一套MySQL源碼下載下來,然后你可以開debug日志,執行一個簡單語句,debug日志會列出所有調用的函數,然后你就照著函數去數據庫源碼里面找下看看在哪里,可以給自己一個問題。舉個例子,你執行一個select1,當然返回的就是1對不對,你先給自己一個需求,比如我現在想給它寫一個bug,這時候返回2,那我該怎么做,可以試試。當然如果你開發功底不錯可以考慮我們團隊,我們團隊天然干這個的。
Q19:讀寫分離的話,主從同步延遲很大,讀的是延后的數據,不是有損傷嗎,一些調優的參數都試過了,這時是不是該分庫分表了?
A19:如果你的這個主庫和從庫的配置是一樣的,而主庫有讀寫,從庫上并沒有壓力的時候還有延遲,那很可能是因為你的并行度不夠,就是你可能沒有開啟并行復制,你可以開下并行復制試下。如果由于對從庫的查詢壓力過大,導致從庫cpu消耗過大,導致延遲,這種情況可以多加幾個從庫,分庫分表當然也是一個解法。什么情況下說需要分庫分表呢,就是你主庫更新量太大了,大到MySQL開啟了并行復制都撐不住的時候,可能需要考慮,這個話題比較復雜,大家可以搜一些文章。
直播互動福利:每晚直播間也同樣會送出多份騰訊公仔,更有騰訊徽章、騰訊云代金券等好禮送上!快快預約報名吧!
掃碼關注后回復「加群」提前加入沙龍交流群
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。