數據庫-數據庫設計-分庫分表


why分庫分表

分庫分表其實是解決海量數據存儲、高並發查詢和寫的問題。解決這個問題還有其他的方案,但是使用場景不同,比如:

  • NosSql:比如Hbase,MongoDB,這些適合非結構化、不關心事務的場景,這時可以可以選擇Nosql陣營的產品。
  • 關系型數據庫:
    • 讀寫分離:讀多寫少模式,采用主從架構,根據qps的峰值和單台機器查詢的性能確定數量。
    • 表分區:在表存儲階段進行存儲,應用無感知,因為是在一個庫內完成的操作,無法線性擴展,所以只能適應數據量不是特別大的case。

本章主要討論關系型數據庫的分庫分表

  • 分表:單表瓶頸:單表數據過千萬時,查詢RT會升高,整體的QPS會下降,難以支撐高並發場景。
  • 分庫:單庫瓶頸:應用數變多,io,磁盤達到瓶頸,整體的QPS會下降,難以支撐高並發場景。

how分庫分表

  • 水平切分與垂直切分

    • 垂直切分:垂直拆分是指數據表列的拆分,把一張列比較多的表拆分為多張表。表的記錄並不多,但是字段卻很長,表占用空間很大,檢索表的時候需要執行大量的IO,嚴重降低了性能。這時需要把大的字段拆分到另一個表,並且該表與原表是一對一的關系。
      • 切分原則
        • 1,把不常用的字段單獨放在一張表;,
        • 2,把text,blob等大字段拆分出來放在附表中;
        • 3,經常組合查詢的列放在一張表中;
      • 優點
        • 數據庫的拆分簡單明了,拆分規則明確;
        • 應用程序模塊清晰明確,整合容易;
        • 數據維護方便易行,容易定位;
      • 缺點
        • 部分表關聯無法在數據庫級別完成,需要在程序中完成;
        • 對於訪問極其頻繁且數據量超大的表仍然存在性能平靜,不一定能滿足要求;
        • 事務處理相對更為復雜;
        • 切分達到一定程度之后,擴展性會遇到限制;
        • 過讀切分可能會帶來系統過渡復雜而難以維護。
      • 備注:一定要在設計階段就解決這個問題,時候的拆分成本代價較高
    • 水平切分:將一個表的記錄水平分到多張表里面,下面會細說
  • 如何選擇分庫分表字段:

    • 充分的業務場景分析,找出使用頻度最高的字段。
    • 常見的有賣家id、買家id、訂單id、商戶id、業務id、時間
  • 分庫分表水平切分的策略:確定分表字段后,要確定如何按照字段去分,常見算法分區、取模、數據路由表

    • 按照時間分區
      • 原理:將一定區間內的數據放到一張表,多個表在一個庫里面
      • 案例:具體用哪一種,需要根據數據量進行評估
        • 按照日分
          每日1張表,當單庫超過100張表的時候,分到下一個庫。
          算法:庫ID=(當前日期-上線日期)/100 表ID=業務表_yyyyMMdd
        • 按照月分
          業務表_yyyyMM
        • 按照年分
          業務表_yyyy
    • 先hash,后取模
    • 直接取模
    • 范圍分表
      • 比如四張表,每個表只存1000w,第一個表存1-1000w,第四張表存儲3001-4000w

帶來的問題&解決的辦法

事物都具有兩面性,分庫分表固然解決了高並發存儲的問題,但是也帶來了一些后遺症

  • 全局主鍵問題
  • 多種查詢維度的問題:比如訂單表,既要通過買家id來查,又要通過賣家id來查,這時sharding column就矛盾了。怎么解決呢?
    • 數據冗余:上面的例子,可以冗余兩張表,分別是買家和賣家表。犧牲存儲來換查詢復雜度
    • 表替代索引:數據冗余適合查詢維度較少的場景,如果多了,數據冗余量太大,就不再是合理的方案了,表替代索引法
    • 全局存儲搜索法:通過搜索引擎的方式存儲和查詢,比如數據同步到ES上。
      • 分庫分表+es的方案,隨着數據量越來越來,雖然分庫分表可以繼續成倍擴容,但是這時候壓力又落到了es這里,這個架構也會慢慢暴露出問題!
        一般訂單表,積分明細表等需要分庫分表的核心表都會有好幾十列,甚至上百列(假設有50列),但是整個表真正需要參與條件索引的可能就不到10個條件(假設有10列)。這時候把50個列所有字段的數據全量索引到es中,對es集群有很大的壓力,后面的es分片故障恢復也會需要很長的時間。
        這個時候我們可以考慮減少es的壓力,讓es集群有限的資源盡可能保存條件檢索時最需要的最有價值的數據,即只把可能參與條件檢索的字段索引到es中,這樣整個es集群壓力減少到原來的1/5(核心表50個字段,只有10個字段參與條件),而50個字段的全量數據保存到HBase中,這就是經典的es+HBase組合方案,即索引與數據存儲隔離的方案。
        Hadoop體系下的HBase存儲能力我們都知道是海量的,而且根據它的rowkey查詢性能那叫一個快如閃電。而es的多條件檢索能力非常強大。這個方案把es和HBase的優點發揮的淋漓盡致,同時又規避了它們的缺點,可以說是一個揚長避免的最佳實踐。
        它們之間的交互大概是這樣的:先根據用戶輸入的條件去es查詢獲取符合過濾條件的rowkey值,然后用rowkey值去HBase查詢,后面這一查詢步驟的時間幾乎可以忽略,因為這是HBase最擅長的場景

業界知名中間件產品和優劣對比

  • 阿里的TDDL,DRDS和cobar,
  • 開源社區的sharding-jdbc(3.x已經更名為sharding-sphere);
  • 民間組織的MyCAT;
  • 360的Atlas;
  • 美團的zebra;

擴容

分布式事務


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM