幾種架構設計模式導論(中)

在上篇文章中,主要說了架構設計模式中的兩種,既:單庫單應用模式、內容分發模式,接下來介紹另外三種架構模式,分別為:查詢分離、微服務、多級緩存

1. 查詢分離

這種主要解決的痛點是單機數據庫壓力過大,從而導致業務緩慢甚至超時,查詢的響應時間變長的問題,也包括需要大量數據庫計算資源的業務查詢請求。這個您可以認為是單庫單應用模式的升級版本,也是絕大多數公司技術架構迭代演進過程中的必由之路。 這種模式的一般設計見下圖:

Paste_Image.png

如上圖所示,這種模式較單庫單應用與內容分發多了幾個部分,一個是業務數據庫進行了主從分離,另一個是引入了ES,為什么要這樣?都解決了哪些問題,下面具體結合業務需求場景進行敘述。

場景一:全文檢索

我想這個業務,大多數應用都會有,如果您使用傳統的數據庫查詢技術,大部分可能都會使用像like這種的SQL語句,高級一一些可能是先分詞,后通過分詞index相關的記錄,弊端是SQL語句的性能與全表掃描機制導致了非常嚴重的性能問題,現在基本上很少見到。

這里的ES(ElasticSearch),是一種查詢引擎,類似的還有Solr等,ES較Solr配置簡單、使用起來更方便,所以這里選用了它。另外,ES這種引擎支持橫向擴展,理論上沒有性能的瓶頸。同時,它還支持各種插件、自定義分詞器等,可擴展性非常強。在這里,使用ES不僅可以完全替代數據庫完成全文檢索功能,還可以實現分頁、排序、分組、分面等功能。具體的,請同學們自行學習。那怎么用呢?一般的流程是這樣的:

  1. 服務端把一條業務數據落庫落表
  2. 服務端異步把該條數據發送到ES
  3. ES把該條記錄按照事先寫入的規則、配置放入自己的索引庫中
  4. 客戶端查詢的時候,由服務端把這個請求先發送到ES,得到數據后,根據需求進行拼裝、組合數據,返回給客戶端

實際中具體怎么用,還請同學們根據實際情況酌情做組合、取舍。

場景二:海量的普通查詢

普通查詢是指我們的業務邏輯中的大部分輔助性的查詢,如:取錢的時候必先查詢一下余額,根據用戶的ID查詢用戶的相關記錄,取得該用戶最新的一條取錢記錄等。我們肯定是要天天要用的,而且用的還非常多。同時呢,我們的寫入請求也是巨多的,導致大量的寫入、查詢操作壓向同一數據庫,然后,數據庫掛了,系統也掛了,領導必然生氣了,你被開除了,還不起房貸了,露宿街頭了,你的老婆跟別人跑了,......

不敢想,所以這個就要求我們必須分散數據庫的壓力,一個業界較成熟的方案就是數據庫的讀寫分離,寫的時候入主庫,讀的時候從從庫讀。這樣就把壓力分散到不同的數據庫中了,如果一個讀庫性能不行,扛不住壓力的話,可以一主多從,橫向擴展。可謂是一劑良藥啊!那怎么使用呢?一個一般的流程是這樣的:

  1. 服務端把一條業務數據落庫
  2. 數據庫同步或異步或半同步把該條數據復制到從庫
  3. 服務端讀數據的時候直接去從庫讀相應的數據

看起來比較簡單吧,一些聰明的、愛思考的、上進的、有老婆的同學可能發現問題了,也包括上面介紹的場景一,就是延遲的問題,如:數據還沒有到從庫,我就馬上讀,那么是讀不到的,會發生問題的。

對于這個問題,各家公司解決的思路不一樣,方法不盡相同。一個普遍的解決方案是:讀不到就讀主庫,當然這么說也是有前提條件的,但具體的方案這里就不一一展開了,我可能會在接下來的分享中詳解各種方案。

另外,關于數據庫的復制模式,還請同學們自行進行學習,太多了太多了,這里說不清。該總結一下這種模式的優缺點的了,如下:

優點:減少數據庫的壓力,理論上可以提供無限高的讀性能,間接提高業務(寫)的性能,專用的查詢、索引、全文(分詞)解決方案。
缺點:數據的延遲,數據一致性的保證較難。

2. 微服務

上面的模式看似不錯,解決了性能問題,我終于可以不用露宿街頭了、老婆還是我的,哈哈。但是

軟件系統天生的復雜性決定了,除了性能,還有其他例如高可用、健壯性等大量問題等待我們解決,再加上各個部門間的撕逼、扯皮,更讓我們碼農雪上加霜,所以

繼續吧......

微服務可以說是最近的熱點,花花綠綠、大大小小、國內國外的公司都在鼓吹,實踐這個模式,可是大部分都沒有弄清楚為什么要這么做,也并不知道這么做有什么好處、壞處,在這里,我將以我自己的親身實踐說一下我對這個模式的看法。隨著業務與人員的增加,遇到了如下的問題:

  1. 單機數據庫寫請求量大量增加,導致數據庫壓力變大
  • 數據庫一旦掛了,那么整個業務都掛了
  • 業務代碼越來越多,都在一個GIT里,越來越難以維護
  • 代碼腐化嚴重、臭味越來越濃
  • 上線越來越頻繁,經常是一個小功能的修改,就要整個大項目要重新編譯
  • 部門越來越多,該哪個部門改動大項目中的哪個東西,撕逼的厲害
  • 其他一些外圍系統直接連接數據庫,導致一旦數據庫結構發生變化,所有的相關系統都要通知,甚至對修改不敏感的系統也要通知
  • 每個應用服務器需要開通所有的權限、網絡、FTP、各種各樣的,因為每個服務器部署的應用都是一樣的
  • 作為架構師,我已經失去了對這個系統的把控......

為了解決上述問題,我司使用了微服務模式,這種模式的一般設計見下圖:

Paste_Image.png

如上圖所示,我把業務進行分塊,做了垂直切分,切成一個個獨立的系統,每個系統各自衍化,有自己的數據庫、緩存、ES等輔助系統,系統之間的實時交互通過RPC,異步交互通過MQ,通過這種組合,共同完成整個系統功能。

那么,這么做是否真的解決上述問題了呢?不玩虛的,一個個來說。對于問題一,由于拆分成了多個子系統,系統上的壓力被分散了,而各個子系統都有自己的數據庫實例,所以數據庫的壓力變小。

對于問題二,一個子系統A的數據庫掛了,只是影響到系統A和使用系統A的那些功能,不會所有的功能不可用,從而解決一個數據庫掛了,導致所有功能不可用的問題。

問題三、四,也因為拆分得到了解決,各個子系統有自己獨立的GIT代碼庫,不會相互影響。通用的模塊可通過庫、服務、平臺的形式解決。

問題五,子系統A發生改變,需要上線,那么我只需要編譯A,然后上線就可以了,不需要其他系統做同樣的事情。

問題六,順應了康威定律,我部門該干什么事、輸出什么,也通過服務的形式暴露出來,我部只管把我部的職責、軟件功能做好就可以。

問題七,所有需要我部數據的需求,都通過接口的形式發布出去,客戶通過接口獲取數據,從而屏蔽了底層數據庫結構,甚至數據來源,我部只需保證我部的接口契約沒有發生變化即可,新的需求增加新的接口,不會影響老的接口。

問題八,不同的子系統需要不同的權限,這個問題也優雅的解決了。

問題九,暫時控制住了復雜性,我只需控制好大的方面,定義好系統邊界、接口、大的流程,然后再分而治之、逐個擊破、合縱連橫。

目前來說,所有問題得到解決!bingo!

但是,這么做還會有許多其他的副作用會隨之產生,如RPC、MQ的超高穩定性、超高性能,網絡間的延遲,數據一致性等問題,這里就不展開來講了,太多了,一本書(厚)都講不完。

另外,對于這個模式來說,最難把握的應該是度,切記不要切分過細,我見過一個功能一個子系統,上百個方法分成上百個子系統的,真的是太過度了。實踐中,一個目前較為可行的方法是:能不分就不分,除非有非常必要的理由!。

優點:相對高性能,可擴展性強,高可用,適合于中等以上規模公司架構。
缺點:復雜、度不好把握。指不僅需要一個能在高層把控大方向、大流程、總體技術的人,還需要針對各個子系統有針對性的開發。把握不好度或者濫用的話,這個模式適得其反!

3.多級緩存

這個模式可以說是應對超高查詢壓力的一種普遍采用的策略,基本的思想就是在所有鏈路的地方,盡能加緩存就加緩存,如下圖所示:

Paste_Image.png

如上圖所示,一般在三個地方加入,一個是客戶端處,一個是API網關處,一個是具體的后端業務處,下面分別介紹。

客戶端處:這個地方加緩存可以說是效果最好的---無延遲。因為不用經過長長的網絡鏈條去后端業務處獲取數據,從而導致加載時間過長,客戶流失等損失。雖然有CDN的支持,但是從客戶端到CDN還是有網絡延遲的,雖然不大。具體的技術依據不同的客戶端而定,對于WEB來講,有瀏覽器本地緩存、Cookie、Storage、緩存策略等技術;對于APP來講,有本地數據庫、本地文件、本地內存、進程內緩存支持。以上提到的各種技術有興趣的同學可以繼續展開來學習。如果客戶端緩存沒有命中,那么就會去后端業務拿數據,一般來講,都會有個API網關,在這里加緩存也是非常有必要的。

API網關處:這個地方加緩存的好處是不用把請求發送到后方,直接在這里就處理了,然后返回給請求者。常見的技術,如http請求,API網關用的基本都是nginx,可以使用nginx本身的緩存模塊,也可以使用Lua+Redis技術定制化。其他的也都大同小異。

后端業務處:這個我想就不用多說了,大家應該差不多都知道,什么Redis,Memcache,Jvm內等等,不熬述了。

實踐中,要結合具體的實際情況,綜合利用各級緩存技術,使得各種請求最大程度的在到達后端業務之前就被解決掉,從而減少后端服務壓力、減少占用帶寬、增強用戶體驗。至于是否只有這三個地方加緩存,我覺得要活學活用,心法比劍法重要!總結一下這個模式的優缺點:

優點:抗住大量讀請求,減少后端壓力。
缺點:數據一致性問題較突出,容易發生雪崩,即:如果客戶端緩存失效、API網關緩存失效,那么所有的大量請求瞬間壓向后端業務系統,后果可想而知。

本次分享的中篇到此結束,接下來的下篇將介紹最后三種模式:分庫分表模式、彈性伸縮模式、多機房模式,相對來講技術含量更高,敬請期待!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容