一、學習動機
伴隨互聯網行業的興起,越來越多的領域需要相應的技術方案,比如:打出軟件、電商平台、直播平台、電子支付、媒體社交。
身邊常見的,校園出成績那一年,我們會感覺網站異常的卡頓,因為訪問人數太多。
單機單點的數據庫,一旦這台機子宕機(機器出現故障、機房停電、...),那整個網站將無法正常訪問。這時候集群就出現了,一台機器出現問題了,另外的機器還在正常運行,網站依舊可以訪問。
集群案例:滴滴出行、淘寶、京東、斗魚直播、支付寶、微信、QQ
二、案例
1.天貓雙十一
2017年天貓雙十一的交易額達到1682億元,3分鍾破百億,9小時破千億
交易峰值(下訂單的峰值):32.5萬/秒
支付峰值:25.6萬/秒
數據庫峰值:4200萬/秒
支持這么漂亮的數字完美運行,除了數據庫集群技術還有雲服務器、負載均衡、RDS雲數據庫等技術
2.微信紅包
2017年除夕當天,全國人民總共收發142億個紅包,峰值42萬/秒
央視春晚微信搖一搖互動總量達110萬億次,峰值8.1億/秒
三、學習目標和方式
1.學習目標:
1)向大型互聯網應用看起,學習架構設計和業務處理
2)掌握PXC集群MySQL方案的原理
3)掌握PXC集群的強一致性
4)掌握PXC集群的高可用方案
2.學習方式:由淺入深,循序漸進;案例有小到大,逐步擴展
四、硬件環境需求
1.win10 x64專業版或者企業版(PXC不支持windows,需要用到虛擬機,所以最好不要使用home版或者32位的系統)/Linux/MacOS
2.Docker虛擬機
3.內存8GB以上
五、單節點數據庫的弊端
1.大型互聯網程序用戶群里龐大,所以架構必須要特殊設計
2.單節點的數據庫無法滿足性能上的要求,就像校園網查成績的時候,如果1萬人同時查,你可能拿到就是一個白屏,無論你是收費的還是免費的數據庫,單節點都滿足不了這種並發需求
3.單節點的數據庫沒有冗余設計,無法滿足高可用,一旦這個機器出現問題,沒有其他節點的數據庫頂替,那網站將無法正常訪問
單節點數據庫測試,5000個連接,5000個並發查詢,平均就1個連接1個查詢,安裝好數據庫,配置好環境變量,[mysqld]下面配置最大連接量為6000(max_connections=6000),執行下面的命令:
mysqlslap -hlocalhost -uroot -pabc123456 -P3306 --concurrency=5000 --iterations=1 --auto-generate-sql --auto-generate-sql-load-type=mixed --auto-generate-sql-add-autoincrement --engine=innodb --number-of-queries=5000
得到下面的結論:
這才5000個並發,需要的時間就達到了34秒,如果設置10000個並發,將如何呢?
數據庫拒絕了很多請求,把沒有拒絕的執行了,需要的時間是167秒,這就是單擊單點在面對並發的時候數據庫的承受能力。
六、PXC高可用集群方案
這樣一個最基本的PXC集群,它保證了每個節點的的數據都是一致的,不會出現數據寫入了數據庫1而沒有寫入數據庫2的情況,這種的集群在遇到單表數據量超過2000萬的時候,mysql性能會受損,所以一個集群還不夠,我們需要把數據分到另一個集群,這個稱為“切片”,就是把大量的數據拆分到不同的集群中,每個集群的數據都是不一樣的,看下面的截圖:
這樣一來,PXC集群1存前面1000萬條數據,PXC集群2存后面1000萬條數據,當一個sql語句請求的時候,通過MyCat這個阿里巴巴的開源中間件,可以把sql分到不同的集群里面去。這種的分片按照數量就是2個分片。
這個切分算法也比較多,比如按照日期、月份、年份、某一列的固定值,或者最簡單的按照主鍵值切分,主鍵對2求模,余0的存分片1,余1的存分片2,這樣MyCat就會把2000萬條數據均勻地分配到2個集群上。
PXC雖然保證了數據的強一致性,但是這是以犧牲性能為代價的,所以適合保存重要的數據,比如訂單。
七、Replication集群方案
這種集群,在第一個節點插入以后,就馬上返回給客戶端執行成功了,然后再做每個節點之間的同步,如果某一個同步操作失敗了,那用戶請求的時候拿到的數據就不同步了,但是它的優勢是速度快,不會犧牲任何地性能,適合保存不那么重要的數據,比如日志。
八、PXC與Replication集群結合
九、系統架構方案
更加清晰和詳細架構請看下面的截圖
十、APP的架構設計
客戶端包括web瀏覽器端,移動手機端,用戶通過客戶端發送一個請求后,Nginx接收到請求后,會做負載均衡,定向到當前最適合(相對沒那么繁忙)處理這個請求的服務器端,服務端接收到請求后,再訪問數據庫,一些熱點數據需要做緩存,比如淘寶首頁的商品。從上面的圖中看,服務器端的某一個出現故障后,nginx會將請求定向到剩下的能正常運行的服務器上面,而數據庫端也是采用的集群,這樣就達到了高可用,就是任意一台機器出現故障,對整個網站的運行不會產生太大的影響,這里可能有人會問如果nginx這台服務器出現問題了怎么辦?可以做虛擬ip(vip),配置主從入口,就是nginx1和nginx2的虛擬ip是一樣的,其中有一個是主入口,在主入口沒有出現問題的時候,從機是不會工作的,當主入口機出現問題了,從入口機就會頂替,如果主從都出現問題了,那網站將無法訪問。
服務器端的spring與spring之間的調用又是如何的?現在都是分布式調用,比較經典的是dubbo+zookeeper。這里有同步調用和異步調用
同步調用:提出問題的一方直接調用處理問題的一方
異步調用:提出問題的一方將問題交個消息中間件,由消息中間件去將問題發放給處理問題的一方,在這里,提出問題的一方稱為“生產者”,處理問題的一方稱為“消費者”,他們彼此是不知道對方是誰,達到業務解耦的效果,這樣做的好處是以后在部署項目、程序的升級、接口的變更的時候,它的影響面就很小。比如說生產者項目開發地有問題,然后用其他語言再做了一個項目,對消費者不會產生任何影響,只要生產生能正常往消息隊列里面發送消息就好;再比如用戶注冊一個淘寶賬號,我們連帶着把支付寶賬號也給你開通,然后其他的投資的項目也給用戶一些優惠(給你2張淘票票的電影票,免費一個月的蝦米音樂會員等等),對應淘寶這一端,它發起一個消息傳達給消息隊列,至於接收端是支付寶還是淘票票還是蝦米音樂,淘寶這一端不知道也不需要關心,等以后阿里再有什么投資項目需要給新用戶優惠的時候,只需要從消息隊列里接收消息就可以,對生產者而言,沒有任何影響。如果是同步調用(dubbo或者webservice調用),其中一端有修改,另一端必然也要改,這種強耦合是不好的。
以下是異步調用方案圖: