自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

從讀寫分離到CQRS,張大胖是如何解決性能問題的?

開發(fā) 開發(fā)工具
現(xiàn)在復(fù)雜的數(shù)據(jù)查詢和簡單的數(shù)據(jù)修改利用的就是同一套領(lǐng)域模型和數(shù)據(jù)庫表, 現(xiàn)在的數(shù)據(jù)庫表主要是為了新增、修改數(shù)據(jù)而設(shè)計的, 對于復(fù)雜的查詢并不友好。 我們能不能單獨的建一套數(shù)據(jù)庫,專門應(yīng)對查詢呢?

[[201917]]

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

張大胖公司的數(shù)據(jù)庫已經(jīng)不堪重負(fù)了。

這個系統(tǒng)最早是兩個實習(xí)生寫的, 按照最初的設(shè)計,只是內(nèi)部用戶玩的, 大家可以把一些閑置不用的東西放在上面做交換, 僅此而已,后來為了在互聯(lián)網(wǎng)的大潮中賺點錢,又包裹上了一層Web的外衣, 讓外界也可以訪問。

大家沒有想到互聯(lián)網(wǎng)威力如此巨大, 用戶量會如此之多, 他們系統(tǒng)使用的Mysql數(shù)據(jù)庫很快就撐不住了。

作為技術(shù)負(fù)責(zé)人的張大胖早已經(jīng)向老大申請了一筆費用, 專門買了一個高性能的服務(wù)器來應(yīng)對, 但是洶涌而來的用戶很快就把高性能給吃得連渣都不剩。

張大胖憂心忡忡: “老大,怎么辦? ”

老大也是技術(shù)出身,反問道: “你分析過為什么數(shù)據(jù)庫壓力這么大嗎? ”

“無非就是讀寫量太大了,尤其是有一些非常復(fù)雜的查詢, 比如最近24小時最熱門的物品之類,需要寫很復(fù)雜的SQL, 運行起來實在太慢了。”

“我記得咱們倆聊過讀寫分離啊, 怎么不試一試?”

“老大啊, 你不知道,這實在是不好弄啊, 為了實現(xiàn)讀寫分離, 得把數(shù)據(jù)庫拆分成master庫和slave庫, 還比較簡單, 但是我們的系統(tǒng)代碼也得改啊, 寫數(shù)據(jù)的時候用master 庫, 讀數(shù)據(jù)的時候用slave庫, 你知道我們這是上個世紀(jì)開發(fā)的系統(tǒng),典型的遺留代碼, 改動起來太麻煩了。”

老大說:“那也得改啊, 你要知道現(xiàn)在這個系統(tǒng)可是咱們公司***的收入來源了。 你們要是不想改,就退下來,我只好去找李小瘋?cè)プ隽?rdquo;

張大胖向來瞧不起馬屁精李小瘋,技術(shù)不咋地,升的到挺快,一起進(jìn)公司的, 現(xiàn)在已經(jīng)比自己高一級了。

張大胖趕緊說:“ 別別, 還是我來”

張大胖帶著幾個弟兄和遺留代碼奮戰(zhàn)了幾個月, 工作量不亞于一次重寫。 張大胖深深地體會到,別看現(xiàn)有代碼很爛, 但是經(jīng)過無數(shù)人的修補(bǔ),勉強(qiáng)能工作。 現(xiàn)在自己從頭寫一遍,出的問題更多,很多小細(xì)節(jié)考慮不到,被測出了無數(shù)Bug。

不過好處也是巨大的,這次重寫,理清了業(yè)務(wù), 實現(xiàn)了讀寫分離,還把緩存也用上了, ***熬了兩天兩夜,新系統(tǒng)終于上線了。

張大胖想著好日子就要開始了,嶄新的代碼, 嶄新的系統(tǒng),應(yīng)該可以撐一段時間。

2.復(fù)雜的查詢

可是新系統(tǒng)上線了一周后,問題又出現(xiàn)了,這次的問題主要集中在一些復(fù)雜的SQL查詢上,這些SQL查詢最要命的得有幾十行! 嚴(yán)重地拖累了數(shù)據(jù)庫 !

張大胖找來DBA 小梁過來做優(yōu)化,小梁看了半天說: “沒轍, 你們的業(yè)務(wù)太復(fù)雜了, 你看看有這么多表在做Join,怎么可能快呢?”

張大胖說:“這沒辦法啊,數(shù)據(jù)庫就是這么設(shè)計的啊, 你懂的,無論如何也得滿足***范式吧。 要不這樣,你給我們創(chuàng)建一個視圖(View) 吧, 把這個復(fù)雜的查詢給封裝起來, 這樣我們使用起來就簡單了”

“那也是換湯不換藥啊, 實際的查詢還在, 沒有本質(zhì)的改變, 照樣還是慢。”

“唉,這可怎么辦, 我們有20多個復(fù)雜查詢,怎么才能提高速度呢?”

小梁說: “你看看這個超級復(fù)雜的查詢, 不就是為了獲得過去24小時的熱門產(chǎn)品嗎,要是有個表單獨存放就好了 hot_products(id, name, desc, total_sold) , 這樣以來一條簡單的SQL就搞定”

小梁的話啟發(fā)了張大胖: 實際上,一套單一的數(shù)據(jù)庫表 對于報表、搜索、事務(wù)等不同的行為是不適當(dāng)?shù)?!

現(xiàn)在復(fù)雜的數(shù)據(jù)查詢和簡單的數(shù)據(jù)修改利用的就是同一套領(lǐng)域模型和數(shù)據(jù)庫表, 現(xiàn)在的數(shù)據(jù)庫表主要是為了新增、修改數(shù)據(jù)而設(shè)計的, 對于復(fù)雜的查詢并不友好。 我們能不能單獨的建一套數(shù)據(jù)庫,專門應(yīng)對查詢呢?

有了這個專門的查詢庫, 用戶在界面上發(fā)起查詢的時候處理起來非常簡單, 一條SQL就搞定,甚至都不用通過業(yè)務(wù)領(lǐng)域?qū)?,換句話說數(shù)據(jù)庫模型和展示層是對應(yīng)的! 再也不用像原來那樣從原始數(shù)據(jù)庫表中得到數(shù)據(jù),轉(zhuǎn)化成領(lǐng)域?qū)ο螅?然后再轉(zhuǎn)化成展示層對象, 實在是太麻煩了 !

但是這個專門的查詢庫該如何更新呢? 更重要的是能不能忍受數(shù)據(jù)的延遲呢?

3.CQRS

張大胖把自己的想法和苦惱給老大講了下。

老大拍了拍他的肩膀: “看來你小子開竅了啊, 想得挺深入的, 從業(yè)務(wù)上看數(shù)據(jù)的延遲可以忍受,比如過去24小時的熱門產(chǎn)品,一點點過時的數(shù)據(jù)對用戶不會產(chǎn)生重大的影響。只要你能達(dá)到最終一致就可以了。”

“那我們該怎么更新這個專門的查詢庫呢?”

“我最近在看一個叫做CQRS的東西” 老大說 “ 你遇到的這個問題可以用同樣的思路來解決下”

“什么是CQRS ? ”

"Command Query Responsibility Segregation,就是命令(增刪改)和查詢的責(zé)任分離, 你看看這個圖"

“這和我剛才的圖差不多啊” 張大胖說

“所以說思路是一致的嘛, 在CQRS中, 強(qiáng)調(diào)的是讀(Query)和寫(Command) 的分離 , 它背后的理念是用戶讀到的數(shù)據(jù)通常是過時的,比如過去24小時最火的產(chǎn)品, 既然如此, 為什么還要從數(shù)據(jù)庫中讀取一遍,轉(zhuǎn)化為領(lǐng)域模型,DTO, VO, ***在UI層展示呢? 何不直接一點,干脆為‘讀’專門建立一個直接的數(shù)據(jù)源呢? 這新的數(shù)據(jù)源不一定是關(guān)系數(shù)據(jù)庫,可以是Cache ,可以直接存儲為xml/json數(shù)據(jù), 只要界面查詢起來方便即可。 ”

“是,最早我也是這么想的,那這個Event是怎么回事?”

“Event 就是事件嘍,例如有人下了一個訂單, 導(dǎo)致某個產(chǎn)品已經(jīng)賣出, 這個時候就可以發(fā)布一個產(chǎn)品已經(jīng)賣出(ProductSold)的事件 , 其中包含產(chǎn)品的ID, 價格,賣出時間等屬性, 這樣的事件被處理以后,可以變成任意的Read Model,例如過去24小時最火的產(chǎn)品 。”

“奧,原來是這么玩的啊, 通過事件機(jī)制把同步變成異步 ” 張大胖說 “ 還有一個問題,如果我們用CQRS, 難道我們的應(yīng)用需要把所有的Command 和Query完全分開嗎, 查詢都通過新的數(shù)據(jù)源? 可是很多查詢很簡單,直接使用關(guān)系數(shù)據(jù)庫就夠了啊。 ”

“不,不要把攤子鋪得太大, 引入一種新的技術(shù)也是需要付出代價的,我們把同步操作變成了異步的操作, 得有良好的事件處理機(jī)制才可以。 所以先用這種思路把你的當(dāng)前問題,也就是復(fù)雜查詢的問題解決掉吧!” 老大***拍了板。

【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請通過作者微信公眾號coderising獲取授權(quán)】

戳這里,看該作者更多好文

 

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2021-03-08 08:16:42

MySQL分離架構(gòu)

2017-04-27 09:18:37

docker開發(fā)配置

2017-02-23 15:59:53

測試MockSetup

2022-02-22 11:54:05

跨域項目前后端

2021-01-30 19:35:44

HDFS單點Hadoop

2018-10-16 16:45:05

數(shù)據(jù)庫讀寫分離

2018-05-17 09:40:56

區(qū)塊鏈身份識別身份驗證

2012-09-05 11:09:15

SELinux操作系統(tǒng)

2025-04-27 10:14:57

2010-08-13 09:01:39

2023-11-28 08:00:00

SpringJava

2017-10-17 09:21:06

2022-09-07 07:05:25

跨域問題安全架構(gòu)

2024-08-16 21:47:18

2011-11-03 10:45:09

京東性能瓶頸

2022-10-13 14:11:29

瀏覽器域名端口

2010-04-29 17:46:31

Oracle死鎖

2010-07-21 09:33:09

VMware View

2019-11-26 14:30:20

Spring循環(huán)依賴Java

2023-07-18 16:05:00

IP地址
點贊
收藏

51CTO技術(shù)棧公眾號