成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

讀寫分離水太深,你把握不住,讓叔來——命令查詢權責分離模式

運維 數據庫運維
多年以前,那時我正年輕,做技術如魚得水,甚至一度希望自己能當一輩子的一線程序員。但是我又有兩個小愿望想要達成:一個是想多掙點錢;另一個就是對項目的技術棧和架構選型能多有點主動權。

[[403252]]

多年以前,那時我正年輕,做技術如魚得水,甚至一度希望自己能當一輩子的一線程序員。

但是我又有兩個小愿望想要達成:一個是想多掙點錢;另一個就是對項目的技術棧和架構選型能多有點主動權。

多掙點錢是因為當時我剛結婚不久,有自己的家庭規劃,所以掙錢的欲望也蠻強。

而想有多點技術主動權的原因則是當時領導很賞識我,有些東西逐漸的放權讓我做,我嘗到了甜頭,所以,也有了自己的一些小野心。

而正巧就在那時候,領導給我了一個現在看來職業生涯中還挺重要的機會。

當時,廣告聯盟正是發展的如火如荼的時候,公司也想參與進去分杯羹,于是決定從零開始搞一套廣告平臺。

而我正好也有些類似的開發經驗,且做事還算靠譜,于是,領導便想著讓我去當這套系統的技術負責人。

如果我能把系統做好,對我來說絕對是個證明自己的機會,對以后達成我的兩個小愿望有好處。對我誘惑很大。

只是,老天給你開了一扇門,就總要給你關一扇窗。這個機會不僅僅是我領導看上了,當時,還有另外一個部門的老大也瞄上了。

不得已,上了高層會議討論。討論來討論去的結果就是學習當時別的公司的做法,內部競爭。

兩個部門做各做一套平臺,然后各放到線上運營一陣子,誰做得好誰就能得到公司全力投入的機會。

好吧,機會變成了冒險。只是到此時,我也并不能退縮。一旦我退縮會連累賞識我的領導,而且將來在公司的發展也會嚴重受阻,只能沖了。

為了贏得這場競爭,我和這套系統的產品負責人也溝通了許久。最后定下來了兩個必須實現的目標:

1. 這套系統功能一定要盡量多,尤其是提供給相關業務人員的功能要多。

之所以要這樣,是因為現在是內部競爭。而對于內部競爭,使用我們這套系統的業務人員話語權其實非常大,他們的滿意度很可能是最終評估的勝負手。

同時,我們也計劃為投放在我們這套系統的廣告主們多準備一些體驗度非常好的數據追蹤和分析功能,這樣能最大的增加我們產品的吸引力。

2. 這套系統的穩定性和可靠性要求非常高,有時候哪怕為此做一些過度設計和實現也是值得的。

這里要解釋下穩定性和可靠性在我們當時那個場景里的含義。穩定性就是要保證性能是穩定的,也就是說我們的系統響應時間應該盡全力保證在一個很短的時間內響應。

而可靠性則是我們的系統應該盡全力保證不出錯,因為出錯很可能就會造成用戶流失,導致我們的產品失敗。

定完目標以及產品給完需求后,我就和團隊進入了異常艱苦的開發工作。那時候,我真的是付出了我全身心的心血。

其實,我本來是個享受生活勝過埋頭苦干的人。雖然此前工作也很忙碌,但是空閑日子也是過得很愜意的。聽聽歌,看看電影,有時和老婆找家餐廳享用美食,時不時的也會踢一場酣暢淋漓的足球。

可是,自從開始投入了這套廣告系統的開發以后,悠閑的日子就一去不復返了。

我記得那時候我下班是踉踉蹌蹌的走,上班又是踉踉蹌蹌的來。當時最大的心愿就是有張床,躺下去永遠別有人叫醒我。

可是即使這樣辛苦,我依然遇到了數不清的難題,這些橫亙在開發路上的硬骨頭,導致我的開發目標一再被調整。

其中最麻煩的,就是高并發的性能問題。

當時我的經驗尚淺,Java 說實話周邊的生態也并不完善。能用來承載訪問的也就是緩存和數據庫。同時,由于版權等問題,我還只能選擇 MySQL 數據庫。

為了解決這些性能問題,我還特意把官方的 MySQL 手冊打印了出來,天天鉆研。

開始的時候,為了抗住預想中的超高并發量,我采用的是當時很流行的讀寫分離模式。

但是,實際測試下來,總是有各種不滿意的地方。其中最麻煩的就是各種復雜查詢的性能。

我說過為了獲得內部競爭的勝利,這套系統我們盡可能想去往高并發、多功能這兩個目標上靠。所以,為了這兩個目標,這套系統其實多了很多方便業務人員使用的功能,并且這個功能設想的目標是:

在高并發下,也依然保持穩定和流暢。

其中,最典型的一個業務就是可以實時更新的廣告投放排行功能。

這個廣告投放排行需求是這樣的:

  • 首先,我們的用戶要能在管理后臺看到他們自己的投放廣告排行,排名是根據消費的金額和點擊次數等指標來排次序。
  • 其次,在我們的后臺,也給業務人員也搞了個這么個排名,不同的是它是個全局的,是我們所有客戶投放的廣告的一個總排行。
  • 然后,這個排名要能實時的根據消費金額和點擊次數的變化而變化。當然,這個實時可以搞成準實時,只要別延遲太過也可以。

本身呢,做排行榜由于用的指標比較多,就需要寫很復雜的 SQL 去數據庫中查詢。再加上個需要實時變化,那就得不停的去數據庫中查詢。

而對于這種情況,我無論如何優化總是得不到滿意的結果。如果我緩存這個排行呢,由于這個排行需要各種統計加排序,所以從數據庫中查詢出來后,還需要各種模型轉換,如果并發量上來,查詢再轉換,性能真的掉的飛快。

那時候,我的壓力非常大,腦子一直在想著性能問題,手上的 MySQL 手冊翻得都快爛的掉了頁。就連回到家睡覺時,眼睛閉上腦海里總是想著如何解決這些問題。

最終上線的時間不斷地逼近,手上的項目卻死死卡在這些性能難題上難以進展,競爭對手卻時不時聽到內部競爭對手順利進行到某某程度的消息。

這一切的一切我快扛不住了,內心勸自己放棄的聲音也越來越大。

我曾經一度認為自己是一個韌性非常強的人,但是現在看來,其實也就是個再普通不過的打工仔而已。

我要逃避了,我想去和產品商量就這樣上線吧,我不想管了,是死是活看老天爺吧,賭對方也遇到我這種問題,甚至還不如我。

只是就在我準備拉上產品最終確定就這樣上線的時候,我內心強烈的不甘阻止了我。我想在我放棄之前,無論如何要知道競爭對手怎么樣了,對方有什么方案和思路可供我參考的。

我找遍了我所有公司的熟人,去不停的打探競爭對手的消息。但是,結果并不好,因為對方比我做的更絕,他們進行了封閉式的開發,而且警惕性非常高。

最終,我只得到了一個關鍵詞:CQRS。對方用 CQRS 來解決性能問題!!!

我年少讀書,那時還沒有手機,總是能一心一意的做好讀書這件事,讀書效率極高。但是如今有了手機,現在我再讀書,總是時不時會分心去看看手機里的信息,有時候為了好好把書讀進去,還不得不把手機特意丟在遠處,防止分心。

而 CQRS 就是這種思路。這個模式與其說是一種架構模式還不如說是一種思想。

CQRS 認為一套系統里的操作,總共就分為讀和寫兩大類。如果一套系統不專門把讀和寫專門分開優化,那么系統就像我讀書帶著手機那樣,會一心兩用,從而因為彼此影響,導致各自的性能無法達到最優。

所以,讀寫應該專門的分開,并分別優化。

在 CQRS 里,寫這種行為被稱為命令,而讀行為被稱為查詢。因為想讓他們分開,所以 CQRS 模式中文翻譯過來就被稱為命令查詢權責分離模式。

我知道這套思路之后,本來并不在意,因為乍一看,這套東西其實和我采用的數據庫的讀寫分離是一樣的,就是把讀寫給分開。

但是,我的技術直覺告訴我,這些并沒有那么簡單。

在計算機的世界里,一個名詞不會無緣無故出現,也不會無緣無故的開始流行。如果真的和數據庫的讀寫分離一樣,那直接叫數據庫讀寫分離就好了。一定有什么不一樣了。

我沒再滿足于中文的搜索結果了,我直接去了 Martin Flower 的網站看原始版本去了。然后,我發現了這樣一幅架構圖。

再結合他的原文我一下子明白了,是模型,模型的不同!

原來的數據庫讀寫分離確實把讀寫的這兩個行為分開了,但是它依然有一個重要的事情沒有做,那就是職責的分開。

什么叫職責的分開呢?就是讀寫雙方不要搞同一套模型。而數據庫讀寫分離的問題就在這里,它使用了同一個模型。

使用同一個模型在這里造成的問題是,這個模型由于既要考慮讀取數據不能太困難,也要考慮寫入數據不能太困難。

而這個恰恰就是違背了 CQRS 中的核心思想:讀寫徹底自由。

如果我們使用 CQRS 思想的話,假設寫入不需要關心讀取的問題,讀取數據也不用關心寫入的問題,那么雙方是不是可以徹底放飛自我了?

比如,寫入數據由于不需要考慮讀取,那我大可以使用 Json 格式,使用 XML 格式之類的非標準格式,甚至直接寫個日志都可以。而讀取數據則根本不需要考慮寫入的問題,我甚至可以弄成一個容易搜索的索引格式來。

而 CQRS 在我看來,正是解決卡死我的性能問題的靈丹妙藥。

以廣告排行這個問題為例,廣告排行麻煩就麻煩在,每次加載排行榜需要有很復雜的查詢,去數據庫中讀取數據。

如果能徹底地把排行榜的讀取和排行榜依賴的那些點擊、消費指標的更新分開,那我苦惱的排行榜性能問題就能迎刃而解。

我費勁心思后,仿照 CQRS 的原版思想搞了一個這樣的設計思路:

這里,數據統計就是廣告排名需要的點擊、消費等數據。這些數據會被放到一個單獨的數據庫中,這個數據庫只用來寫入,不考慮讀。

然后,展示廣告排行的功能本身又會單獨從緩存中把廣告排行的模型直接讀取出來展示出去,而不用專門再做什么轉換了。也不存在什么復雜查詢的問題。

但是,我們的需求是要準實時的讓廣告排行根據點擊、消費等數據自動更新,那么如果寫入數據和讀取數據模型分開了,該怎么辦呢?

多年以前,當我第一次在網上買東西的時候,心里有個疑問:我下了個訂單,賣我東西的商家是怎么知道的?莫非要一直盯著?

這個問題到我親自開發電商系統的時候才知道,當我們下單的時候,需要發一個通知給對應的商家,告訴商家哪個客戶購買了哪個商品。

所以,廣告排行自動更新的解決方案有了,和電商下單通知商家的道理一樣。當有數據寫入的時候,我們把寫入的數據復制一份通知給讀取數據的模型就可以了。

好,現在整套邏輯完整了。

但是,我并沒有急于馬上把 CQRS 這套模式去應用到實際的項目當中。因為,我發現我竟然不知道 CQRS 這套模式的缺點是什么。

要知道,世界上還不存在完美的解決方案,全都是既有優點又有缺點的。而 CQRS 我竟然覺得很完美的解決了我的問題,這說明我對這套模式的認知還存在問題。

當時,離約定的上線時間已經越來越近了,差不多還剩一周時間。我真的很想閉眼把方案實施下去。

但是,不行,我這個人做事向來喜歡把事情想得通透,把事物認知的十分清楚后再去做。

我決定冒險花兩天去實現兩個功能點,然后親自體驗一下引入 CQRS 的得與失。

兩天后,我終于發現了問題:引入 CQRS 的模式后,最大的問題在于引入了過度的復雜性。

由于需要讀和寫分開,那么我們開發的工作量無形中被加大了一倍。又引入 CQRS,這變得更復雜了。

因為我們發現,不同的功能,只有使用不同的讀取或者寫入模型才能充分用上 CQRS 的優點。

比如,廣告排行可能使用了緩存中間件去存取現成的排名。根據關鍵字搜索各種合適的廣告,可能就得考慮開源的搜索引擎中間件。每引入一種都會增加開發成本、服務器成本,以及更多的復雜度。

最終,我們的廣告系統按時上線了。

只不過,并沒有廣泛的采用 CQRS 模式,我只是把最重要的功能點用上了 CQRS,其余的有關性能的問題,我決定暫時放下。

之所以這樣,是因為我覺得大部分的問題,其實是我們過度設計引發的。即使因此我失敗了,我也認了。

我并不想為自己親手打造的系統埋下巨大的隱患,更不想給團隊帶來無謂的工作量,我不想卷成這樣。

上線后,我是如此忐忑,尤其是在上線運營的頭兩個月。

我不知道自己的妥協是否會誘發巨大的問題,我也不知道自己的所作所為是不是真的是對的。

兩個系統的競爭在上線兩個月后就有結果了。

這么快的得到結果,恰恰就是因為我的對手廣泛的使用了 CQRS 模式。

他從一開始設計的時候,就想著一鳴驚人,他的系統里引入了七八種中間件。把大量的功能拆分成了讀寫兩部分,而這引發了巨大的災難,過度的復雜性,導致整個系統難以控制。

其中最頭痛的就是,由于引入 CQRS,他們必須通過消息的傳遞去溝通讀寫兩套組件。

但是,當讀取組件收到消息后,卻發現寫入失敗了。導致用戶看到了對應的數據后,過一段時間,卻發現數據和以前看到的對不上了。

比如,點擊次數,開始看到的是 1000 次,結果兩個小時后,發現變成了 999 次了。

這類問題每天都在出現,而他們因為系統太復雜了,查問題、定位問題、解決問題的時間被大大拉長。最后,客戶們紛紛不干了,公司只好把客戶轉到了我這邊的平臺上。

競爭結束了,我勝利了,可是我真的無法高興地起來。因為今天他因為錯誤的引入新技術失敗了,那明天我又何嘗不會因為誤用新技術新思想而失敗呢?今日的他又何嘗不是明日的我?

愿天下程序員凡事深思熟悉,謹言慎行!

本文轉載自微信公眾號「四猿外」,可以通過以下二維碼關注。轉載本文請聯系四猿外公眾號。

 

責任編輯:武曉燕 來源: 四猿外
相關推薦

2021-05-19 10:09:23

消息隊列架構

2022-06-20 14:59:14

讀寫分離模Loki

2019-09-30 09:19:54

Redis分離云數據庫

2018-10-16 16:45:05

數據庫讀寫分離

2017-05-25 10:22:13

NoSQL數據庫主主備份

2023-07-07 08:36:45

配置注解jar

2021-03-26 08:20:51

SpringBoot讀寫分離開發

2022-04-25 08:03:57

MySQL中間件MyCat

2009-05-04 09:13:52

PHPMySQL讀寫分離

2018-01-01 05:23:13

服務化讀寫分離架構

2020-04-23 15:08:41

SpringBootMyCatJava

2017-09-04 09:53:58

MySQLAtlasNavicat

2021-06-25 10:05:58

SpringBootMySQL數據庫

2010-05-17 11:19:44

MySQL proxy

2025-02-26 12:19:52

2024-05-31 13:34:57

2023-02-01 07:34:41

讀寫分離數據庫

2011-08-30 12:49:59

Mysql ProxyLua分離

2021-09-08 10:23:08

讀寫分離Java數據庫

2020-02-28 19:06:21

緩存讀寫Redis
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产一区不卡在线观看 | 亚洲视频中文字幕 | 男人阁久久 | 一区二区三区亚洲 | 国产三级精品三级在线观看四季网 | 日日日日日日bbbbb视频 | 色视频www在线播放国产人成 | www.国产精品 | 久久国产精品免费一区二区三区 | 福利视频网站 | 精品在线免费观看视频 | 91久久久久久久 | 日韩中文字幕网 | 日韩一区三区 | 91视频电影| 久久五月婷 | 国产综合视频 | 婷婷五月色综合香五月 | 国产精品国产三级国产a | 亚洲在线免费观看 | 蜜桃毛片 | 久草网址| 亚洲成人国产综合 | av在线免费观看网址 | 国产精品免费福利 | 精品久久久久国产 | 欧美另类日韩 | 韩日精品在线观看 | 国产精品自拍视频网站 | 欧美在线不卡 | 欧美精品一区久久 | 国产一区亚洲 | 国产精品一区二区三区在线 | 久久久久黄色 | 国产精品99久久久久久www | 国产线视频精品免费观看视频 | 三区在线观看 | 中文区中文字幕免费看 | 国产精品福利网站 | 99精品视频免费观看 | 中文字幕一区二区三区四区五区 |