58怎么玩數(shù)據(jù)庫架構(gòu)

大家好,我是58沈劍验残,今天我分享的主題是《58怎么玩數(shù)據(jù)庫架構(gòu)》捞附,我的PPT頁數(shù)非常少,討論的問題非常的聚焦胚膊。

一故俐、數(shù)據(jù)庫的基本概念

基本概念就一頁P(yáng)PT,讓大家就一些數(shù)據(jù)庫方面的概念達(dá)成一致紊婉。

首先是“單庫”,最開始的時(shí)候數(shù)據(jù)庫都是這么玩的辑舷,幾乎所有公司都會(huì)經(jīng)歷這個(gè)階段喻犁。

接下來是“分片”,也就是水平切分,它是用來解決數(shù)據(jù)量大的問題肢础。有一些數(shù)據(jù)庫支持auto sharding还栓,自動(dòng)分片,例如mongoDB传轰,58同城也用過兩年mongoDB剩盒,后來發(fā)現(xiàn)auto sharding不太可控,不知道什么時(shí)候會(huì)進(jìn)行數(shù)據(jù)遷移慨蛙,數(shù)據(jù)遷移過程中會(huì)有大粒度的鎖辽聊,讀寫被阻塞,業(yè)務(wù)會(huì)有抖動(dòng)和毛刺期贫,這些是業(yè)務(wù)不能接受的跟匆,于是后來又被我們棄用。

一旦進(jìn)行分片通砍,就會(huì)面臨“數(shù)據(jù)路由”的問題玛臂,來了一個(gè)請(qǐng)求,要將請(qǐng)求路由到對(duì)應(yīng)的數(shù)據(jù)庫分片上封孙〖T互聯(lián)網(wǎng)常用的數(shù)據(jù)路由方法有三種:

(1)一個(gè)是按照數(shù)據(jù)范圍路由,比如有兩個(gè)分片虎忌,一個(gè)范圍是0-1億泡徙,一個(gè)范圍是1億-2億,這樣來路由呐籽。

這個(gè)方式的優(yōu)點(diǎn)是非常的簡(jiǎn)單锋勺,并且擴(kuò)展性好,假如兩個(gè)分片不夠了狡蝶,增加一個(gè)2億-3億的分片即可庶橱。

這個(gè)方式的缺點(diǎn)是:雖然數(shù)據(jù)的分布是均衡的,每一個(gè)庫的數(shù)據(jù)量差不多贪惹,但請(qǐng)求的負(fù)載會(huì)不均衡苏章。例如有一些業(yè)務(wù)場(chǎng)景,新注冊(cè)的用戶活躍度更高奏瞬,大范圍的分片請(qǐng)求負(fù)載會(huì)更高枫绅。

(2)二個(gè)是按照hash路由,比如有兩個(gè)分片硼端,數(shù)據(jù)模2尋庫即可并淋。

這個(gè)方式的優(yōu)點(diǎn)是路由方式很簡(jiǎn)單,數(shù)據(jù)分布也是均衡的珍昨,請(qǐng)求負(fù)載也是均衡的县耽。

這個(gè)方式的缺點(diǎn)是如果兩個(gè)分片數(shù)據(jù)量過大句喷,要變成三個(gè)分片,數(shù)據(jù)遷移會(huì)比較麻煩兔毙,即擴(kuò)展性會(huì)受限唾琼。

(3)三個(gè)是路由服務(wù)。前面兩個(gè)數(shù)據(jù)路由方法均有一個(gè)缺點(diǎn)澎剥,業(yè)務(wù)線需要耦合路由規(guī)則锡溯,如果路由規(guī)則發(fā)生變化,業(yè)務(wù)線是需要配合升級(jí)的哑姚。路由服務(wù)可以實(shí)現(xiàn)業(yè)務(wù)線與路由規(guī)則的解耦祭饭,業(yè)務(wù)線每次訪問數(shù)據(jù)庫之前先調(diào)用路由服務(wù),來知道數(shù)據(jù)究竟存放在哪個(gè)分庫上蜻懦。

接下來是“分組”與“復(fù)制”甜癞,這解決的是擴(kuò)展讀性能,保證讀高可用的問題宛乃。

根據(jù)經(jīng)驗(yàn)悠咱,大部分互聯(lián)網(wǎng)的業(yè)務(wù)都是讀多寫少。

淘寶征炼、京東查詢商品析既,搜索商品的請(qǐng)求可能占了99%,只有下單和支付的時(shí)候有寫請(qǐng)求谆奥。

58同城搜索帖子眼坏,察看列表頁,查看詳情頁都是讀請(qǐng)求酸些,發(fā)布帖子是寫請(qǐng)求宰译,寫請(qǐng)求的量也是比較少的。

大部分互聯(lián)網(wǎng)的場(chǎng)景都讀多寫少魄懂,一般來說讀性能會(huì)最先成為瓶頸沿侈,怎么快速解決這個(gè)問題呢?

我們通常使用讀寫分離市栗,擴(kuò)充讀庫的方式來提升系統(tǒng)的讀性能缀拭,同時(shí)多個(gè)讀庫也保證了讀的可用性,一臺(tái)讀庫掛了填帽,另外一臺(tái)讀庫可以持續(xù)的提供服務(wù)蛛淋。

常見數(shù)據(jù)庫軟件架構(gòu)的的玩法綜合了“分片”和“分組”,數(shù)據(jù)量大進(jìn)行分片篡腌,為了提高讀性能褐荷,保證讀的高可用,進(jìn)行了分組嘹悼,80%互聯(lián)網(wǎng)公司數(shù)據(jù)庫都是上圖這種軟件架構(gòu)诚卸。

二葵第、可用性架構(gòu)實(shí)踐

數(shù)據(jù)庫大家都用绘迁,平時(shí)除了根據(jù)業(yè)務(wù)設(shè)計(jì)表結(jié)構(gòu)合溺,根據(jù)訪問來設(shè)計(jì)索引之外,還應(yīng)該在設(shè)計(jì)時(shí)考慮數(shù)據(jù)的可用性缀台,可用性又分為讀的高可用寫的高可用棠赛。

上圖是“讀”高可用的常見玩法,我們是怎么樣保證讀庫的高可用的呢膛腐?解決高可用這個(gè)問題的思路是冗余睛约。

解決站點(diǎn)的可用性問題冗余多個(gè)站點(diǎn),解決服務(wù)的可用性問題冗余多個(gè)服務(wù)哲身,解決數(shù)據(jù)的可用性問題冗余多份數(shù)據(jù)辩涝。

如果用一個(gè)讀庫,保證不了讀高可用勘天,就復(fù)制讀庫怔揩,一個(gè)讀庫掛了另一個(gè)仍然可以提供服務(wù),這么用復(fù)制的方式來保證讀的可用性脯丝。

數(shù)據(jù)的冗余會(huì)引發(fā)一個(gè)副作用商膊,就是一致性的問題

如果是單庫宠进,讀和寫都落在同一個(gè)庫上晕拆,每次讀到的都是最新的數(shù)據(jù)庫,不存在一致性的問題材蹬。

但是為了保證可用性將數(shù)據(jù)復(fù)制到多個(gè)地方实幕,而這多個(gè)地方的數(shù)據(jù)絕對(duì)不是實(shí)時(shí)同步的,會(huì)有同步時(shí)延堤器,所以有可能會(huì)讀到舊的數(shù)據(jù)裳瘪。如何解決主從數(shù)據(jù)庫一致性問題我們?cè)诤竺嬖賮碇v挺举。

很多互聯(lián)網(wǎng)公司的數(shù)據(jù)庫軟件架構(gòu)都是一主兩從或者一主三從,不能夠保證“寫”的高可用,因?yàn)閷懫鋵?shí)還是只有一個(gè)庫叶组,仍是單點(diǎn),如果這個(gè)庫掛了的話泽铛,寫會(huì)受影響缘挽。那小伙伴們?yōu)槭裁催€使用這個(gè)架構(gòu)呢?

我剛才提到大部分互聯(lián)網(wǎng)公司99%的業(yè)務(wù)都是“讀”業(yè)務(wù)员串,寫庫不是主要矛盾勇哗,寫庫掛了,可能只有1%的用戶會(huì)受影響寸齐。

如果要做到“寫”的高可用欲诺,對(duì)數(shù)據(jù)庫軟件架構(gòu)的沖擊比較大抄谐,不一定值得,為了解決1%的問題引入了80%的復(fù)雜度扰法,所以很多互聯(lián)網(wǎng)公司都沒有解決寫數(shù)據(jù)庫的高可用的問題蛹含。

怎么來解決寫的高可用問題呢?思路還是冗余塞颁,讀的高可用是冗余讀庫浦箱,寫的高可用是冗余寫庫。把一個(gè)寫變成兩個(gè)寫祠锣,做一個(gè)雙主同步酷窥,一個(gè)掛了的話,可以將寫的流量自動(dòng)切到另外一個(gè)伴网,寫庫的高可用性蓬推。

用雙主同步的方式保證寫高可用性會(huì)存在什么樣的問題?

剛才提到澡腾,用冗余的方式保證可用性會(huì)存在一致性問題沸伏。因?yàn)閮蓚€(gè)主相互同步,這個(gè)同步是有時(shí)延的蛋铆,很多公司用到auto-increment-id這樣的一些數(shù)據(jù)庫的特性馋评,如果用雙主同步的架構(gòu),一個(gè)主id由10變成11刺啦,在數(shù)據(jù)沒有同步過去之前留特,另一個(gè)主又來了一個(gè)寫請(qǐng)求,也由10變成11玛瘸,雙向同步會(huì)主鍵沖突蜕青,同步失敗,造成數(shù)據(jù)丟失糊渊。

解決這個(gè)雙主同步id沖突的方案有兩種

(1)一個(gè)是雙主使用不同的初始值右核,相同的步長來生成id,一個(gè)庫從0開始(生成02468)渺绒,一個(gè)庫從1開始(生成13579)贺喝,步長都為2,這樣兩邊同步數(shù)據(jù)就不會(huì)沖突宗兼。

(2)另一個(gè)方式是不要使用數(shù)據(jù)庫的auto-increment-id躏鱼,而由業(yè)務(wù)層來保證生成的id不沖突

58同城沒有使用上述兩種方式來保證讀寫的可用性殷绍,我們使用的是“雙主”當(dāng)“主從”的方式來保證數(shù)據(jù)庫的讀寫可用性染苛。

雖然看上去是雙主同步,但是讀寫都在一個(gè)主上主到,另一個(gè)主庫沒有讀寫流量茶行,完全standby躯概。當(dāng)一個(gè)主庫掛掉的時(shí)候,流量會(huì)自動(dòng)的切換到另外一個(gè)主庫上畔师,這一切對(duì)業(yè)務(wù)線都是透明的娶靡,自動(dòng)完成。

58同城的這種方案茉唉,讀寫都在一個(gè)主庫上固蛾,就不存同步延時(shí)而引發(fā)的一致性問題了,但缺點(diǎn)有兩個(gè):

第一是數(shù)據(jù)庫資源利用率只有50%度陆;

第二個(gè)是沒有辦法通過增加讀庫的方式來擴(kuò)展系統(tǒng)的讀性能;

58同城的數(shù)據(jù)庫軟件架構(gòu)如何來擴(kuò)展讀性能呢献幔,我們接著來看下一章懂傀。

三、讀性能架構(gòu)實(shí)踐

如何增加數(shù)據(jù)庫的讀性能蜡感,先看下傳統(tǒng)的玩法:

(1)第一種玩法是增加從庫蹬蚁,通過增加從庫來提升讀性能,缺點(diǎn)是什么呢郑兴?從庫越多犀斋,寫的性能越慢,同步的時(shí)間越長情连,不一致的可能性越高叽粹。

(2)第二種常見的玩法是增加緩存,緩存是大家用的非常多的一種提高系統(tǒng)讀性能的方法却舀,特別是對(duì)于讀多寫少的互聯(lián)網(wǎng)場(chǎng)景非常的有效虫几。常用的緩存玩法如上圖,上游是業(yè)務(wù)線挽拔,下游是讀寫分離主從同步和一個(gè)cache辆脸。

對(duì)于寫操作:會(huì)先淘汰cache,再寫數(shù)據(jù)庫螃诅。

對(duì)于讀操作:先讀cache啡氢,如果cache hit則返回?cái)?shù)據(jù),如果cachemiss則讀從庫术裸,然后把讀出來的數(shù)據(jù)再入緩存倘是。

這是常見的cache玩法。

傳統(tǒng)的cache玩法在一種異常時(shí)序下穗椅,會(huì)引發(fā)嚴(yán)重的一致性問題辨绊,考慮這樣一個(gè)特殊的時(shí)序:

(1)先來了一個(gè)寫請(qǐng)求,淘汰了cache匹表,寫了數(shù)據(jù)庫门坷;

(2)又來了一個(gè)讀請(qǐng)求宣鄙,讀cache,cache miss了默蚌,然后讀從庫冻晤,此時(shí)寫請(qǐng)求還沒有同步到從庫上,于是讀了一個(gè)臟數(shù)據(jù)绸吸,接著臟數(shù)據(jù)入緩存鼻弧;

(3)最后主從同步完成;

這個(gè)時(shí)序會(huì)導(dǎo)致臟數(shù)據(jù)一直在緩存中沒有辦法被淘汰掉锦茁,數(shù)據(jù)庫和緩存中的數(shù)據(jù)嚴(yán)重不一致攘轩。

58同城也是采用緩存的方式來提升讀性能的,那我們會(huì)不會(huì)有數(shù)據(jù)一致性問題呢码俩,接著往下看度帮。

四、一致性架構(gòu)實(shí)踐

58同城采用“服務(wù)+緩存+數(shù)據(jù)庫”一套的方式來保證數(shù)據(jù)的一致性稿存,由于58同城使用“雙主當(dāng)主從用”的數(shù)據(jù)庫讀寫高可用架構(gòu)笨篷,讀寫都在一個(gè)主庫上,不會(huì)讀到所謂“讀庫的臟數(shù)據(jù)”瓣履,所以數(shù)據(jù)庫與緩存的不一致情況也不會(huì)存在率翅。

傳統(tǒng)玩法中,主從不一致的問題有一些什么樣的解決方案呢袖迎?我們一起來看一下冕臭。

