Java學習之Mysql結構優化
背景:業務發展初期為了便於快速叠代,很多應用都采用集中式的架構,隨著業務規模的擴展,系統變得越來越復雜,訪問量越來越大,不得不進一步擴展系統的吞吐能力。
優化1、主從集群:通過數據庫的復制策略,可以將一臺mysql數據庫服務器中的數據復制到其他的mysql數據庫服務器之上,當各臺數據庫服務器上都包含相同數據的時候,前端應用通過訪問mysql集群中任意一臺服務器,都能夠讀取到相同的數據,這樣,每臺mysql服務器所需要承擔的負載就會大大降低,從而提高整個系統的承載能力,達到系統擴展的目的。
要實現數據庫的復制,需要開啟master服務器端的binary log,數據復制的過程實際上就是slave從master獲取binary log,然後再在本地鏡像的執行日誌中所記錄的操作,由於復制過程是異步的,因此,master和slave之間的數據有可能存在延遲的現象,此時只能夠保證數據最終的一致性。
優化2、讀寫分離:前端服務器通過master來執行數據寫入的操作,數據的更新通過binary log同步到slave集群,而對於數據讀取的請求,則交由slave來處理,這樣,slave集群可以分擔數據庫讀的壓力,並且,讀寫分離還保障了數據能夠達到最終一致性。一般而言,大多數站點的讀數據庫操作要比寫數據庫操作更為密集,如果讀的壓力較大,還可以通過新增slave來進行系統的擴展,因此,master-slave的架構能夠顯著的減輕前面所提到的單庫讀的壓力,畢竟在大多數應用當中,讀的壓力要比寫的壓力大的多。
master-slaves復制架構存在一個問題,即所謂的單點故障,當master宕機,系統將無法寫入,而在某些特定的場景下,可能需要master停機,以便進行系統維護、優化或者升級,同樣的道理,master停機將導致整個系統都無法寫入,直到master恢復,大部分情況下這顯然是難以接受的。為了盡可能的降低系統停止寫入的時間,最佳的方式就是采用dual master架構,即master-master架構。
優化3、分表:對於訪問極為頻繁且數據量巨大的單表來說,我們首先要做的,就是減少單表的記錄條數,以便減少數據查詢所需要的時間,提高數據庫的吞吐,這就是所謂的 分表。在分表之前,首先需要選擇適當的分表策略,使得數據能夠較為均衡的分布到多張表中,並且,不影響正常的查詢。對於互聯網企業來說,大部分數據都是與用戶進行關聯的,因此,用戶id是最常用的分表字段,因為大部分查詢都需要帶上用戶id,這樣既不影響查詢,又能夠使數據較為均衡的分布到各個表中。
優化4、分庫:分表能夠解決單表數據量過大帶來的查詢效率下降的問題,但是,卻無法給數據庫的並發處理能力帶來質的提升,面對高並發的讀寫訪問,當數據庫master服務器無法承載寫操作壓力時,不管如何擴展slave服務器,此時都沒有意義了。因此,我們必須換一種思路,對數據庫進行拆分,從而提高數據庫寫入能力,這就是所謂的 分庫。舉例來說,假設某門戶網站,它包含了新聞、用戶、帖子、評論等等幾大塊內容,對於數據庫來說,它可能包含這樣幾張表,news、users、post、comment,隨著數據量的增加,可以根據業務邏輯進行拆分,分成多個庫,以提高系統吞吐能力。
有的時候,數據庫可能即面臨著高並發訪問的壓力,又需要面對海量數據的存儲問題,這時候,需要對數據庫即采用分庫策略,又采用分表策略,以便同時擴展系統的並發處理能力,以及提升單表的查詢性能,這就是所謂的 分庫分表。
假設將原來的單庫單表order拆分成256個庫,每個庫包含1024個表,那麽,按照前面所提到的路由策略,對於userid=262145的訪問,路由的計算過程如下:
中間變量=262145%(256*1024)=1
庫=取整(1/1024)=0
表=1%1024=1
這意味著,對於userid=262145的訂單記錄的查詢和修改,將被路由到第0個庫的第1個表中執行。
缺陷:
1.條件查詢、分頁查詢受到限制,查詢必須帶上分庫分表所帶上的id
2.事務可能跨多個庫,數據一致性無法通過本地事務實現,無法使用外鍵
3.分庫分表規則確定以後,擴展變更規則需要遷移數據
Java學習之Mysql結構優化