分庫&分表&讀寫分離

爲什麼要分庫分表和讀寫分離?

類似淘寶網這樣的網站,海量數據的存儲和訪問成爲了系統設計的瓶頸問題,日益增長的業務數據,無疑對數據庫造成了相當大的負載,同時對於系統的穩定性和擴展性提出很高的要求。隨着時間和業務的發展,數據庫中的表會越來越多,表中的數據量也會越來越大,相應地,數據操作的開銷也會越來越大;另外,無論怎樣升級硬件資源,單臺服務器的資源(CPU、磁盤、內存、網絡IO、事務數、連接數)總是有限的,最終數據庫所能承載的數據量、數據處理能力都將遭遇瓶頸。分表、分庫和讀寫分離可以有效地減小單臺數據庫的壓力。

MySQ一主多從,讀寫分離;寫主庫,讀從庫(所有的數據庫的數據都是一樣的)
數據一樣的,那麼當數據量太大的時查詢還是很慢的

分庫分表的原因

  1. 隨着單庫中的數據量越來越大,相應的,查詢所需要的時間也越來越多,這個時候,相當於數據的處理遇到了瓶頸
  2. 單庫發生意外的時候,需要修復的是所有的數據,而多庫中的一個庫發生意外的時候,只需要修復一個庫(當然,也可以用物理分區的方式處理這種問題)

分庫(根據用戶的ID分庫)
所有數據庫的表結構是一樣的,但存儲的數據完全不同
真實的開發環境以用戶的ID進行分離,每一個庫的數據量小,查詢就很快了
無法解決問題:當一個數據庫中表中數據量過大的時候,查詢依然很慢

分表(根據存儲數據的時間來分)
當一個數據庫的數據量過大時,必須進行表拆分
分表主要是基於數據表的某個字段來將一個表拆分爲多個子表,即一個表中的數據行拆分到多個子表中去保存,子表存放到同一個數據庫的不同表或者不同的數據庫中。

分庫分錶帶來的問題及解決辦法
任何事情都有兩面性,分庫分表也不例外,如果採用分庫分表,會引入新的的問題

1、分佈式事務問題
使用分佈式事務中間件解決,具體是通過最終一致性還是強一致性分佈式事務,看業務需求,這裏就不多說。

2、跨節點關聯查詢 Join 問題
切分之前,我們可以通過Join來完成。而切分之後,數據可能分佈在不同的節點上,此時Join帶來的問題就比較麻煩了,考慮到性能,儘量避免使用Join查詢。

解決這個問題的一些方法:
全局表
全局表,也可看做是 “數據字典表”,就是系統中所有模塊都可能依賴的一些表,爲了避免跨庫Join查詢,可以將 這類表在每個數據庫中都保存一份。這些數據通常
很少會進行修改,所以也不擔心一致性的問題。
字段冗餘
利用空間換時間,爲了性能而避免join查詢。例:訂單表保存userId時候,也將userName冗餘保存一份,這樣查詢訂單詳情時就不需要再去查詢"買家user表"了。
數據組裝
在系統層面,分兩次查詢。第一次查詢的結果集中找出關聯數據id,然後根據id發起第二次請求得到關聯數據。最後將獲得到的數據進行字段拼裝。

3、跨節點分頁、排序、函數問題
跨節點多庫進行查詢時,會出現Limit分頁、Order by排序等問題。分頁需要按照指定字段進行排序,當排序字段就是分片字段時,通過分片規則就比較容易定位到指定的分片;

當排序字段非分片字段時,就變得比較複雜了。需要先在不同的分片節點中將數據進行排序並返回,然後將不同分片返回的結果集進行彙總和再次排序,最終返回給用戶。

4、全局主鍵避重問題
如果都用主鍵自增肯定不合理,如果用UUID那麼無法做到根據主鍵排序,所以我們可以考慮通過雪花ID來作爲數據庫的主鍵,

5、數據遷移問題
採用雙寫的方式,修改代碼,所有涉及到分庫分表的表的增、刪、改的代碼,都要對新庫進行增刪改。同時,再有一個數據抽取服務,不斷地從老庫抽數據,往新庫寫,

邊寫邊按時間比較數據是不是最新的。

當業務系統的數據容量接近或超過單臺服務器的容量、QPS/TPS接近或超過單個數據庫實例的處理極限等此時,往往是採用垂直和水平結合的數據拆分方法,把數據服務和數據存儲分佈到多臺數據庫服務器上

讀寫分離

什麼是讀寫分離

讀寫分離的實質是將應用程序對數據庫的讀寫操作分配到多個數據庫服務器上,從而降低單臺數據庫的訪問壓力。

讀寫分離一般通過配置主從數據庫的方式,數據的讀取來自從庫,對數據庫增加修改刪除操作主庫。
在這裏插入圖片描述

爲什麼要讀寫分離呢?
通過數據庫中間件,可以對數據庫進行水平擴展,由原來單臺數據庫擴展到多臺數據庫,數據庫中間件通過路由規則將數據的訪問請求路由到其中一臺數據庫上

  • 因爲數據庫的“寫”(寫10000條數據到oracle可能要3分鐘)操作是比較耗時的。
  • 但是數據庫的“讀”(從oracle讀10000條數據可能只要5秒鐘)。
  • 所以讀寫分離,解決的是,數據庫的寫入,影響了查詢的效率。
  • 降低了數據訪問的瓶頸和單臺數據庫的壓力。通過數據庫中間件還可以將DBA和研發進行解耦,提升DBA運維效率。
    在這裏插入圖片描述

讀寫分離方案

  • 當數據庫讀遠大於寫,查詢多的情況,就可以考慮主數據負責寫操作,從數據庫負責讀操作,一主多重,從而把數據讀寫分離
  • 可以結合redis等緩存來配合分擔數據的讀操作,大大的降低後端數據庫的壓力
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章