主從為什么會(huì)不一致?剛才提到讀寫會(huì)有時(shí)延瓢棒,有可能讀到從庫上的舊數(shù)據(jù)浴韭。常見的方法是引入中間件,業(yè)務(wù)層不直接訪問數(shù)據(jù)庫脯宿,而是通過中間件訪問數(shù)據(jù)庫念颈,這個(gè)中間件會(huì)記錄哪一些key上發(fā)生了寫請(qǐng)求,在數(shù)據(jù)主從同步時(shí)間窗口之內(nèi)连霉,如果key上又出了讀請(qǐng)求榴芳,就將這個(gè)請(qǐng)求也路由到主庫上去(因?yàn)榇藭r(shí)從庫可能還沒有同步完成,是舊數(shù)據(jù))跺撼,使用這個(gè)方法來保證數(shù)據(jù)的一致性窟感。

中間件的方案很理想,那為什么大部分的互聯(lián)網(wǎng)的公司都沒有使用這種方案來保證主從數(shù)據(jù)的一致性呢歉井?那是因?yàn)?b>數(shù)據(jù)庫中間件的技術(shù)門檻比較高柿祈,有一些大公司,例如百度,騰訊躏嚎,阿里他們可能有自己的中間件蜜自,并不是所有的創(chuàng)業(yè)公司互聯(lián)網(wǎng)公司有自己的中間件產(chǎn)品,況且很多互聯(lián)網(wǎng)公司的業(yè)務(wù)對(duì)數(shù)據(jù)一致性的要求并沒有那么高卢佣。比如說同城搜一個(gè)帖子重荠,可能5秒鐘之后才搜出來,對(duì)用戶的體驗(yàn)并沒有多大的影響虚茶。

除了中間件戈鲁,讀寫都路由到主庫,58同城就是這么干的嘹叫,也是一種解決主從不一致的常用方案婆殿。

解決完主從不一致,第二個(gè)要解決的是數(shù)據(jù)庫和緩存的不一致待笑,剛才提到cache傳統(tǒng)的玩法鸣皂,臟數(shù)據(jù)有可能入cache,我們?cè)趺唇鉀Q呢暮蹂?

兩個(gè)實(shí)踐:第一個(gè)是緩存雙淘汰機(jī)制,第二個(gè)是建議為所有item設(shè)定過期時(shí)間(前提是允許cache miss)癌压。

(1)緩存雙淘汰仰泻,傳統(tǒng)的玩法在進(jìn)行寫操作的時(shí)候滩届,先淘汰cache再寫主庫。上文提到棠枉,在主從同步時(shí)間窗口之內(nèi)可能有臟數(shù)據(jù)入cache,此時(shí)如果再發(fā)起一個(gè)異步的淘汰泡挺,即使不一致時(shí)間窗內(nèi)臟數(shù)據(jù)入了cache娄猫,也會(huì)再次淘汰掉贱除。

(2)為所有item設(shè)定超時(shí)時(shí)間,例如10分鐘媳溺。極限時(shí)序下悬蔽,即使有臟數(shù)據(jù)入cache,這個(gè)臟數(shù)據(jù)也最多存在十分鐘录语。帶來的副作用是,可能每十分鐘逗栽,這個(gè)key上有一個(gè)讀請(qǐng)求會(huì)穿透到數(shù)據(jù)庫上彼宠,但我們認(rèn)為這對(duì)數(shù)據(jù)庫的從庫壓力增加是非常小的凭峡。

五决记、擴(kuò)展性架構(gòu)實(shí)踐

擴(kuò)展性也是架構(gòu)師在做數(shù)據(jù)庫架構(gòu)設(shè)計(jì)的時(shí)候需要考慮的一點(diǎn)系宫。我分享一個(gè)58同城非常帥氣的秒級(jí)數(shù)據(jù)擴(kuò)容的方案扩借。這個(gè)方案解決什么問題呢?原來數(shù)據(jù)庫水平切分成N個(gè)庫康谆,現(xiàn)在要擴(kuò)容成2N個(gè)庫嫉到,要解決這個(gè)問題何恶。

假設(shè)原來分成兩個(gè)庫,假設(shè)按照hash的方式分片忱叭,如上圖分為奇數(shù)庫和偶數(shù)庫今艺。

第一個(gè)步驟提升從庫虚缎,底下一個(gè)從庫放到上面來(其實(shí)什么動(dòng)作都沒有做);

第二個(gè)步驟修改配置轴合,此時(shí)擴(kuò)容完成碗短,原來是2個(gè)分片偎谁,修改配置后變成4個(gè)分片巡雨,這個(gè)過程沒有數(shù)據(jù)的遷移铐望。原來偶數(shù)的那一部分現(xiàn)在變成了兩個(gè)部分,一部分是0督弓,一部分是2咽筋,奇數(shù)的部分現(xiàn)在變成1和3。0庫和2庫沒有數(shù)據(jù)沖突虱痕,只是擴(kuò)容之后在短時(shí)間內(nèi)雙主的可用性這個(gè)特性丟失掉了辐赞。

第三個(gè)步驟還要做一些收尾操作:把舊的雙主給解除掉新思,為了保證可用性增加新的雙主同步赘风,原來擁有全部的數(shù)據(jù)邀窃,現(xiàn)在只為一半的數(shù)據(jù)提供服務(wù)了,我們把多余的數(shù)據(jù)刪除掉舵抹,結(jié)尾這三個(gè)步驟可以事后慢慢操作惧蛹。整個(gè)擴(kuò)容在過程在第二步提升從庫刑枝,修改配置其實(shí)就秒級(jí)完成了仅讽,非常的帥氣洁灵。

這個(gè)方案的缺點(diǎn)是只能實(shí)現(xiàn)N庫到2N 庫的擴(kuò)容徽千,2變4、4變8百框,不能實(shí)現(xiàn)2庫變3庫铐维,2庫變5庫的擴(kuò)容嫁蛇,如何能夠?qū)崿F(xiàn)這種擴(kuò)容呢睬棚?

數(shù)據(jù)庫擴(kuò)展性方面有很多的需求抑党,例如剛才說的2庫擴(kuò)3庫撵摆,2庫擴(kuò)5庫台汇。產(chǎn)品經(jīng)理經(jīng)常變化需求,擴(kuò)充表的屬性也是經(jīng)常的事情俐筋,今年的數(shù)據(jù)庫大會(huì)同行也介紹了一些使用觸發(fā)器來做online schema change的方案澄者,但是觸發(fā)器的局限性在于:

第一粱挡、觸發(fā)器對(duì)數(shù)據(jù)庫性能的影響比較大俄精;

第二竖慧、觸發(fā)器只能在同一個(gè)庫上才有效圾旨,而互聯(lián)網(wǎng)的場(chǎng)景特點(diǎn)是數(shù)據(jù)量非常大砍的,并發(fā)量非常大廓鞠,庫都分布在不同的物理機(jī)器上床佳,觸發(fā)器沒法弄夕土。

最后還有一類擴(kuò)展性需求瘟判,底層存儲(chǔ)介質(zhì)發(fā)生變化拷获,原來是mongodb存儲(chǔ)匆瓜,現(xiàn)在要變?yōu)閙ysql存儲(chǔ),這也是擴(kuò)展性需求(雖然很少)萧吠,這三類需求怎么擴(kuò)展纸型?

方法是導(dǎo)庫狰腌,遷移數(shù)據(jù)琼腔,遷移數(shù)據(jù)有幾種做法踱葛,第一種停服務(wù)剖毯,如果大家的業(yè)務(wù)能夠接受這種方法逊谋,強(qiáng)烈建議使用這種方法胶滋,例如有一些游戲公司究恤,晚上一點(diǎn)到兩點(diǎn)服務(wù)器維護(hù),可能就是在干分區(qū)或者合區(qū)這類導(dǎo)庫的事情抄腔。

