披荊斬棘,餓了么數(shù)據(jù)庫(kù)高可用架構(gòu)演進(jìn)!
本文將和大家分享餓了么作為高速發(fā)展的互聯(lián)網(wǎng)企業(yè)之一,在發(fā)展歷程中數(shù)據(jù)庫(kù)技術(shù)如何跟隨企業(yè)發(fā)展并不斷滿(mǎn)足業(yè)務(wù)的需求。
分享內(nèi)容大致涉及到以下五點(diǎn):
- 數(shù)據(jù)庫(kù)架構(gòu)怎么滿(mǎn)足業(yè)務(wù)、支撐業(yè)務(wù)發(fā)展
- 怎么提高數(shù)據(jù)庫(kù)的可用性
- 如何對(duì)數(shù)據(jù)流進(jìn)行相應(yīng)的控制和保護(hù)
- 規(guī)模大了以后如何提高數(shù)據(jù)庫(kù)運(yùn)維的效率
- 一些個(gè)人認(rèn)為重要原則的總結(jié)
首先簡(jiǎn)單介紹一下餓了么的概況,點(diǎn)過(guò)外賣(mài)的同學(xué)應(yīng)該都知道餓了么吧?
餓了么發(fā)展最快階段也是最近四五年的事情,我是 2015 年進(jìn)入餓了么的,那時(shí)每天才幾十萬(wàn)的訂單,服務(wù)器也不多。
到了 2016 年時(shí)每天訂單達(dá)到了幾百萬(wàn),商戶(hù)也更多了;而 2017 年不管是訂單、運(yùn)單都是千萬(wàn)以上,直到現(xiàn)在都還在快速增長(zhǎng)。
這么多數(shù)據(jù)的產(chǎn)生對(duì)底層數(shù)據(jù)存儲(chǔ)是非常大的挑戰(zhàn),而且那個(gè)時(shí)候要在非常短的時(shí)間內(nèi)應(yīng)對(duì)業(yè)務(wù)的爆發(fā)性的增長(zhǎng),所以當(dāng)時(shí)底層的技術(shù)挑戰(zhàn)也是非常大的。
數(shù)據(jù)庫(kù)架構(gòu)
垂直拆分
在數(shù)據(jù)庫(kù)架構(gòu)方面餓了么開(kāi)始的時(shí)候也是比較原始的階段,最初是一主多從的架構(gòu);發(fā)展到后面發(fā)現(xiàn)訂單數(shù)據(jù)庫(kù)很難再滿(mǎn)足業(yè)務(wù)往上增長(zhǎng)的需求了。
過(guò)百萬(wàn)之后一主不管幾從都很難滿(mǎn)足業(yè)務(wù)的需求(因?yàn)閷?xiě)太大),這就面臨著需要拆分的情況,需要把熱點(diǎn)業(yè)務(wù)單獨(dú)拆出來(lái),把一套數(shù)據(jù)庫(kù)拆成多套,進(jìn)行垂直的業(yè)務(wù)拆分。
數(shù)據(jù)庫(kù)架構(gòu)-垂直
拆分根據(jù)什么原則呢?又怎么來(lái)預(yù)算訂單庫(kù)現(xiàn)在的架構(gòu)能承載多少的 TPS 和 QPS 呢?
我們當(dāng)時(shí)是結(jié)合訂單量、對(duì)應(yīng)的 QPS、TPS 數(shù)據(jù),再根據(jù)半年后的增長(zhǎng)情況來(lái)推算出每個(gè)業(yè)務(wù)大概會(huì)產(chǎn)生出多少的 QPS、TPS。
然后結(jié)合每套集群能承載的 TPS、QPS 數(shù)量(基于壓測(cè)),就能估算出需要拆分成什么樣的結(jié)構(gòu)、以及拆分后每一套(半年后)大致需要承載多少 TPS、QPS。
當(dāng)時(shí)按業(yè)務(wù)垂直拆分后,這一套方案承載了 200、300 萬(wàn)訂單的規(guī)模,垂直拆分的優(yōu)勢(shì)是代價(jià)小見(jiàn)效快(業(yè)務(wù)代碼改動(dòng)并不大),能快速有效的支撐業(yè)務(wù)。
水平拆分
雖然按垂直架構(gòu)拆分完了,但是熱點(diǎn)的地方依然還是熱點(diǎn),比如說(shuō)訂單隨著下單量的增長(zhǎng)依然會(huì)變成很大的瓶頸。
那如何打破瓶頸呢?我們需要把訂單這個(gè)熱點(diǎn)再單獨(dú)拆分成多套。
數(shù)據(jù)庫(kù)架構(gòu)-水平
也就是行業(yè)里說(shuō)得比較多的“水平拆分”,把原來(lái)的一張訂單表在底層拆成 1000 張小表,放在不同的集群上。
這樣即使這一個(gè)訂單的量再大,也能夠通過(guò)不斷水平擴(kuò)容機(jī)器來(lái)將壓力拆分到更多的集群上,從而滿(mǎn)足了熱點(diǎn)的性能承載。
我們可以通過(guò)壓測(cè)計(jì)算出每套集群能承載出多少 QPS 和 TPS,再結(jié)合現(xiàn)在的業(yè)務(wù)情況就能估算出多少訂單會(huì)對(duì)應(yīng)產(chǎn)生多少的 QPS 和 TPS。
進(jìn)而也能知道拆分成多少套集群能承載多少的業(yè)務(wù)量,所以也就知道了要擴(kuò)多少機(jī)器才能滿(mǎn)足半年或者一年后的業(yè)務(wù)增長(zhǎng)。
如果說(shuō)底層因?yàn)閿U(kuò)容做了分片策略,但是這個(gè)改動(dòng)對(duì)業(yè)務(wù)不是透明的話(huà),那就意味著業(yè)務(wù)需要做很多改造來(lái)適應(yīng)底層的分片邏輯,一般業(yè)務(wù)是很難接受的。
所以,我們的水平拆分為了對(duì)業(yè)務(wù)做到透明,需要做一層代理層(我們叫 DAL),代理層會(huì)幫助業(yè)務(wù)代碼做到對(duì)數(shù)據(jù)庫(kù)底層拆分邏輯的訪(fǎng)問(wèn)透明,業(yè)務(wù)看到的還是一張訂單表,但是底層變了 1000 張表。
完成水平擴(kuò)容后基本上所謂的熱點(diǎn)也不會(huì)存在太大的瓶頸,如果再往上增長(zhǎng)的話(huà)可以繼續(xù)拆小,繼續(xù)添加更多的機(jī)器來(lái)承載。
多活架構(gòu)
垂直拆分之后,我們就沒(méi)有性能瓶頸了嗎?其實(shí)機(jī)房也會(huì)成為我們的瓶頸。一般來(lái)講企業(yè)都是租賃供應(yīng)商的機(jī)房,一個(gè)機(jī)房能進(jìn)多少機(jī)器不是沒(méi)有限制的,供應(yīng)商也不可能給你預(yù)留太多的位置。
當(dāng)你服務(wù)所在的機(jī)房放不進(jìn)去機(jī)器以后,你會(huì)發(fā)現(xiàn)雖然技術(shù)架構(gòu)能滿(mǎn)足水平擴(kuò)容,但是在物理上不能再加機(jī)器了,性能瓶頸依然會(huì)到來(lái)。
為打破單個(gè)機(jī)房面臨的容量瓶頸,我們需要擴(kuò)容到更多的機(jī)房,所以我們做了“多活架構(gòu)”。
數(shù)據(jù)庫(kù)架構(gòu)-多活
在每個(gè)機(jī)房數(shù)據(jù)庫(kù)都是簡(jiǎn)單的主從架構(gòu),下單的時(shí)候北京用戶(hù)可以在頭個(gè)機(jī)房下單,上海用戶(hù)可以在第二個(gè)機(jī)房下單。
這樣的話(huà)下單的高峰壓力會(huì)分散到多個(gè)點(diǎn)去,同一套集群在兩個(gè)機(jī)房都有部署,意味著承載的性能變大了。
這個(gè)時(shí)候就可以在兩個(gè)機(jī)房放機(jī)器,如果一個(gè)機(jī)房的機(jī)器滿(mǎn)了放不下,我們可以把流量引到另一個(gè)機(jī)房,擴(kuò)容另一邊機(jī)房,這樣就打破了單個(gè)機(jī)房對(duì)容量的限制。
我們多活邏輯是根據(jù)用戶(hù)所在的位置決定他在哪個(gè)機(jī)房下單,可能他今天在北京明天在上海,下的單在不同的機(jī)房。
要讓用戶(hù)看到所有的數(shù)據(jù),就必須要讓數(shù)據(jù)雙向流通起來(lái),所以多機(jī)房之間做數(shù)據(jù)的相互流通是數(shù)據(jù)庫(kù)做多活的必備條件。
有很多企業(yè)做的是熱備,只是在一邊下單,但是另一邊是 backup 的狀態(tài),一旦這邊出現(xiàn)問(wèn)題以后再切到那邊,這樣的架構(gòu)并不能解決性能問(wèn)題,而且資源利用率很低(有多少公司出問(wèn)題真敢切?)。
而我們多活的架構(gòu)可以在兩個(gè)機(jī)房同時(shí)下單,能讓性能、資源利用率和可靠性都得到明顯提高。
數(shù)據(jù)庫(kù)架構(gòu)層面從垂直拆分、水平拆分到多活后,基本能滿(mǎn)足絕大多數(shù)企業(yè)的業(yè)務(wù)發(fā)展了,這當(dāng)中我們有兩個(gè)組件發(fā)揮了重要的作用,也一起介紹下。
①DAL
代理層(DAL),最直觀(guān)的需求是能做分庫(kù)分表,能做讀寫(xiě)分離,還可以做資源隔離、連接數(shù)隔離、連接的管理等,更重要的是還能對(duì)數(shù)據(jù)庫(kù)進(jìn)行相應(yīng)的保護(hù)。
外賣(mài)業(yè)務(wù)大多數(shù)人都是在中午下單,所以 11 點(diǎn)左右是餓了么的業(yè)務(wù)高峰。
為了緩解數(shù)據(jù)庫(kù)壓力,我們會(huì)通過(guò) DAL 層做削峰處理,當(dāng)流量過(guò)大時(shí)我們會(huì)讓用戶(hù)消息做排隊(duì)的處理,由此緩解對(duì)數(shù)據(jù)庫(kù)的瞬間沖擊。如果流量特別大的時(shí)候還可以做限流、熔斷等處理。
還有黑白名單機(jī)制,大家了解數(shù)據(jù)庫(kù)運(yùn)維的話(huà)會(huì)知道,如果研發(fā)寫(xiě)的 SQL 有問(wèn)題,放入到數(shù)據(jù)庫(kù)里風(fēng)險(xiǎn)會(huì)比較高。
如果他現(xiàn)在發(fā)了一個(gè)刪除表的 SQL 命令過(guò)來(lái)就有風(fēng)險(xiǎn),我們的 DAL 就會(huì)把這類(lèi)黑名單 SQL 給拒絕。
更高級(jí)一點(diǎn)的功能是多維分表以及全局表 Map Table 功能。有些配置表希望在所有機(jī)房都有,DAL 上就可以做 Global Table 的功能,可以保證在所有節(jié)點(diǎn)上都是同樣的數(shù)據(jù)。
當(dāng)然,DAL 做完這些功能后,對(duì) SQL 也是有一些限制的。比方說(shuō)事務(wù),下單不能跨服務(wù)片去做事務(wù)。
很多傳統(tǒng)的應(yīng)用業(yè)務(wù)邏輯會(huì)把很多東西包在一個(gè)事務(wù)里完成,但互聯(lián)網(wǎng)業(yè)務(wù)應(yīng)該盡量減少這種應(yīng)用,在底層分片后,業(yè)務(wù)事務(wù)并不能完全通過(guò)數(shù)據(jù)庫(kù)里的事務(wù)來(lái)保障。
可能每個(gè)表分片維度不一樣,會(huì)導(dǎo)致數(shù)據(jù)分布到不同的機(jī)器上,這樣就需要跨服務(wù)器事務(wù)一致性的保障,所以業(yè)務(wù)就不能再依賴(lài)于數(shù)據(jù)庫(kù)的事務(wù),需要通過(guò)其他的機(jī)制來(lái)保證。
還有 Order by 、Group by 會(huì)受到限制,如果你查 Top10 的話(huà),DAL 只會(huì)在一個(gè)分片上把 Top10 給到你,但并非是全局的。雖然有這些限制,但是與 DAL 帶來(lái)的好處比是完全可以接受的。
②DRC
數(shù)據(jù)同步組件 DRC,實(shí)現(xiàn)的功能是在一邊機(jī)房接受變更日志,并把變更日志傳遞到其他的機(jī)房去,其他機(jī)房再能把這個(gè)變更應(yīng)用上。
為什么用 DRC 組件而不用 MySQL 原生復(fù)制呢?因?yàn)槲覀兊逆溌肥强鐧C(jī)房跨地域的,上海和北京遠(yuǎn)距離的傳輸下,使用原生復(fù)制的話(huà)缺乏靈活性。
比方 MySQL 會(huì)產(chǎn)生各種各樣的消息,尤其是做維護(hù)操作時(shí)要加字段的話(huà),會(huì)產(chǎn)生大量的變更日志,這時(shí)直接傳遞就會(huì)導(dǎo)致網(wǎng)絡(luò)直接堵死。
在北京和上海的帶寬就 5~10G 的情況下,一個(gè) DDL 變更 100G 的表,會(huì)把帶寬打滿(mǎn),這樣很容易造成大的故障。
而且用DRC還可以做很多事情:
- 比如說(shuō)無(wú)用消息的過(guò)濾,MySQL 平時(shí)會(huì)產(chǎn)生很多通知消息,但我們只需要數(shù)據(jù)變更的消息,就只需要傳遞變更信息。
- 可以做數(shù)據(jù)包的壓縮,還可以做維護(hù)操作的過(guò)濾。維護(hù)操作可以在兩個(gè)機(jī)房同時(shí)進(jìn)行,并且不希望用復(fù)制的方式來(lái)傳遞,這樣的話(huà)避免了在維護(hù)上產(chǎn)生大量的變更消息,導(dǎo)致網(wǎng)絡(luò)阻塞等問(wèn)題。
- 再比如說(shuō)數(shù)據(jù)發(fā)生沖突了該怎么處理?還有怎么避免數(shù)據(jù)的環(huán)路。如果變更日志 A 寫(xiě)在上海機(jī)房,但是 A 變更傳遞到北京機(jī)房后,又會(huì)更新北京機(jī)房的日志,A 又會(huì)通過(guò)北京機(jī)房的變更重新傳回到上海機(jī)房,這樣就是環(huán)路了。
DRC 會(huì)對(duì)相應(yīng)的變更來(lái)源打上標(biāo)簽,這樣數(shù)據(jù)就可以控制不回到自己產(chǎn)生的機(jī)房里。
數(shù)據(jù)庫(kù)的高可用
下一步是怎么提高數(shù)據(jù)庫(kù)的可用性。整個(gè)網(wǎng)站的可用性是由多部分完成的,數(shù)據(jù)庫(kù)只是其中的一塊,所以數(shù)據(jù)庫(kù)可用性要做到比整體可用性更高。
比如做三個(gè)九的網(wǎng)站可用性,那底層需要四個(gè)九,甚至五個(gè)九的可用性來(lái)保證。
架構(gòu)
我們都知道物理上的故障是不可避免的,任何一臺(tái)機(jī)器都有可能出現(xiàn)故障,任何一個(gè)設(shè)備都有可能故障,所以我們需要針對(duì)可能出現(xiàn)故障的地方都有相應(yīng)的高可用方案。
EMHA
一臺(tái) Master 機(jī)器出故障的時(shí)候,我們的 HA 是基于開(kāi)源 MHA 改造的 EMHA。
在每個(gè)機(jī)房里 EMHA 管理每個(gè)機(jī)房 Master 出現(xiàn)故障時(shí)的切換,也不光是只負(fù)責(zé)出故障的切換,還要求控制切換時(shí)間在 30s 左右,同時(shí)要把故障拋給其他需要通知到的地方。
比如代理就要知道這臺(tái) Master 已經(jīng)掛了后新的 Master 是誰(shuí),所以 EMHA 切換時(shí)需要把消息擴(kuò)散出去,讓所有需要信息的組件、環(huán)節(jié)都能接受到信息。
這樣就能達(dá)到主庫(kù)掛的時(shí)候?qū)I(yè)務(wù)的影響非常小(可能業(yè)務(wù)都沒(méi)有感知),DB 切換同時(shí)自動(dòng)完成切組件的對(duì)接,由此來(lái)提高可用性。
多分片方案
如果對(duì)下單業(yè)務(wù)沒(méi)有辦法做到機(jī)器不出故障,但希望出故障時(shí)影響非常小,可以做分片方案。
比如說(shuō)分成了 10 個(gè)片放 10 臺(tái)機(jī)器上,這個(gè)時(shí)候一臺(tái)機(jī)器出故障影響的是 1 個(gè)片,整體只會(huì)影響十分之一的業(yè)務(wù)。
如果你把片分得足夠小的話(huà)影響的范圍會(huì)變得更小,我們對(duì)關(guān)鍵的業(yè)務(wù)會(huì)進(jìn)行更細(xì)的分片,一個(gè)片壞了也只能影響 1/n 的業(yè)務(wù)。
異地多活
異地多活后一個(gè)機(jī)房出問(wèn)題不會(huì)受到多大影響,因?yàn)闄C(jī)房間切換的時(shí)間就在幾分鐘內(nèi)能完成,這就能讓系統(tǒng) Online 的時(shí)間大大提高。
另外,做重要維護(hù)的時(shí)候可以把一個(gè)機(jī)房的流量全切走,在沒(méi)有流量的機(jī)房做相應(yīng)的維護(hù)動(dòng)作,維護(hù)完成之后再把流量切過(guò)來(lái),然后操作另外的機(jī)房,這樣風(fēng)險(xiǎn)特別高的維護(hù)操作也不用做關(guān)站處理。
一般大型一點(diǎn)的網(wǎng)站做一次關(guān)站維護(hù)需要的時(shí)間很長(zhǎng);以上這些點(diǎn)是從架構(gòu)上能把可用性一層一層往上提。
下面我們?cè)倏聪聫墓收习l(fā)現(xiàn)和處理的角度怎么提高可用性。
故障
可用性還有很重要的點(diǎn)——既然故障不可避免,那我們就要追求如何快速地發(fā)現(xiàn)問(wèn)題,解決問(wèn)題。
Trace
全鏈路跟蹤從應(yīng)用(appid)一直下串到 DB,包括有接入層、應(yīng)用層、中間層、服務(wù)層、代理層、緩存層、數(shù)據(jù)庫(kù)層等串聯(lián)起來(lái)。
TraceID 能提供正反向異常互推能力:ID 會(huì)從上往下串,不管你在哪一層發(fā)現(xiàn)的問(wèn)題,拿到 ID 就可以查看鏈路上哪些環(huán)節(jié)有問(wèn)題(哪個(gè)環(huán)節(jié)耗時(shí)最長(zhǎng)或者出異常),這樣就可以及時(shí)地定位問(wèn)題。
如果每個(gè)地方各查各的話(huà),時(shí)間消耗是很長(zhǎng)的,有 Trace 系統(tǒng)后,定位問(wèn)題的效率會(huì)提高很多。
還有在數(shù)據(jù)庫(kù)層面來(lái)看 80%~90% 的問(wèn)題都是 SQL 問(wèn)題,如果能及時(shí)獲取有問(wèn)題 SQL,判斷這個(gè) SQL 的來(lái)源,并對(duì)某些非關(guān)鍵的問(wèn)題 SQL 進(jìn)行限流或者攔截訪(fǎng)問(wèn)的話(huà),就能隔離問(wèn)題 SQL 的影響,減少 DB 故障。
VDBA
我們?cè)跀?shù)據(jù)庫(kù)層開(kāi)發(fā)了一個(gè) VDBA 的自動(dòng)處理程序,它會(huì)不停地對(duì)所有的數(shù)據(jù)庫(kù)進(jìn)行掃描,根據(jù)我們制定的規(guī)則判斷狀態(tài),如果發(fā)現(xiàn)有問(wèn)題的 SlowSQL 會(huì)根據(jù)引起異常的程度進(jìn)行限流、查殺、拒絕等操作。
當(dāng)然 VDBA 能處理的不僅僅是 SlowSQL,還有系統(tǒng)出現(xiàn)堵塞了,有未提交的事務(wù)、復(fù)制中斷、Blocked、binlog 太大了需要清理等都能處理。
很多事情讓 VBDA 自動(dòng)處理后,不僅效率提高了,也大大減少人操作的風(fēng)險(xiǎn)。
在故障處理時(shí)加快故障的定位時(shí)間和故障自動(dòng)處理的機(jī)制后,可用性會(huì)得到明顯的提升。
數(shù)據(jù)流控制
數(shù)據(jù)流控制也依賴(lài)于剛剛所說(shuō)的一些組建。作為數(shù)據(jù)的管理人員,理論上應(yīng)該有自己的手段來(lái)控制什么樣的數(shù)據(jù)能進(jìn)入,什么樣的 SQL 能通過(guò),要以什么樣的方式來(lái)存儲(chǔ)等。
把控不是說(shuō)你寫(xiě)寫(xiě)文檔就能把控住的,需要有相應(yīng)強(qiáng)制的手段和工具。每個(gè)業(yè)務(wù)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)能使用多少連接、帳號(hào)權(quán)限是什么樣的都需要有比較標(biāo)準(zhǔn)的控制,這樣能夠讓所有數(shù)據(jù)在進(jìn)來(lái)的時(shí)候就能夠在 DBA 的掌控當(dāng)中。
數(shù)據(jù)進(jìn)來(lái)以后需要生產(chǎn)落地存儲(chǔ),落地后的數(shù)據(jù)也需要再傳遞到其他地方,這些都需要有相應(yīng)的控制。
比如說(shuō)現(xiàn)在大數(shù)據(jù)要拿數(shù)據(jù),我們就可以通過(guò) DRC 的消息來(lái)推送給大數(shù)據(jù),這樣就不需要再掃描數(shù)據(jù)庫(kù)來(lái)拿數(shù)據(jù)了。
原來(lái)的大數(shù)據(jù)通過(guò) Sqoop 任務(wù)都是隔天隔小時(shí)拉取數(shù)據(jù),但現(xiàn)在可以做到實(shí)時(shí)的數(shù)據(jù)傳遞,做營(yíng)銷(xiāo)活動(dòng)時(shí)可以實(shí)時(shí)看到營(yíng)銷(xiāo)的效果。
數(shù)據(jù)產(chǎn)生后還可能需要對(duì)外提供,如要把生產(chǎn)的數(shù)據(jù)同步到測(cè)試環(huán)境和開(kāi)發(fā)環(huán)境;這個(gè)時(shí)候可以由 DataBus 來(lái)幫你同步數(shù)據(jù),生產(chǎn)數(shù)據(jù)外傳需要做數(shù)據(jù)脫敏和清洗操作(尤其是手機(jī)號(hào)、ID號(hào))。
原來(lái)是比較麻煩的,現(xiàn)在研發(fā)只需要管同步的配置信息就可以了,組件會(huì)自動(dòng)脫敏和清晰,非常方便,也符合安全的規(guī)范。
運(yùn)維提效
重點(diǎn)講一下關(guān)于運(yùn)維提效:在一個(gè)有上千號(hào)研發(fā)人員的公司,如果只有一堆規(guī)范文檔之類(lèi)的來(lái)維護(hù)規(guī)則是很難把控的,因?yàn)槿藛T有離職的、新進(jìn)入的,不可能跟每個(gè)人都去宣傳,所以必須要有平臺(tái)來(lái)管控。
SQL 治理
首先在 SQL 發(fā)布的時(shí)候,我們平臺(tái)上的發(fā)布工具里面會(huì)內(nèi)嵌需要遵循的標(biāo)準(zhǔn),如果表建的時(shí)候不符合標(biāo)準(zhǔn)是沒(méi)法生產(chǎn)提交的,這樣就強(qiáng)制地把規(guī)則和標(biāo)準(zhǔn)變成硬性要求,SQL 還可以自動(dòng)實(shí)現(xiàn)審核也節(jié)省了 DBA 很多時(shí)間。
另外,生產(chǎn)一旦出現(xiàn)變慢的 SQL 后,監(jiān)控系統(tǒng)會(huì)馬上把消息 Push 給研發(fā),如果影響到生產(chǎn)運(yùn)作的話(huà)會(huì)直接拒掉、查殺掉。
比方我們定義超過(guò) 30 秒的 SQL 是不允許線(xiàn)上產(chǎn)生的,這類(lèi) SQL 會(huì)被直接殺掉,這樣可以大大減少生產(chǎn)的風(fēng)險(xiǎn)。
自助發(fā)布
很多公司的 DBA 大部分時(shí)間在審核 SQL 和發(fā)布 SQL,而我們的 SQL 都是研發(fā)自助發(fā)布的,不需要 DBA 操心。
我們平臺(tái)支持原生、PT 執(zhí)行、mm-ost 執(zhí)行(餓了么自行改造的數(shù)據(jù)庫(kù)多機(jī)房同步發(fā)布工具),發(fā)布平臺(tái)會(huì)幫他們計(jì)算好你的發(fā)布大概需要多長(zhǎng)時(shí)間,甚至?xí)o你判斷什么時(shí)候是業(yè)務(wù)低峰(那個(gè)時(shí)候發(fā)布會(huì)比較好),這樣研發(fā)對(duì)自己的發(fā)布也是比較有把控力的。
自助歸檔
歸檔操作也是個(gè)比較頻繁的需求,一旦生產(chǎn)產(chǎn)生大量數(shù)據(jù)后,就需要做冷熱數(shù)據(jù)分離,要把不需要經(jīng)常用的數(shù)據(jù)搬走。
原來(lái)這個(gè)操作是比較費(fèi)勁的,需要 DBA 跟在后面做很多事情,而現(xiàn)在只需要研發(fā)自助解決。
如果你的表超過(guò) 1000 萬(wàn)就需要部署歸檔任務(wù)了,這個(gè)時(shí)候會(huì)推送消息給研發(fā)告訴他你的表已經(jīng)超過(guò)標(biāo)準(zhǔn)了,需要部署歸檔任務(wù),研發(fā)自己就可以在平臺(tái)上把表的歸檔規(guī)則填上去,完成審批后后臺(tái)幫你自動(dòng)地做這件事情了。
還有關(guān)于 DB 的備份和恢復(fù),一旦數(shù)據(jù)庫(kù)部署到生產(chǎn)后,在后臺(tái)的系統(tǒng)里會(huì)幫你自動(dòng)地部署備份、恢復(fù)任務(wù)和自動(dòng)校驗(yàn)可用性,你還可以在平臺(tái)上完成數(shù)據(jù)的回檔,一旦數(shù)據(jù)刷錯(cuò)了、寫(xiě)錯(cuò)了通過(guò)平臺(tái)就能找回。
數(shù)據(jù)保障和遷移
對(duì) DBA 來(lái)講需要把一個(gè)數(shù)據(jù)庫(kù)從這臺(tái)機(jī)器搬到另外的機(jī)器上,需要把一個(gè)大表拆分成多張小表,類(lèi)似的動(dòng)作就需要搬數(shù)據(jù)。
我們做了數(shù)據(jù)搬遷的工具,你只需要做配置就可以了,配置完成之后可以自動(dòng)搬數(shù)據(jù)了,也會(huì)減少 DBA 很多工作量。
云實(shí)踐
現(xiàn)在餓了么所有的開(kāi)發(fā)測(cè)試環(huán)境都是在云上的,效率比自己做環(huán)境高很多,隨時(shí)需要隨時(shí)拿,用完隨時(shí)釋放。
另外還可以做彈性,彈性伸縮比較難,現(xiàn)在我們也沒(méi)有完全實(shí)現(xiàn),但正在朝著這個(gè)方向努力。
我們業(yè)務(wù)的曲線(xiàn)是午高峰和晚高峰,這個(gè)時(shí)候流量很大,彈性調(diào)度需要在業(yè)務(wù)高峰的時(shí)候把機(jī)器加上,在業(yè)務(wù)低峰的時(shí)候把機(jī)器回收回去,提高機(jī)器的利用率。
云機(jī)房后面會(huì)承載我們主要的流量,云機(jī)房的好處是底層管理不需要自己負(fù)責(zé),擴(kuò)容資源比較方便,這樣能提高交付的效率。
在云上的機(jī)房可以灰度引流,剛開(kāi)始可以很少的流量去做,當(dāng)我們覺(jué)得它很穩(wěn)健之后就可以把流量逐步往上遷,這樣能逐步把云平臺(tái)的優(yōu)勢(shì)利用起來(lái),把資源動(dòng)態(tài)伸縮的環(huán)境利用起來(lái),同時(shí)也能控制風(fēng)險(xiǎn)。
所以,現(xiàn)在利用云來(lái)提高運(yùn)維效率是很好的手段。
建議原則
總結(jié)一下,從我們做這些事情里面抽取我個(gè)人感覺(jué)比較重要的點(diǎn)是什么呢?
①最小可用性原則
不管是對(duì)帳號(hào)的處理、連接的處理、SQL 的標(biāo)準(zhǔn)都應(yīng)該有比較嚴(yán)格的限制,不能使用太多的資源,也不應(yīng)該占用太多的資源。
最小可用性原則就是你的連接數(shù)平時(shí)只用 20 個(gè),那我給你 40 個(gè),有一倍波動(dòng)的空間就可以了。還有帳號(hào)權(quán)限只需要增、改、查的權(quán)限,這樣就不會(huì)給你刪除的權(quán)限。
②Design for Failure
這是我們 CTO 經(jīng)常講的,設(shè)計(jì)環(huán)節(jié)不管是在運(yùn)維規(guī)劃還是代碼的環(huán)節(jié)都應(yīng)該考慮接受失敗的情況。
不管是物理層面還是架構(gòu)層面的基礎(chǔ)設(shè)施一定會(huì)出現(xiàn)問(wèn)題,這個(gè)時(shí)候優(yōu)良的架構(gòu)必須要考慮應(yīng)對(duì)錯(cuò)誤情況,確保這類(lèi)波動(dòng)和短暫的問(wèn)題能做到容錯(cuò)和隔離,不至于導(dǎo)致整體的崩潰,同時(shí)具備快速恢復(fù)的能力。
③標(biāo)準(zhǔn)、流程、自動(dòng)(助)、量化
一開(kāi)始應(yīng)該設(shè)定好標(biāo)準(zhǔn),接著把標(biāo)準(zhǔn)拆解成流程,再把流程做成自動(dòng)化、自助化的處理,進(jìn)而達(dá)到維持整體標(biāo)準(zhǔn)的不變形,同時(shí)提高效率的目的,盡可能做到可量化。
比如去年我們維護(hù) 100 個(gè) DB 實(shí)例需要兩個(gè) DBA,今年效率提升后也許一個(gè)就可以了,量化反過(guò)來(lái)也能促進(jìn)運(yùn)維效率的提升(可以知道哪些環(huán)節(jié)最消耗人力和資源,針對(duì)性的優(yōu)化后效率就提高了)。
④灰度、限流、熔斷、隔離
變更是系統(tǒng)穩(wěn)定性的很大變數(shù),想要提高整體的可用性必須對(duì)變更環(huán)節(jié)有苛刻的限制要求。
比方我們要求所有的發(fā)布必須先灰度,灰度完成之后在發(fā)一邊的機(jī)房,然后再全量化,要有快速回退手段;然后程序要求有過(guò)載保護(hù)處理,具備限流、熔斷和隔離等兜底措施。
⑤穩(wěn)定、效率、成本
這三點(diǎn)應(yīng)該是企業(yè)對(duì)技術(shù)部門(mén)的核心訴求,也是有追求的技術(shù)團(tuán)隊(duì)不斷努力的方向。
⑥要方向,更要落地
今天介紹的內(nèi)容經(jīng)歷過(guò)的人都知道每一步都不容易,對(duì)于基礎(chǔ)設(shè)施還很薄弱的公司來(lái)講,最重要的還是考慮自己能夠用得上的,先要有落腳點(diǎn),哪怕從最基礎(chǔ)的問(wèn)題開(kāi)始,把問(wèn)題一項(xiàng)一項(xiàng)解決。
然后再逐步完善,一步步的改變才能真正讓用戶(hù)、公司感覺(jué)到團(tuán)隊(duì)的價(jià)值。所以講了這么多,最重要的還是要落地。
虢國(guó)飛,餓了么數(shù)據(jù)技術(shù)部負(fù)責(zé)人。從事數(shù)據(jù)庫(kù)行業(yè)十余年,專(zhuān)注于 MySQL、PGSQL、MSSQL 等數(shù)據(jù)庫(kù)領(lǐng)域的管理、研究和平臺(tái)的研發(fā)等工作。目前在餓了么主要負(fù)責(zé)數(shù)據(jù)庫(kù)和相關(guān)中間件的管理、開(kāi)發(fā)和維護(hù)工作。