分庫分表會帶來哪些問題

1 爲何要分庫分表

確定是數據庫性能瓶頸的出現,才須要分庫分表,可是隻要出現性能瓶頸問題就必定要分庫分表嗎?不必定
html

1.1 數據庫通常會出現什麼問題

  • 沒法獲取連鏈接。數據庫鏈接數是一種資源,因爲數據庫硬件的限制,通常都須要控制最大鏈接數。當併發量達到必定程度就會形成數據庫鏈接不夠用。
  • 操做數據變慢。一張表的數據量過大,致使插入、更新、查詢、刪除操做變慢。
  • 磁盤不足。某個數據庫數據量太大,磁盤容量不夠或者接近最大容量,致使寫入或者查詢都很慢。

1.2 出現問題應該怎麼分析並解決

針對上述問題,咱們應該如何思考?前端

  • 沒法獲取鏈接問題:(1)能夠把單個操做改操批量操做,尤爲是建立記錄,減小獲取鏈接的次數。(2)修改數據庫配置,增長最大鏈接數和緩衝區。
  • 操做數據變慢問題:(1)優化sql和索引。對於慢查詢語句,能夠優化查詢sql,使它儘可能用到索引。對於更新和插入語句,能夠把單個操做改操批量操做。(2)優化表結構和存儲引擎。根據表的使用場景(讀多寫少、寫多讀少)合理選擇存儲引擎,或者對錶字段進行拆分和優化。(3)使用集羣,作負載均衡,利用主從庫作讀寫分離。(4)緩存。在查詢數據庫前面作一層緩存。(5)分庫分表。把數據存儲到不一樣的數據庫或者表,減輕數據庫存儲和訪問的壓力。
  • 磁盤不足問題:(1)分庫分表。減輕單個數據庫存儲壓力。(2)增長磁盤空間

2 分庫分表解決了什麼問題

主要是解決單個數據庫存儲和訪問的壓力。分庫以後,單個數據庫存儲的數據量就少了,並且響應的請求也減小了。
redis

通常有性能問題均可以採用分庫分表解決,可是分庫分表並非性能問題的最優解。
例如沒法獲取鏈接問題,是由於單個數據庫最大鏈接數有限,若是分庫則可擴大鏈接數。
例如操做數據慢,分庫以後操做也相應的分到了多個數據庫商,操做確定會加快。
例如磁盤不足,分庫以後不一樣的庫在不一樣的物理機器商,磁盤容量確定比單個數據庫大。
算法

3 分庫分錶帶來了什麼問題

3.1分佈式一致性問題

因爲數據存儲在不一樣的節點上,確定會致使數據不一致。分佈式不一致問題的研究可參考文章分佈式一致性那些事兒sql

3.2 跨節點關聯表

當A庫的a表須要與B庫的b表關聯查詢怎麼辦?有以下幾種解決方案:
數據庫

  • 冗餘字段。若是a表只須要關聯出b表的一個或者幾個字段,能夠考慮在a表中冗餘這幾個字段,這樣就不須要關聯b表了。
  • 基礎數據冗餘表。有的基礎數據例如國家、貨幣等,不一樣的數據庫都要關聯它,則在每一個數據庫中冗餘存儲這些基礎數據。
  • 冗餘業務表。仍是」A庫的a表須要與B庫的b表關聯查詢「場景,能夠在A庫中冗餘存儲B庫的b表,經過數據同步機制保持與B庫的b表數據一致,這樣A庫就能夠直接關聯冗餘表了。
  • 綁定表。須要關聯的數據放在一個節點上。好比按租戶分庫分表,不一樣租戶之間不會有數據關聯查詢,同一個租戶內的數據都在一個節點上,能夠直接關聯。

當出現了跨接待你關聯的問題,必定要想想業務邏輯是否合理,若是真的要跨節點關聯,通常是經過rpc調用另一個節點的數據,組裝好再返回給前端或者第三方,對外無感知。緩存

3.3 跨節點分頁、排序、函數計算

跨節點多庫進行查詢時,會出現 limit 分頁,order by 排序的問題。好比有兩個節點,節點 1 存的是奇數 id=1,3,5,7,9……;節點 2 存的是偶數 id=2,4,6,8,10……執行 select*from user_info order by id limit 0,10,則須要在兩個節點上各取出 10 條,而後合併數據,從新排序。
markdown

max、min、sum、count 之類的函數在進行計算的時候,也須要先在每一個分片上執行相應的函數,而後將各個分片的結果集進行彙總和再次計算,最終將結果返回。
併發

或者根據名稱模糊分頁查詢,而名稱字段單獨存放在i18n表,這個時候就須要先從i18n表中查出全部符合模糊查詢的記錄,而後從主表中分頁查詢,當i18n表很是大的時候很耗性能。
負載均衡

3.4 全局主鍵不惟一

MySQL 的數據庫裏面字段有一個自增的屬性,Oracle 也有 Sequence 序列。若是是一個數據庫,那麼能夠保證 ID 是不重複的,可是水平分表之後,每一個表都按照本身的規律自增,確定會出現 ID 重複的問題,這個時候咱們就不能用本地自增的方式了。

解決方案:

  • UUID。缺點是否是遞增,並且在分佈式環境中還可能出現重複。
  • 基於數據庫把id統一存儲。全部須要id的服務都從同一個數據庫中獲取,數據庫確保id遞增且惟一。可是這樣增長了一層調用,當請求量大的時候對數據庫也是一種壓力。
  • 基於redis。比數據庫速度快,也是增長了一層調用,有失敗、超時的風險
  • 雪花算法。可是它強依賴機器時鐘,若是時鐘回撥,則可能致使生成 ID 重複。

3.5 數據庫擴容、數據遷移問題

有的分庫分表策略在數據庫擴容的時候不方便。好比按id的奇偶分表,當某一天按奇偶分表仍是太大,須要換再加一張表,則須要換一種分表策略,好比模3或者模5,則須要把以前的兩張表數據讀取出來從新分表;

有的表按月份分表,每月增長一張表,則不須要遷移歷史數據。

若是採用數值範圍分片,只須要添加節點就能夠進行擴容了,不須要對分片數據遷移。若是採用的是數值取模分片,則考慮後期的擴容問題就相對比較麻煩。

4 參考

【1】MySQL分庫分表會帶來哪些棘手的問題?
【2】分庫分表須要考慮的問題及方案
【3】爲何須要分庫分表
【4】分佈式一致性那些事兒

相關文章
相關標籤/搜索