大家好,我是58沈劍悟耘,今天我分享的主題是《58怎么玩數(shù)據(jù)庫架構(gòu)》暂幼,我的PPT頁數(shù)非常少旺嬉,討論的問題非常的聚焦。一病瞳、數(shù)據(jù)庫的基本概念基本概念就一頁P(yáng)PT套菜,讓大家就一些數(shù)據(jù)庫方面的概念達(dá)成一致逗柴。首先是“單庫”戏溺,最開始的時(shí)候數(shù)據(jù)庫都是這么玩的旷祸,幾乎所有公司都會(huì)經(jīng)歷這個(gè)階段托享。接下來是“分片”闰围,也就是水平切分羡榴,它是用來解決數(shù)據(jù)量大的問題校仑。有一些數(shù)據(jù)庫支持auto sharding肤视,自動(dòng)分片,例如mongoDB愿汰,58同城也用過兩年mongoDB衬廷,后來發(fā)現(xiàn)auto sharding不太可控吗跋,不知道什么時(shí)候會(huì)進(jìn)行數(shù)據(jù)遷移跌宛,數(shù)據(jù)遷移過程中會(huì)有大粒度的鎖疆拘,讀寫被阻塞哎迄,業(yè)務(wù)會(huì)有抖動(dòng)和毛刺漱挚,這些是業(yè)務(wù)不能接受的旨涝,于是后來又被我們棄用颊糜。一旦進(jìn)行分片衬鱼,就會(huì)面臨“數(shù)據(jù)路由”的問題鸟赫,來了一個(gè)請(qǐng)求抛蚤,要將請(qǐng)求路由到對(duì)應(yīng)的數(shù)據(jù)庫分片上岁经∽喝溃互聯(lián)網(wǎng)常用的數(shù)據(jù)路由方法有三種:(1)一個(gè)是按照數(shù)據(jù)范圍路由,比如有兩個(gè)分片蒂胞,一個(gè)范圍是0-1億骗随,一個(gè)范圍是1億-2億鸿染,這樣來路由。這個(gè)方式的優(yōu)點(diǎn)是非常的簡(jiǎn)單丢烘,并且擴(kuò)展性好播瞳,假如兩個(gè)分片不夠了赢乓,增加一個(gè)2億-3億的分片即可牌芋。這個(gè)方式的缺點(diǎn)是:雖然數(shù)據(jù)的分布是均衡的躺屁,每一個(gè)庫的數(shù)據(jù)量差不多犀暑,但請(qǐng)求的負(fù)載會(huì)不均衡耐亏。例如有一些業(yè)務(wù)場(chǎng)景广辰,新注冊(cè)的用戶活躍度更高择吊,大范圍的分片請(qǐng)求負(fù)載會(huì)更高干发。(2)二個(gè)是按照hash路由,比如有兩個(gè)分片必峰,數(shù)據(jù)模2尋庫即可吼蚁。這個(gè)方式的優(yōu)點(diǎn)是路由方式很簡(jiǎn)單肝匆,數(shù)據(jù)分布也是均衡的旗国,請(qǐng)求負(fù)載也是均衡的能曾。這個(gè)方式的缺點(diǎn)是如果兩個(gè)分片數(shù)據(jù)量過大寿冕,要變成三個(gè)分片驼唱,數(shù)據(jù)遷移會(huì)比較麻煩曙蒸,即擴(kuò)展性會(huì)受限纽窟。(3)三個(gè)是路由服務(wù)臂港。前面兩個(gè)數(shù)據(jù)路由方法均有一個(gè)缺點(diǎn)审孽,業(yè)務(wù)線需要耦合路由規(guī)則式散,如果路由規(guī)則發(fā)生變化暴拄,業(yè)務(wù)線是需要配合升級(jí)的乖篷。路由服務(wù)可以實(shí)現(xiàn)業(yè)務(wù)線與路由規(guī)則的解耦,業(yè)務(wù)線每次訪問數(shù)據(jù)庫之前先調(diào)用路由服務(wù)鲸沮,來知道數(shù)據(jù)究竟存放在哪個(gè)分庫上诉探。接下來是“分組”與“復(fù)制”肾胯,這解決的是擴(kuò)展讀性能敬肚,保證讀高可用的問題。根據(jù)經(jīng)驗(yàn)弄慰,大部分互聯(lián)網(wǎng)的業(yè)務(wù)都是讀多寫少陆爽。淘寶扳缕、京東查詢商品慌闭,搜索商品的請(qǐng)求可能占了99%别威,只有下單和支付的時(shí)候有寫請(qǐng)求。58同城搜索帖子驴剔,察看列表頁省古,查看詳情頁都是讀請(qǐng)求,發(fā)布帖子是寫請(qǐng)求豺妓,寫請(qǐng)求的量也是比較少的。大部分互聯(lián)網(wǎng)的場(chǎng)景都讀多寫少布讹,一般來說讀性能會(huì)最先成為瓶頸科侈,怎么快速解決這個(gè)問題呢?我們通常使用讀寫分離炒事,擴(kuò)充讀庫的方式來提升系統(tǒng)的讀性能,同時(shí)多個(gè)讀庫也保證了讀的可用性蔫慧,一臺(tái)讀庫掛了挠乳,另外一臺(tái)讀庫可以持續(xù)的提供服務(wù)。常見數(shù)據(jù)庫軟件架構(gòu)的的玩法綜合了“分片”和“分組”姑躲,數(shù)據(jù)量大進(jìn)行分片睡扬,為了提高讀性能,保證讀的高可用黍析,進(jìn)行了分組卖怜,80%互聯(lián)網(wǎng)公司數(shù)據(jù)庫都是上圖這種軟件架構(gòu)。二阐枣、可用性架構(gòu)實(shí)踐數(shù)據(jù)庫大家都用马靠,平時(shí)除了根據(jù)業(yè)務(wù)設(shè)計(jì)表結(jié)構(gòu),根據(jù)訪問來設(shè)計(jì)索引之外蔼两,還應(yīng)該在設(shè)計(jì)時(shí)考慮數(shù)據(jù)的可用性甩鳄,可用性又分為讀的高可用與寫的高可用。上圖是“讀”高可用的常見玩法额划,我們是怎么樣保證讀庫的高可用的呢妙啃?解決高可用這個(gè)問題的思路是冗余。解決站點(diǎn)的可用性問題冗余多個(gè)站點(diǎn)俊戳,解決服務(wù)的可用性問題冗余多個(gè)服務(wù)揖赴,解決數(shù)據(jù)的可用性問題冗余多份數(shù)據(jù)。如果用一個(gè)讀庫抑胎,保證不了讀高可用燥滑,就復(fù)制讀庫,一個(gè)讀庫掛了另一個(gè)仍然可以提供服務(wù)圆恤,這么用復(fù)制的方式來保證讀的可用性突倍。數(shù)據(jù)的冗余會(huì)引發(fā)一個(gè)副作用腔稀,就是一致性的問題。如果是單庫羽历,讀和寫都落在同一個(gè)庫上焊虏,每次讀到的都是最新的數(shù)據(jù)庫,不存在一致性的問題秕磷。但是為了保證可用性將數(shù)據(jù)復(fù)制到多個(gè)地方诵闭,而這多個(gè)地方的數(shù)據(jù)絕對(duì)不是實(shí)時(shí)同步的,會(huì)有同步時(shí)延澎嚣,所以有可能會(huì)讀到舊的數(shù)據(jù)疏尿。如何解決主從數(shù)據(jù)庫一致性問題我們?cè)诤竺嬖賮碇v。很多互聯(lián)網(wǎng)公司的數(shù)據(jù)庫軟件架構(gòu)都是一主兩從或者一主三從易桃,不能夠保證“寫”的高可用褥琐,因?yàn)閷懫鋵?shí)還是只有一個(gè)庫,仍是單點(diǎn)晤郑,如果這個(gè)庫掛了的話敌呈,寫會(huì)受影響。那小伙伴們?yōu)槭裁催€使用這個(gè)架構(gòu)呢造寝?我剛才提到大部分互聯(lián)網(wǎng)公司99%的業(yè)務(wù)都是“讀”業(yè)務(wù)磕洪,寫庫不是主要矛盾,寫庫掛了诫龙,可能只有1%的用戶會(huì)受影響析显。如果要做到“寫”的高可用,對(duì)數(shù)據(jù)庫軟件架構(gòu)的沖擊比較大签赃,不一定值得谷异,為了解決1%的問題引入了80%的復(fù)雜度,所以很多互聯(lián)網(wǎng)公司都沒有解決寫數(shù)據(jù)庫的高可用的問題锦聊。怎么來解決寫的高可用問題呢晰绎?思路還是冗余,讀的高可用是冗余讀庫括丁,寫的高可用是冗余寫庫荞下。把一個(gè)寫變成兩個(gè)寫哗伯,做一個(gè)雙主同步超升,一個(gè)掛了的話,可以將寫的流量自動(dòng)切到另外一個(gè)聚凹,寫庫的高可用性构资。用雙主同步的方式保證寫高可用性會(huì)存在什么樣的問題抽诉?剛才提到,用冗余的方式保證可用性會(huì)存在一致性問題吐绵。因?yàn)閮蓚€(gè)主相互同步迹淌,這個(gè)同步是有時(shí)延的河绽,很多公司用到auto-increment-id這樣的一些數(shù)據(jù)庫的特性,如果用雙主同步的架構(gòu)唉窃,一個(gè)主id由10變成11耙饰,在數(shù)據(jù)沒有同步過去之前,另一個(gè)主又來了一個(gè)寫請(qǐng)求纹份,也由10變成11苟跪,雙向同步會(huì)主鍵沖突,同步失敗蔓涧,造成數(shù)據(jù)丟失件已。解決這個(gè)雙主同步id沖突的方案有兩種:(1)一個(gè)是雙主使用不同的初始值,相同的步長來生成id元暴,一個(gè)庫從0開始(生成02468)篷扩,一個(gè)庫從1開始(生成13579),步長都為2茉盏,這樣兩邊同步數(shù)據(jù)就不會(huì)沖突瞻惋。(2)另一個(gè)方式是不要使用數(shù)據(jù)庫的auto-increment-id,而由業(yè)務(wù)層來保證生成的id不沖突援岩。58同城沒有使用上述兩種方式來保證讀寫的可用性,我們使用的是“雙主”當(dāng)“主從”的方式來保證數(shù)據(jù)庫的讀寫可用性掏导。雖然看上去是雙主同步享怀,但是讀寫都在一個(gè)主上,另一個(gè)主庫沒有讀寫流量趟咆,完全standby添瓷。當(dāng)一個(gè)主庫掛掉的時(shí)候,流量會(huì)自動(dòng)的切換到另外一個(gè)主庫上值纱,這一切對(duì)業(yè)務(wù)線都是透明的鳞贷,自動(dòng)完成。58同城的這種方案虐唠,讀寫都在一個(gè)主庫上搀愧,就不存同步延時(shí)而引發(fā)的一致性問題了,但缺點(diǎn)有兩個(gè):第一是數(shù)據(jù)庫資源利用率只有50%疆偿;第二個(gè)是沒有辦法通過增加讀庫的方式來擴(kuò)展系統(tǒng)的讀性能咱筛;58同城的數(shù)據(jù)庫軟件架構(gòu)如何來擴(kuò)展讀性能呢,我們接著來看下一章杆故。三迅箩、讀性能架構(gòu)實(shí)踐如何增加數(shù)據(jù)庫的讀性能,先看下傳統(tǒng)的玩法:(1)第一種玩法是增加從庫处铛,通過增加從庫來提升讀性能饲趋,缺點(diǎn)是什么呢拐揭?從庫越多,寫的性能越慢奕塑,同步的時(shí)間越長堂污,不一致的可能性越高。(2)第二種常見的玩法是增加緩存爵川,緩存是大家用的非常多的一種提高系統(tǒng)讀性能的方法敷鸦,特別是對(duì)于讀多寫少的互聯(lián)網(wǎng)場(chǎng)景非常的有效。常用的緩存玩法如上圖寝贡,上游是業(yè)務(wù)線扒披,下游是讀寫分離主從同步和一個(gè)cache。對(duì)于寫操作:會(huì)先淘汰cache圃泡,再寫數(shù)據(jù)庫碟案。對(duì)于讀操作:先讀cache,如果cache hit則返回?cái)?shù)據(jù)颇蜡,如果cachemiss則讀從庫价说,然后把讀出來的數(shù)據(jù)再入緩存。這是常見的cache玩法风秤。傳統(tǒng)的cache玩法在一種異常時(shí)序下鳖目,會(huì)引發(fā)嚴(yán)重的一致性問題,考慮這樣一個(gè)特殊的時(shí)序:(1)先來了一個(gè)寫請(qǐng)求缤弦,淘汰了cache领迈,寫了數(shù)據(jù)庫;(2)又來了一個(gè)讀請(qǐng)求碍沐,讀cache狸捅,cache miss了,然后讀從庫累提,此時(shí)寫請(qǐng)求還沒有同步到從庫上尘喝,于是讀了一個(gè)臟數(shù)據(jù),接著臟數(shù)據(jù)入緩存斋陪;(3)最后主從同步完成朽褪;這個(gè)時(shí)序會(huì)導(dǎo)致臟數(shù)據(jù)一直在緩存中沒有辦法被淘汰掉,數(shù)據(jù)庫和緩存中的數(shù)據(jù)嚴(yán)重不一致无虚。58同城也是采用緩存的方式來提升讀性能的鞍匾,那我們會(huì)不會(huì)有數(shù)據(jù)一致性問題呢,接著往下看骑科。四橡淑、一致性架構(gòu)實(shí)踐58同城采用“服務(wù)+緩存+數(shù)據(jù)庫”一套的方式來保證數(shù)據(jù)的一致性,由于58同城使用“雙主當(dāng)主從用”的數(shù)據(jù)庫讀寫高可用架構(gòu)咆爽,讀寫都在一個(gè)主庫上梁棠,不會(huì)讀到所謂“讀庫的臟數(shù)據(jù)”置森,所以數(shù)據(jù)庫與緩存的不一致情況也不會(huì)存在。傳統(tǒng)玩法中符糊,主從不一致的問題有一些什么樣的解決方案呢凫海?我們一起來看一下。主從為什么會(huì)不一致男娄?剛才提到讀寫會(huì)有時(shí)延行贪,有可能讀到從庫上的舊數(shù)據(jù)。常見的方法是引入中間件模闲,業(yè)務(wù)層不直接訪問數(shù)據(jù)庫建瘫,而是通過中間件訪問數(shù)據(jù)庫,這個(gè)中間件會(huì)記錄哪一些key上發(fā)生了寫請(qǐng)求尸折,在數(shù)據(jù)主從同步時(shí)間窗口之內(nèi)啰脚,如果key上又出了讀請(qǐng)求,就將這個(gè)請(qǐng)求也路由到主庫上去(因?yàn)榇藭r(shí)從庫可能還沒有同步完成实夹,是舊數(shù)據(jù))橄浓,使用這個(gè)方法來保證數(shù)據(jù)的一致性。中間件的方案很理想亮航,那為什么大部分的互聯(lián)網(wǎng)的公司都沒有使用這種方案來保證主從數(shù)據(jù)的一致性呢荸实?那是因?yàn)閿?shù)據(jù)庫中間件的技術(shù)門檻比較高,有一些大公司缴淋,例如百度准给,騰訊,阿里他們可能有自己的中間件宴猾,并不是所有的創(chuàng)業(yè)公司互聯(lián)網(wǎng)公司有自己的中間件產(chǎn)品,況且很多互聯(lián)網(wǎng)公司的業(yè)務(wù)對(duì)數(shù)據(jù)一致性的要求并沒有那么高叼旋。比如說同城搜一個(gè)帖子仇哆,可能5秒鐘之后才搜出來,對(duì)用戶的體驗(yàn)并沒有多大的影響夫植。除了中間件讹剔,讀寫都路由到主庫,58同城就是這么干的详民,也是一種解決主從不一致的常用方案延欠。解決完主從不一致,第二個(gè)要解決的是數(shù)據(jù)庫和緩存的不一致沈跨,剛才提到cache傳統(tǒng)的玩法由捎,臟數(shù)據(jù)有可能入cache,我們?cè)趺唇鉀Q呢饿凛??jī)蓚€(gè)實(shí)踐:第一個(gè)是緩存雙淘汰機(jī)制狞玛,第二個(gè)是建議為所有item設(shè)定過期時(shí)間(前提是允許cache miss)软驰。(1)緩存雙淘汰,傳統(tǒng)的玩法在進(jìn)行寫操作的時(shí)候心肪,先淘汰cache再寫主庫锭亏。上文提到,在主從同步時(shí)間窗口之內(nèi)可能有臟數(shù)據(jù)入cache硬鞍,此時(shí)如果再發(fā)起一個(gè)異步的淘汰慧瘤,即使不一致時(shí)間窗內(nèi)臟數(shù)據(jù)入了cache,也會(huì)再次淘汰掉固该。(2)為所有item設(shè)定超時(shí)時(shí)間锅减,例如10分鐘。極限時(shí)序下蹬音,即使有臟數(shù)據(jù)入cache上煤,這個(gè)臟數(shù)據(jù)也最多存在十分鐘。帶來的副作用是著淆,可能每十分鐘劫狠,這個(gè)key上有一個(gè)讀請(qǐng)求會(huì)穿透到數(shù)據(jù)庫上,但我們認(rèn)為這對(duì)數(shù)據(jù)庫的從庫壓力增加是非常小的永部。五独泞、擴(kuò)展性架構(gòu)實(shí)踐擴(kuò)展性也是架構(gòu)師在做數(shù)據(jù)庫架構(gòu)設(shè)計(jì)的時(shí)候需要考慮的一點(diǎn)。我分享一個(gè)58同城非常帥氣的秒級(jí)數(shù)據(jù)擴(kuò)容的方案苔埋。這個(gè)方案解決什么問題呢懦砂?原來數(shù)據(jù)庫水平切分成N個(gè)庫,現(xiàn)在要擴(kuò)容成2N個(gè)庫组橄,要解決這個(gè)問題荞膘。假設(shè)原來分成兩個(gè)庫,假設(shè)按照hash的方式分片玉工,如上圖分為奇數(shù)庫和偶數(shù)庫羽资。第一個(gè)步驟提升從庫,底下一個(gè)從庫放到上面來(其實(shí)什么動(dòng)作都沒有做)遵班;第二個(gè)步驟修改配置屠升,此時(shí)擴(kuò)容完成,原來是2個(gè)分片狭郑,修改配置后變成4個(gè)分片腹暖,這個(gè)過程沒有數(shù)據(jù)的遷移。原來偶數(shù)的那一部分現(xiàn)在變成了兩個(gè)部分翰萨,一部分是0脏答,一部分是2,奇數(shù)的部分現(xiàn)在變成1和3。0庫和2庫沒有數(shù)據(jù)沖突以蕴,只是擴(kuò)容之后在短時(shí)間內(nèi)雙主的可用性這個(gè)特性丟失掉了糙麦。第三個(gè)步驟還要做一些收尾操作:把舊的雙主給解除掉,為了保證可用性增加新的雙主同步丛肮,原來擁有全部的數(shù)據(jù)赡磅,現(xiàn)在只為一半的數(shù)據(jù)提供服務(wù)了,我們把多余的數(shù)據(jù)刪除掉宝与,結(jié)尾這三個(gè)步驟可以事后慢慢操作焚廊。整個(gè)擴(kuò)容在過程在第二步提升從庫,修改配置其實(shí)就秒級(jí)完成了习劫,非常的帥氣咆瘟。這個(gè)方案的缺點(diǎn)是只能實(shí)現(xiàn)N庫到2N 庫的擴(kuò)容,2變4诽里、4變8袒餐,不能實(shí)現(xiàn)2庫變3庫,2庫變5庫的擴(kuò)容谤狡,如何能夠?qū)崿F(xiàn)這種擴(kuò)容呢灸眼?數(shù)據(jù)庫擴(kuò)展性方面有很多的需求,例如剛才說的2庫擴(kuò)3庫墓懂,2庫擴(kuò)5庫焰宣。產(chǎn)品經(jīng)理經(jīng)常變化需求,擴(kuò)充表的屬性也是經(jīng)常的事情捕仔,今年的數(shù)據(jù)庫大會(huì)同行也介紹了一些使用觸發(fā)器來做online schema change的方案匕积,但是觸發(fā)器的局限性在于:第一、觸發(fā)器對(duì)數(shù)據(jù)庫性能的影響比較大榜跌;第二闪唆、觸發(fā)器只能在同一個(gè)庫上才有效,而互聯(lián)網(wǎng)的場(chǎng)景特點(diǎn)是數(shù)據(jù)量非常大钓葫,并發(fā)量非常大悄蕾,庫都分布在不同的物理機(jī)器上,觸發(fā)器沒法弄瓤逼。最后還有一類擴(kuò)展性需求笼吟,底層存儲(chǔ)介質(zhì)發(fā)生變化库物,原來是mongodb存儲(chǔ)霸旗,現(xiàn)在要變?yōu)閙ysql存儲(chǔ),這也是擴(kuò)展性需求(雖然很少)戚揭,這三類需求怎么擴(kuò)展诱告?方法是導(dǎo)庫,遷移數(shù)據(jù)民晒,遷移數(shù)據(jù)有幾種做法精居,第一種停服務(wù)锄禽,如果大家的業(yè)務(wù)能夠接受這種方法,強(qiáng)烈建議使用這種方法靴姿,例如有一些游戲公司沃但,晚上一點(diǎn)到兩點(diǎn)服務(wù)器維護(hù),可能就是在干分區(qū)或者合區(qū)這類導(dǎo)庫的事情佛吓。如果業(yè)務(wù)上不允許停服務(wù)宵晚,想做到平滑遷移,雙寫法可以解決這類問題维雇。(1)雙寫法遷移數(shù)據(jù)的第一步是升級(jí)服務(wù)淤刃,原來的服務(wù)是寫一個(gè)庫,現(xiàn)在建立新的數(shù)據(jù)庫吱型,雙寫逸贾。比如底層存儲(chǔ)介質(zhì)的變化,我們?cè)瓉硎莔ongo數(shù)據(jù)庫津滞,現(xiàn)在建立好新的mysql數(shù)據(jù)庫铝侵,然后對(duì)服務(wù)的所有寫接口進(jìn)行雙庫寫升級(jí)。(2)第二步寫一個(gè)小程序去進(jìn)行數(shù)據(jù)的遷移据沈。比如寫一個(gè)離線的程序哟沫,把兩個(gè)庫的數(shù)據(jù)重新分片,分到三個(gè)庫里锌介。也可能是把一個(gè)只有三個(gè)屬性的用戶表導(dǎo)到五個(gè)屬性的數(shù)據(jù)表里面嗜诀。這個(gè)數(shù)據(jù)遷移要限速,導(dǎo)完之后兩個(gè)庫的數(shù)據(jù)一致嗎孔祸?只要提前雙寫隆敢,如果沒有什么意外,兩邊的數(shù)據(jù)應(yīng)該是一致的崔慧。什么時(shí)候會(huì)有意外呢拂蝎?在導(dǎo)某一條數(shù)據(jù)的過程當(dāng)中正好發(fā)生了一個(gè)刪除操作,這個(gè)數(shù)據(jù)剛被服務(wù)雙寫刪除惶室,又被遷移數(shù)據(jù)的程序插入到了新庫中温自,這種非常極限的情況下會(huì)造成兩邊的數(shù)據(jù)不一致。(3)建議第三步再開發(fā)一個(gè)小腳本皇钞,對(duì)兩邊的數(shù)據(jù)進(jìn)行比對(duì)悼泌,如果發(fā)現(xiàn)了不一致,就將數(shù)據(jù)修復(fù)夹界。當(dāng)修復(fù)完成之后馆里,我們認(rèn)為數(shù)據(jù)是一致的,再將雙寫又變成單寫,數(shù)據(jù)完成遷移鸠踪。這個(gè)方式的優(yōu)點(diǎn):第一丙者、改動(dòng)是非常小的,對(duì)服務(wù)的影響比較小营密,單寫變雙寫械媒,開發(fā)兩個(gè)小工具,一個(gè)是遷移程序评汰,從一個(gè)庫讀數(shù)據(jù)滥沫,另外一個(gè)庫插進(jìn)去;還有一個(gè)數(shù)據(jù)校驗(yàn)程序键俱,兩個(gè)數(shù)據(jù)進(jìn)行比對(duì)兰绣,改動(dòng)是比較小的。第二编振、隨時(shí)可回滾的缀辩,方案風(fēng)險(xiǎn)比較小,在任何一個(gè)步驟如果發(fā)現(xiàn)問題踪央,可以隨時(shí)停止操作臀玄。比如遷移數(shù)據(jù)的過程當(dāng)中發(fā)現(xiàn)不對(duì),就把新的數(shù)據(jù)庫干掉畅蹂,重新再遷健无。因?yàn)樵谇袚Q之前,所有線上的讀服務(wù)和寫服務(wù)都是舊庫提供液斜,只有切了以后累贤,才是新庫提供的服務(wù)。這是我們非常帥氣的一個(gè)平滑導(dǎo)庫的方式少漆。六臼膏、總結(jié)今天的內(nèi)容就這么多,大概做一個(gè)簡(jiǎn)單的總結(jié):首先介紹了單庫示损、分片渗磅、復(fù)制、分組检访、路由規(guī)則的概念始鱼。分片解決的是數(shù)據(jù)量大的問題,復(fù)制和分組解決的是提高讀性能脆贵,保證讀的可用性的問題医清。分片會(huì)引入路由,常用的三種路由的方法丹禀,按照范圍状勤、按照hash,或者新增服務(wù)來路由双泪。怎么保證數(shù)據(jù)的可用性持搜,保證數(shù)據(jù)可用性的思路是冗余,但會(huì)引發(fā)數(shù)據(jù)的不一致焙矛,58同城保證可用性的實(shí)踐是雙主當(dāng)主從用葫盼,讀寫流量都在一個(gè)庫上,另一個(gè)庫standby村斟,一個(gè)主庫掛掉流量自動(dòng)遷移到另外一個(gè)主庫贫导,只是資源利用率是50%,并且不能通過增加從庫的方式提高讀性蟆盹。讀性能的實(shí)踐孩灯,傳統(tǒng)的玩法是增加從庫或者增加緩存。存在的問題是逾滥,主從可能不一致峰档,同城的玩法是服務(wù)加數(shù)據(jù)庫加緩存一套的方式來解決這些問題。一致性的實(shí)踐寨昙,解決主從不一致性有兩種方法讥巡,一種是增加中間件,中間件記錄哪些key上發(fā)生了寫操作舔哪,在主從同步時(shí)間窗口之內(nèi)的讀操作也路由到主庫欢顷。第二種方法是強(qiáng)制讀主。數(shù)據(jù)庫與緩存的一致性捉蚤,我們的實(shí)踐是雙淘汰抬驴,在發(fā)生寫請(qǐng)求的時(shí)候,淘汰緩存缆巧,寫入數(shù)據(jù)庫怎爵,再做一個(gè)延時(shí)的緩存淘汰操作。第二個(gè)實(shí)踐是建議為所有的item設(shè)置一個(gè)超時(shí)時(shí)間盅蝗。擴(kuò)展性今天分享了58同城一個(gè)非常帥氣的N庫擴(kuò)2N庫的秒級(jí)擴(kuò)容方案鳖链,還分享了一個(gè)平滑雙寫導(dǎo)庫的方案,解決兩庫擴(kuò)三庫墩莫,數(shù)據(jù)庫字段的增加芙委,以及底層介質(zhì)的變化的問題。我今天分享的內(nèi)容就這么多狂秦,謝謝大家灌侣,希望大家有收獲。===【完】===回【趕集】趕集mysql軍規(guī)回【join】30秒懂SQL中的join歡迎大伙留言提問裂问,有問必答侧啼。如果有收獲幫忙隨手轉(zhuǎn)一下哈牛柒。

如果業(yè)務(wù)上不允許停服務(wù),想做到平滑遷移痊乾,雙寫法可以解決這類問題皮壁。

(1)雙寫法遷移數(shù)據(jù)的第一步是升級(jí)服務(wù),原來的服務(wù)是寫一個(gè)庫哪审,現(xiàn)在建立新的數(shù)據(jù)庫蛾魄,雙寫。比如底層存儲(chǔ)介質(zhì)的變化湿滓,我們?cè)瓉硎莔ongo數(shù)據(jù)庫滴须,現(xiàn)在建立好新的mysql數(shù)據(jù)庫,然后對(duì)服務(wù)的所有寫接口進(jìn)行雙庫寫升級(jí)叽奥。

(2)第二步寫一個(gè)小程序去進(jìn)行數(shù)據(jù)的遷移扔水。比如寫一個(gè)離線的程序,把兩個(gè)庫的數(shù)據(jù)重新分片朝氓,分到三個(gè)庫里铭污。也可能是把一個(gè)只有三個(gè)屬性的用戶表導(dǎo)到五個(gè)屬性的數(shù)據(jù)表里面。這個(gè)數(shù)據(jù)遷移要限速膀篮,導(dǎo)完之后兩個(gè)庫的數(shù)據(jù)一致嗎嘹狞?只要提前雙寫,如果沒有什么意外誓竿,兩邊的數(shù)據(jù)應(yīng)該是一致的磅网。

