分庫分表策略的可實現架構


 

  分庫分表 是解決mysql水平擴展的主要手段。

  網上有關策略的討論很多,主要是hash擴展、按時間擴展、按范圍擴展等等。但真正想實施分庫分表的朋友們往往覺得策略聽來終覺淺,覺知此事要代碼,因此本文的主要目的是給朋友們提供一個可實現架構。

 

  JDBCTemplateHibernate

  大家都知道HibernateORM(對象-關系數據庫 mapping)意義上的第一個真正的統治級產品。 JDBCTemplate則是對Springjdbc的簡單封裝,相對於Hibernate,工程師需要自己寫sql,而不是像Hibernate那樣直接操作對象解決數據庫持久化的問題。

  因為暴露了sqlJDBCTemplate當然也不利於跨數據庫(畢竟每個數據庫的實現產品的sql也不竟相同)。但現在大多數互聯網企業都傾向於使用JDBCTemplate,而不是Hibernate

  個人認為主要原因就是性能問題:

  (1) 為獲取更好性能,往往根據不同數據庫采用特有的優化方式,即使是DAO層全部用Hibernate實現,遷移數據庫也不是輕松的工作。

  (2) 使用Hibernate處理關聯關系往往將大量數據信息加載到業務系統內存,而不是在數據庫系統中處理,只是將最終結果返回。這樣破壞了生產系統和DB的解耦,導致DB優化困難,以及生產系統的不安全。

  (3) 分庫分表對於Hibernate來說顯得比較復雜

   可以說第三個原因是主要的。本文會圍繞JDBCTemplate來實現分庫分表,如果你還在使用Hibernate,建議逐漸切換到JDCBTemplate

 

分庫分表策略

  分庫分表策略,簡單來說就是根據要被持久化的數據,分配一個庫或者表來讀/寫。因此DBSplitStrategy接口定義如下:

  interface DBSplitStrategy {  

       String getDBName(long id); // 獲取庫名  

       String getTableSuffix(long id); // 獲取表名  

       JdbcTemplate getIdxJdbcTemplate(long id); // 獲取db jt  

       JdbcTemplate getIdxJdbcTemplate(String dbname); // 根據庫名獲取 db jt  

       JdbcTemplate getIdxJdbcTemplateByTable(String table); // 根據表名獲取db jt  

  }  

  接口定義是圍繞最基本的:key -> 邏輯庫名/表名 -> 物理庫名/表名

 實現類

   以最常見的HashSplit為例,首先我們需要幾個基本的配置項:

  (1)基本庫名,也可以叫庫名前綴;

  (2)分庫總數;

  (3)分表總數;

  (4)分庫對應的物理地址,即JDBCTemplate定義

Spring 配置

  <bean id="dataService" class="DBSplitStrategy">
    <property name="DBNameBase" value="session_" />
    <property name="splitDBCount" value="16" />
    <property name="splitTbCount" value="64" />
    <property name="dmJts">
  <map>
  <entry key="session_1" value-ref="jts1"></entry>
  <entry key="session_2" value-ref="jts2"></entry>
  ...

 

有了以上配置,代碼工作只需要把輸入的關鍵詞安裝策略轉換成邏輯庫名、表名即可,偽代碼如下:碼  

  public String getTableName(long id) {  

      long hash = getHash4split(id, splitCount);  

      return tbNameBase + String.valueOf(hash / shareDBCount + 1);  

  }  

  

  public String getDBName(long id) {  

      long hash = getHash4split(id, splitCount);  

      return dbNameBase + ( hash % shareDBCount + 1);  

  }  

  這段代碼里有個有趣的邏輯,如果你的業務主鍵從 一直增長,那么分庫分表的結果就是:庫1,表0;庫2,表0;庫3,表0..... 1,表2;庫2,表2... 

 總結

  Mysql分庫分表,水平擴展還有很多問題這里沒有涉及到,比如, 

  如果最初分配的64個分表不夠用了怎么辦?這是最初決定分庫分表是需要考慮的重要問題,因為hash容易,rehash難。

  這么多數據分散在不同的庫表中,怎么分析和挖掘呢?

  怎么樣的分庫策略更適合你呢?

 


免責聲明!

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



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