圖解分散式系統架構演進之路

来源:https://www.cnblogs.com/aishangJava/archive/2018/12/12/10105796.html
-Advertisement-
Play Games

0、介紹 本篇文章是在我看完《從零開始學架構》之後,以架構演變為主線,梳理了一下演變過程中出現的問題以及解決方案,文章中引用了這本書的一些內容和圖片 分散式和集群的概念經常被搞混,現在一句話讓你明白兩者的區別。 分散式:一個業務拆分成多個子業務,部署在不同的伺服器上集群:同一個業務,部署在多個伺服器 ...


0、介紹

本篇文章是在我看完《從零開始學架構》之後,以架構演變為主線,梳理了一下演變過程中出現的問題以及解決方案,文章中引用了這本書的一些內容和圖片

分散式和集群的概念經常被搞混,現在一句話讓你明白兩者的區別。

分散式:一個業務拆分成多個子業務,部署在不同的伺服器上
集群:同一個業務,部署在多個伺服器上

例如:電商系統可以拆分成商品,訂單,用戶等子系統。這就是分散式,而為了應對併發,同時部署好幾個用戶系統,這就是集群

1、單應用架構

2、應用伺服器和數據伺服器分離

單機負載越來越來,所以要將應用伺服器和資料庫伺服器分離

 

 

3、應用伺服器做集群

每個系統的處理能力是有限的,為了提高併發訪問量,需要對應用伺服器做集群

 

這時會涉及到兩個問題:

  1. 負載均衡

  2. session共用

負載均衡就是將請求均衡地分配到多個系統上,常見的技術有如下幾種

DNS

DNS是最簡單也是最常見的負載均衡方式,一般用來實現地理級別的均衡。例如,北方的用戶訪問北京的機房,南方的用戶訪問廣州的機房。一般不會使用DNS來做機器級別的負載均衡,因為太耗費IP資源了。例如,百度搜索可能要10000台以上的機器,不可能將這麼多機器全部配置公網IP,然後用DNS來做負載均衡。

Nginx&LVS&F5

DNS是用於實現地理級別的負載均衡,而Nginx&LVS&F5用於同一地點內機器級別的負載均衡。其中Nginx是軟體的7層負載均衡,LVS是內核的4層負載均衡,F5是硬體做4層負載均衡,性能從低到高位Nginx<LVS<F5

下圖形象的展示了一個實際請求過程中,地理級別的負載均衡和機器級別的負載均衡是如何分工和結合的,其中粗線是地理級別的負載均衡,細線是機器級別的負載均衡,實線代表最終的路由路徑

session共用

session共用就是用戶在A伺服器登錄,結果查看購物車時,請求發送到了B伺服器,因此用戶的session存在A伺服器上,所以當請求發送到B伺服器上時,會認為用戶沒有登錄

目前解決session跨域共用問題有如下幾種方式

  1. session sticky

    將請求都落到同一個伺服器上,如Nginx的url hash

  2. session replication

    session複製,每台伺服器都保存一份相同的session

  3. session 集中存儲

    存儲在db、 存儲在緩存伺服器 (redis)

  4. cookie (主流)

    將信息存在加密後的cookie中

4、資料庫讀寫分離

搭建資料庫主從集群,實現資料庫讀寫分離,改善資料庫負載壓力

資料庫讀寫分離的基本實現如下

  1. 資料庫伺服器搭建主從集群,一主一從,一主多從都可以

  2. 資料庫主機負責讀寫操作,從機只負責讀操作

  3. 資料庫主機通過複製將數據同步到從機,每台資料庫伺服器都存儲了所有的業務數據

  4. 業務伺服器將寫操作分給資料庫主機,將讀操作分給資料庫從機

實現方式

讀寫分離需要將讀/寫操作區分開來,然後訪問不同的資料庫伺服器;分庫分表需要根據不同的數據訪問不同的資料庫伺服器,兩者本質上都是一種分配機制,即將不同的SQL語句發送到不同的資料庫伺服器。

讀寫分離,包括後面要提到的分庫分表的實現方式有兩種:

  1. 程式代碼封裝

  2. 中間件封裝

程式代碼封裝指在代碼中抽象一個數據訪問層來實現讀寫分離,分庫分表

中間件封裝指的是獨立一套系統出來,實現讀寫分離和分庫分表操作,如我們熟悉的MySQL Router和Mycat等

 5、引入搜索引擎來查詢

傳統的關係型資料庫通過索引來達到快速查詢的目的,但是在全文搜索的業務場景下,索引也無能為力,主要體現在如下幾點:

  1. 全文搜索的條件可以隨意排列組合,如果通過索引來滿足,則索引的數量會非常多

  2. 全文搜索的模糊匹配方式,索引無法滿足,只能用like查詢,而like查詢是整表掃描,效率非常低

目前主要有Elasticsearch與Solr。Solr 是傳統搜索應用的有力解決方案,但 Elasticsearch 更適用於新興的實時搜索應用。

6、增加緩存

為了應對流量持續增加,必須增加緩存

常見的方式有如下幾種:

Redis與Memcached

以我們常見的Mybatis為例,很容易和Redis與Memcached整合起來,緩存已經查詢過的SQL,因為Mybatis知道自己不擅長緩存,所以提供了介面讓這些緩存工具進行整合

CDN

CDN是為瞭解決用戶網路訪問時的“最後一公裡”效應,本質上是一種“以空間換空間”的加速策略,即將內容緩存在離用戶最近的地方,用戶訪問的是緩存的內容,而不是站點實時的內容。

7、分庫分表

讀寫分離分散了資料庫讀寫操作的壓力,但沒有分散存儲壓力,當數據量達到千萬甚至上億條的時候,單台伺服器的存儲能力會成為系統的瓶頸。常見的分散存儲的方法有分庫和分表兩大類

 

業務分庫

業務分庫指的是按照業務模塊將數據分散到不同的資料庫伺服器。例如,一個簡單的電商網站,包括商品,訂單,用戶三個業務模塊,我們可以將商品數據,訂單數據,用戶數據,分開放到3台不同的資料庫伺服器上,而不是將所有數據都放在一臺資料庫伺服器上

當然業務分庫也會帶來新的問題:

  1. join操作問題:業務分庫後,原本在同一個資料庫中的表分散到不同資料庫中,導致無法使用SQL的join查詢

  2. 事務問題:原本在同一個資料庫中不同的表可以在同一個事務中修改,業務分庫後,表分散到不同資料庫中,無法通過事務統一修改

  3. 成本問題:業務分庫同時也帶來了成本的代價,本來1台伺服器搞定的事情,現在要3台,如果考慮備份,那就是2台變成6台

分表

表單數據拆分有兩種方式,垂直分表水平分表

垂直分表:垂直分表適合將表中某些不常用且占了大量空間的列拆分出去。如上圖的nickname和description欄位不常用,就可以將這個欄位獨立到另外一張表中,這樣在查詢name時,就能帶來一定的性能提升

水平分表:水平分表適合表行數特別大的表,如果單表行數超過5000萬就必須進行分表,這個數字可以作為參考,但並不是絕對標準,關鍵還是要看表的訪問性能

水平分表後,某條數據具體屬於哪個切分後的子表,需要增加路由演算法進行計算,常見的路由演算法

範圍路由:選取有序的數據列(例如,整型,時間戳等)作為路由條件,不同分段分散到不同的資料庫表中。以最常見的用戶ID為例,路由演算法可以按照1000000的範圍大小進行分段,1-999999放到資料庫1的表中,1000000-1999999放到資料庫2的表中,以此類推

Hash路由:選取某個列(或者某幾個列組合也可以)的值進行Hash運算,然後根據Hash結果分散到不同的資料庫表中。同樣以用戶Id為例,假如我們一開始就規划了10個資料庫表,路由演算法可以簡單地用user_id%10的值來表示數據所屬的資料庫表編號,ID為985的用戶放到編號為5的子表中,ID為10086的用戶放到編號為6的子表中。

配置路由:配置路由就是路由表,用一張獨立的表來記錄路由信息,同樣以用戶ID為例,我們新增一張user_router表,這個表包含user_id和table_id兩列,根據user_id就可以查詢對應的table_id

8、應用拆分/微服務

隨著業務的發展,業務越來越多,應用的壓力越來越大。工程規模也越來越龐大。這個時候就可以考慮將應用拆分,按照領域模型將我們的商品,訂單,用戶分拆成子系統。

這樣拆分以後,可能會有一些相同的代碼,比如訂單模塊有對用戶數據的查詢,用戶模塊中肯定也有對用戶數據的查詢。這些相同的代碼和模塊一定要抽象出來。這樣有利於維護和管理。這時可以將模塊變為一個個服務,模塊之間互相調用來獲取數據,系統就變成一個微服務了。

 

服務拆分以後,服務之間的通信可以通過RPC技術,比較典型的有:Webservice、Hessian、HTTP、RMI等。如當前的Dubbo和Spring Cloud都是目前比較流行的微服務框架。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 命令模式是行為型設計模式,本文對命令模式Command進行了簡單介紹,深入的分析了命令模式的意圖,以及演化邏輯,並且給出了命令模式的Java版示例,理解命令模式有利於理解面向對象的編程思想,一切皆是對象,方法調用也是一種對象。 ...
  • 索引的構成 在看IndicesService服務中移除索引的前提,先瞭解一個Index類的構成,也就是索引的一些基本信息,代碼貼圖如下: 主要的信息就兩個:一個是name,表示索引名稱,一個是uuid,表示索引的唯一標識。ok,瞭解這個之後。我們開始表述我們的正題,索引是怎麼刪除的,要刪除哪些信息。 ...
  • 前言 這一章的課題看起來就很和藹可親了,比起前面繞的我不要不要的工廠模式,那感覺真是太好了,但是正是因為簡單,那麼問題就來了,我怎麼才能把這個東西敘述清楚?怎麼樣才能老少咸宜呢? 如何能夠在把這個東西講清楚的同時,引入一些新的東西讓這個設計模式能顯得不那麼普通呢?我不知道能不能做到,不過,吹x馬上開 ...
  • 代理模式(Proxy Pattern)也叫委托模式,是一個使用率非常高的模式。 定義: 為其他對象提供一種代理以控制對這個對象的訪問。 代理模式是一項基本的設計技巧,許多其他的模式,如狀態模式、策略模式、訪問者模式本質上也採用了代理模式。類圖如下所示。 代理模式提供以下3個角色。 抽象主題(Subj ...
  • 在文章《 "Java 11 正式發佈,這 8 個逆天新特性教你寫出更牛逼的代碼" 》中,我有介紹到 Java 11 的八個新特性,其中關於 String 加強部分,我覺得有點意思,這裡單獨再拉出來講。 Java 11 增加了一系列的字元串處理方法,如以下所示。 最有意思的是 和 方法了,來看下還能怎 ...
  • [TOC] mybatis插件機制 mybatis的插件機制使用動態代理實現,不瞭解的朋友請先瞭解代理模式和動態代理;插件本質是功能增強,那麼它如果需要對某個方法進行增強,首先要攔截這個方法,其實也就類似於攔截器,mybatis的插件在代碼中定義為Interceptor,也就是攔截器;後面統一稱作攔 ...
  • #!/usr/bin/env python # encoding: utf-8 #@author: 東哥加油! #@file: del_tb_bigtable_statistic.py #@time: 2018/11/21 15:39 import pymysql import datetime i... ...
  • 平時在開發過程中dao、bean和XML文件都是自動生成的,很少寫XML的配置關係,今天記錄一下mybatis的關聯查詢中的多對一和一對多的情況。 首先是有兩張表(學生表Student和老師Teacher表),為了更易懂,這裡只設置了最簡單的幾個必要欄位。表結構如下圖: Student表: ​ Te ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...