新聞中心
1.不堪重負(fù)的數(shù)據(jù)庫

公司主營業(yè)務(wù):成都做網(wǎng)站、網(wǎng)站制作、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出高坪免費(fèi)做網(wǎng)站回饋大家。
張大胖公司的數(shù)據(jù)庫已經(jīng)不堪重負(fù)了。
這個(gè)系統(tǒng)最早是兩個(gè)實(shí)習(xí)生寫的, 按照最初的設(shè)計(jì),只是內(nèi)部用戶玩的, 大家可以把一些閑置不用的東西放在上面做交換, 僅此而已,后來為了在互聯(lián)網(wǎng)的大潮中賺點(diǎn)錢,又包裹上了一層Web的外衣, 讓外界也可以訪問。
大家沒有想到互聯(lián)網(wǎng)威力如此巨大, 用戶量會(huì)如此之多, 他們系統(tǒng)使用的Mysql數(shù)據(jù)庫很快就撐不住了。
作為技術(shù)負(fù)責(zé)人的張大胖早已經(jīng)向老大申請了一筆費(fèi)用, 專門買了一個(gè)高性能的服務(wù)器來應(yīng)對, 但是洶涌而來的用戶很快就把高性能給吃得連渣都不剩。
張大胖憂心忡忡: “老大,怎么辦? ”
老大也是技術(shù)出身,反問道: “你分析過為什么數(shù)據(jù)庫壓力這么大嗎? ”
“無非就是讀寫量太大了,尤其是有一些非常復(fù)雜的查詢, 比如最近24小時(shí)最熱門的物品之類,需要寫很復(fù)雜的SQL, 運(yùn)行起來實(shí)在太慢了?!?/p>
“我記得咱們倆聊過讀寫分離啊, 怎么不試一試?”
“老大啊, 你不知道,這實(shí)在是不好弄啊, 為了實(shí)現(xiàn)讀寫分離, 得把數(shù)據(jù)庫拆分成master庫和slave庫, 還比較簡單, 但是我們的系統(tǒng)代碼也得改啊, 寫數(shù)據(jù)的時(shí)候用master 庫, 讀數(shù)據(jù)的時(shí)候用slave庫, 你知道我們這是上個(gè)世紀(jì)開發(fā)的系統(tǒng),典型的遺留代碼, 改動(dòng)起來太麻煩了。”
老大說:“那也得改啊, 你要知道現(xiàn)在這個(gè)系統(tǒng)可是咱們公司***的收入來源了。 你們要是不想改,就退下來,我只好去找李小瘋?cè)プ隽恕?/p>
張大胖向來瞧不起馬屁精李小瘋,技術(shù)不咋地,升的到挺快,一起進(jìn)公司的, 現(xiàn)在已經(jīng)比自己高一級(jí)了。
張大胖趕緊說:“ 別別, 還是我來”
張大胖帶著幾個(gè)弟兄和遺留代碼奮戰(zhàn)了幾個(gè)月, 工作量不亞于一次重寫。 張大胖深深地體會(huì)到,別看現(xiàn)有代碼很爛, 但是經(jīng)過無數(shù)人的修補(bǔ),勉強(qiáng)能工作。 現(xiàn)在自己從頭寫一遍,出的問題更多,很多小細(xì)節(jié)考慮不到,被測出了無數(shù)Bug。
不過好處也是巨大的,這次重寫,理清了業(yè)務(wù), 實(shí)現(xiàn)了讀寫分離,還把緩存也用上了, ***熬了兩天兩夜,新系統(tǒng)終于上線了。
張大胖想著好日子就要開始了,嶄新的代碼, 嶄新的系統(tǒng),應(yīng)該可以撐一段時(shí)間。
2.復(fù)雜的查詢
可是新系統(tǒng)上線了一周后,問題又出現(xiàn)了,這次的問題主要集中在一些復(fù)雜的SQL查詢上,這些SQL查詢最要命的得有幾十行! 嚴(yán)重地拖累了數(shù)據(jù)庫 !
張大胖找來DBA 小梁過來做優(yōu)化,小梁看了半天說: “沒轍, 你們的業(yè)務(wù)太復(fù)雜了, 你看看有這么多表在做Join,怎么可能快呢?”
張大胖說:“這沒辦法啊,數(shù)據(jù)庫就是這么設(shè)計(jì)的啊, 你懂的,無論如何也得滿足***范式吧。 要不這樣,你給我們創(chuàng)建一個(gè)視圖(View) 吧, 把這個(gè)復(fù)雜的查詢給封裝起來, 這樣我們使用起來就簡單了”
“那也是換湯不換藥啊, 實(shí)際的查詢還在, 沒有本質(zhì)的改變, 照樣還是慢。”
“唉,這可怎么辦, 我們有20多個(gè)復(fù)雜查詢,怎么才能提高速度呢?”
小梁說: “你看看這個(gè)超級(jí)復(fù)雜的查詢, 不就是為了獲得過去24小時(shí)的熱門產(chǎn)品嗎,要是有個(gè)表單獨(dú)存放就好了 hot_products(id, name, desc, total_sold) , 這樣以來一條簡單的SQL就搞定”
小梁的話啟發(fā)了張大胖: 實(shí)際上,一套單一的數(shù)據(jù)庫表 對于報(bào)表、搜索、事務(wù)等不同的行為是不適當(dāng)?shù)?!
現(xiàn)在復(fù)雜的數(shù)據(jù)查詢和簡單的數(shù)據(jù)修改利用的就是同一套領(lǐng)域模型和數(shù)據(jù)庫表, 現(xiàn)在的數(shù)據(jù)庫表主要是為了新增、修改數(shù)據(jù)而設(shè)計(jì)的, 對于復(fù)雜的查詢并不友好。 我們能不能單獨(dú)的建一套數(shù)據(jù)庫,專門應(yīng)對查詢呢?
有了這個(gè)專門的查詢庫, 用戶在界面上發(fā)起查詢的時(shí)候處理起來非常簡單, 一條SQL就搞定,甚至都不用通過業(yè)務(wù)領(lǐng)域?qū)?,換句話說數(shù)據(jù)庫模型和展示層是對應(yīng)的! 再也不用像原來那樣從原始數(shù)據(jù)庫表中得到數(shù)據(jù),轉(zhuǎn)化成領(lǐng)域?qū)ο螅?然后再轉(zhuǎn)化成展示層對象, 實(shí)在是太麻煩了 !
但是這個(gè)專門的查詢庫該如何更新呢? 更重要的是能不能忍受數(shù)據(jù)的延遲呢?
3.CQRS
張大胖把自己的想法和苦惱給老大講了下。
老大拍了拍他的肩膀: “看來你小子開竅了啊, 想得挺深入的, 從業(yè)務(wù)上看數(shù)據(jù)的延遲可以忍受,比如過去24小時(shí)的熱門產(chǎn)品,一點(diǎn)點(diǎn)過時(shí)的數(shù)據(jù)對用戶不會(huì)產(chǎn)生重大的影響。只要你能達(dá)到最終一致就可以了?!?/p>
“那我們該怎么更新這個(gè)專門的查詢庫呢?”
“我最近在看一個(gè)叫做CQRS的東西” 老大說 “ 你遇到的這個(gè)問題可以用同樣的思路來解決下”
“什么是CQRS ? ”
"Command Query Responsibility Segregation,就是命令(增刪改)和查詢的責(zé)任分離, 你看看這個(gè)圖"
“這和我剛才的圖差不多啊” 張大胖說
“所以說思路是一致的嘛, 在CQRS中, 強(qiáng)調(diào)的是讀(Query)和寫(Command) 的分離 , 它背后的理念是用戶讀到的數(shù)據(jù)通常是過時(shí)的,比如過去24小時(shí)最火的產(chǎn)品, 既然如此, 為什么還要從數(shù)據(jù)庫中讀取一遍,轉(zhuǎn)化為領(lǐng)域模型,DTO, VO, ***在UI層展示呢? 何不直接一點(diǎn),干脆為‘讀’專門建立一個(gè)直接的數(shù)據(jù)源呢? 這新的數(shù)據(jù)源不一定是關(guān)系數(shù)據(jù)庫,可以是Cache ,可以直接存儲(chǔ)為xml/json數(shù)據(jù), 只要界面查詢起來方便即可。 ”
“是,最早我也是這么想的,那這個(gè)Event是怎么回事?”
“Event 就是事件嘍,例如有人下了一個(gè)訂單, 導(dǎo)致某個(gè)產(chǎn)品已經(jīng)賣出, 這個(gè)時(shí)候就可以發(fā)布一個(gè)產(chǎn)品已經(jīng)賣出(ProductSold)的事件 , 其中包含產(chǎn)品的ID, 價(jià)格,賣出時(shí)間等屬性, 這樣的事件被處理以后,可以變成任意的Read Model,例如過去24小時(shí)最火的產(chǎn)品 ?!?/p>
“奧,原來是這么玩的啊, 通過事件機(jī)制把同步變成異步 ” 張大胖說 “ 還有一個(gè)問題,如果我們用CQRS, 難道我們的應(yīng)用需要把所有的Command 和Query完全分開嗎, 查詢都通過新的數(shù)據(jù)源? 可是很多查詢很簡單,直接使用關(guān)系數(shù)據(jù)庫就夠了啊。 ”
“不,不要把攤子鋪得太大, 引入一種新的技術(shù)也是需要付出代價(jià)的,我們把同步操作變成了異步的操作, 得有良好的事件處理機(jī)制才可以。 所以先用這種思路把你的當(dāng)前問題,也就是復(fù)雜查詢的問題解決掉吧!” 老大***拍了板。
【本文為專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號(hào)coderising獲取授權(quán)】
網(wǎng)站欄目:從讀寫分離到CQRS,張大胖是如何解決性能問題的?
網(wǎng)頁網(wǎng)址:http://www.5511xx.com/article/dpchgho.html


咨詢
建站咨詢