什么時(shí)候會(huì)有意外呢?在導(dǎo)某一條數(shù)據(jù)的過程當(dāng)中正好發(fā)生了一個(gè)刪除操作筷屡,這個(gè)數(shù)據(jù)剛被服務(wù)雙寫刪除涧偷,又被遷移數(shù)據(jù)的程序插入到了新庫中,這種非常極限的情況下會(huì)造成兩邊的數(shù)據(jù)不一致毙死。

(3)建議第三步再開發(fā)一個(gè)小腳本燎潮,對(duì)兩邊的數(shù)據(jù)進(jìn)行比對(duì),如果發(fā)現(xiàn)了不一致扼倘,就將數(shù)據(jù)修復(fù)确封。當(dāng)修復(fù)完成之后,我們認(rèn)為數(shù)據(jù)是一致的再菊,再將雙寫又變成單寫爪喘,數(shù)據(jù)完成遷移。

這個(gè)方式的優(yōu)點(diǎn)

第一纠拔、改動(dòng)是非常小的秉剑,對(duì)服務(wù)的影響比較小,單寫變雙寫稠诲,開發(fā)兩個(gè)小工具侦鹏,一個(gè)是遷移程序诡曙,從一個(gè)庫讀數(shù)據(jù),另外一個(gè)庫插進(jìn)去略水;還有一個(gè)數(shù)據(jù)校驗(yàn)程序价卤,兩個(gè)數(shù)據(jù)進(jìn)行比對(duì),改動(dòng)是比較小的聚请。

第二、隨時(shí)可回滾的稳其,方案風(fēng)險(xiǎn)比較小驶赏,在任何一個(gè)步驟如果發(fā)現(xiàn)問題,可以隨時(shí)停止操作既鞠。比如遷移數(shù)據(jù)的過程當(dāng)中發(fā)現(xiàn)不對(duì)煤傍,就把新的數(shù)據(jù)庫干掉,重新再遷嘱蛋。因?yàn)樵谇袚Q之前蚯姆,所有線上的讀服務(wù)和寫服務(wù)都是舊庫提供,只有切了以后洒敏,才是新庫提供的服務(wù)龄恋。這是我們非常帥氣的一個(gè)平滑導(dǎo)庫的方式。

六凶伙、總結(jié)

今天的內(nèi)容就這么多郭毕,大概做一個(gè)簡(jiǎn)單的總結(jié):

首先介紹了單庫、分片函荣、復(fù)制显押、分組、路由規(guī)則的概念傻挂。分片解決的是數(shù)據(jù)量大的問題乘碑,復(fù)制和分組解決的是提高讀性能,保證讀的可用性的問題金拒。分片會(huì)引入路由兽肤,常用的三種路由的方法,按照范圍绪抛、按照hash轿衔,或者新增服務(wù)來路由。

怎么保證數(shù)據(jù)的可用性睦疫,保證數(shù)據(jù)可用性的思路是冗余害驹,但會(huì)引發(fā)數(shù)據(jù)的不一致,58同城保證可用性的實(shí)踐是雙主當(dāng)主從用蛤育,讀寫流量都在一個(gè)庫上宛官,另一個(gè)庫standby葫松,一個(gè)主庫掛掉流量自動(dòng)遷移到另外一個(gè)主庫,只是資源利用率是50%底洗,并且不能通過增加從庫的方式提高讀性腋么。

讀性能的實(shí)踐,傳統(tǒng)的玩法是增加從庫或者增加緩存亥揖。存在的問題是珊擂,主從可能不一致,同城的玩法是服務(wù)加數(shù)據(jù)庫加緩存一套的方式來解決這些問題费变。

一致性的實(shí)踐摧扇,解決主從不一致性有兩種方法,一種是增加中間件挚歧,中間件記錄哪些key上發(fā)生了寫操作扛稽,在主從同步時(shí)間窗口之內(nèi)的讀操作也路由到主庫。第二種方法是強(qiáng)制讀主滑负。數(shù)據(jù)庫與緩存的一致性在张,我們的實(shí)踐是雙淘汰,在發(fā)生寫請(qǐng)求的時(shí)候矮慕,淘汰緩存帮匾,寫入數(shù)據(jù)庫,再做一個(gè)延時(shí)的緩存淘汰操作痴鳄。第二個(gè)實(shí)踐是建議為所有的item設(shè)置一個(gè)超時(shí)時(shí)間辟狈。

擴(kuò)展性今天分享了58同城一個(gè)非常帥氣的N庫擴(kuò)2N庫的秒級(jí)擴(kuò)容方案,還分享了一個(gè)平滑雙寫導(dǎo)庫的方案夏跷,解決兩庫擴(kuò)三庫哼转,數(shù)據(jù)庫字段的增加,以及底層介質(zhì)的變化的問題槽华。

我今天分享的內(nèi)容就這么多壹蔓,謝謝大家,希望大家有收獲猫态。

===【完】===

回【趕集】趕集mysql軍規(guī)

回【join】30秒懂SQL中的join

歡迎大伙留言提問佣蓉,有問必答。

如果有收獲幫忙隨手轉(zhuǎn)一下哈亲雪。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末勇凭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子义辕,更是在濱河造成了極大的恐慌虾标,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灌砖,死亡現(xiàn)場(chǎng)離奇詭異璧函,居然都是意外死亡傀蚌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門蘸吓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來善炫,“玉大人,你說我怎么就攤上這事库继÷嵋眨” “怎么了就缆?”我有些...
    開封第一講書人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵清钥,是天一觀的道長。 經(jīng)常有香客問我寨蹋,道長雨膨,這世上最難降的妖魔是什么擂涛? 我笑而不...
    開封第一講書人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任读串,我火速辦了婚禮聊记,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恢暖。我一直安慰自己排监,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開白布杰捂。 她就那樣靜靜地躺著舆床,像睡著了一般。 火紅的嫁衣襯著肌膚如雪嫁佳。 梳的紋絲不亂的頭發(fā)上挨队,一...
    開封第一講書人閱讀 49,749評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音蒿往,去河邊找鬼盛垦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瓤漏,可吹牛的內(nèi)容都是我干的腾夯。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼蔬充,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蝶俱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起饥漫,我...
    開封第一講書人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤榨呆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后庸队,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體愕提,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馒稍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浅侨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纽谒。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖如输,靈堂內(nèi)的尸體忽然破棺而出鼓黔,到底是詐尸還是另有隱情,我是刑警寧澤不见,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布澳化,位于F島的核電站,受9級(jí)特大地震影響稳吮,放射性物質(zhì)發(fā)生泄漏缎谷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一灶似、第九天 我趴在偏房一處隱蔽的房頂上張望列林。 院中可真熱鬧,春花似錦酪惭、人聲如沸希痴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽砌创。三九已至,卻和暖如春鲫懒,著一層夾襖步出監(jiān)牢的瞬間嫩实,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來泰國打工窥岩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留甲献,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓谦秧,卻偏偏與公主長得像竟纳,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疚鲤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容