一、目標和方式
1.目標:
1)大型互聯網應用的架構設計和業務處理
2)掌握PXC集羣MySQL方案的原理
3)掌握PXC集羣的強一致性
4)掌握PXC集羣的高可用方案
2.分析方式:由淺入深,循序漸進;案例有小到大,逐步擴展
二、硬件環境需求
1.win /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集羣結合
每一臺Slave只有一個Master,這樣可以防止自增鍵出現重複計數的問題,mycat實現了數據庫一般查詢和一致性查詢分流,master-slave提高了併發性能。master-master實現了本地雙活高可用。master-rp(異地)異地實時同步提高了抗風險能力。上圖中任意一臺服務器宕機都不會影響服務的正常運行
七、系統架構方案
更加清晰和詳細架構請看下面的截圖
八、APP的架構設計
客戶端包括web瀏覽器端,移動手機端,用戶通過客戶端發送一個請求後,Nginx接收到請求後,會做負載均衡,定向到當前最適合(相對沒那麼繁忙)處理這個請求的服務器端,服務端接收到請求後,再訪問數據庫,一些熱點數據需要做緩存,比如淘寶首頁的商品。從上面的圖中看,服務器端的某一個出現故障後,nginx會將請求定向到剩下的能正常運行的服務器上面,而數據庫端也是採用的集羣,這樣就達到了高可用,就是任意一臺機器出現故障,對整個網站的運行不會產生太大的影響,這裏可能有人會問如果nginx這臺服務器出現問題了怎麼辦?可以做虛擬ip(vip),配置主從入口,就是nginx1和nginx2的虛擬ip是一樣的,其中有一個是主入口,在主入口沒有出現問題的時候,從機是不會工作的,當主入口機出現問題了,從入口機就會頂替,如果主從都出現問題了,那網站將無法訪問。
服務器端的spring與spring之間的調用又是如何的?現在都是分佈式調用,比較經典的是dubbo+zookeeper。這裏有同步調用和異步調用
同步調用:提出問題的一方直接調用處理問題的一方
異步調用:提出問題的一方將問題交個消息中間件,由消息中間件去將問題發放給處理問題的一方,在這裏,提出問題的一方稱爲“生產者”,處理問題的一方稱爲“消費者”,他們彼此是不知道對方是誰,達到業務解耦的效果,這樣做的好處是以後在部署項目、程序的升級、接口的變更的時候,它的影響面就很小。比如說生產者項目開發地有問題,然後用其他語言再做了一個項目,對消費者不會產生任何影響,只要生產生能正常往消息隊列裏面發送消息就好;再比如用戶註冊一個淘寶賬號,我們連帶着把支付寶賬號也給你開通,然後其他的投資的項目也給用戶一些優惠(給你2張淘票票的電影票,免費一個月的蝦米音樂會員等等),對應淘寶這一端,它發起一個消息傳達給消息隊列,至於接收端是支付寶還是淘票票還是蝦米音樂,淘寶這一端不知道也不需要關心,等以後阿里再有什麼投資項目需要給新用戶優惠的時候,只需要從消息隊列裏接收消息就可以,對生產者而言,沒有任何影響。如果是同步調用(dubbo或者webservice調用),其中一端有修改,另一端必然也要改,這種強耦合是不好的。
以下是異步調用方案圖: