分庫分表-ShardingSphere

  • 前言

通常mysql單表存儲數據量小於1千萬左右的時候,它的讀寫性能是最好的。可是當業務發展到必定程度,數據增加到必定程度的時候,咱們就會發現爲何查詢速度愈來愈慢了,甚至還會出現數據庫掛了等其餘一系列問題。那麼此時咱們就須要採起一些方案來解決這些問題,通常以下:java

1.分庫分表
2.讀寫分離
3.利用NoSql

這裏我暫時只記錄分庫分表。node

  • 調研

通常業界用的比較多的是阿里的MyCat以及噹噹的Sharding-Jdbc。mysql

MyCat比較適合大公司。他是架在應用層和數據庫之間,作了一層代理和轉發。對於業務上來講,並不須要關心數據怎麼分庫分表。MyCat單獨的一個應用會專門維護這些數據。他回去攔截應用的sql並進行處理再轉發出去。對於業務層幾乎不須要改動,可是多了一層轉發的鏈路。算法

Sharding-Jdbc比較適合中小型公司。雖然他只支持Mysql,可是他十分輕量,支持任何基於java的ORM框架以及三方的數據庫鏈接池。他是以jar包的形式,所以很是靈活,性能高。雖然不用像Mycat須要多一層轉發,可是每一個項目都須要依賴這個jar包,同時在擴展數據庫的時候避免不了部分數據的遷移。spring

  • 選擇

因爲Sharding-Jdbc已經進入了Apache孵化器,其名爲ShardingSphere。所以我這裏直接用了ShardingSphere,能夠更方便的進行運用。sql

官方文檔:https://shardingsphere.apache.org/document/current/cn/overview/數據庫

  • 操做
  1. 依賴jar包

如上文全部,每一個項目都須要依賴相關jar包:express

<dependency>
      <groupId>org.apache.shardingsphere</groupId>
      <artifactId>sharding-jdbc-core</artifactId>
      <version>4.0.0-RC1</version>
</dependency>
<!-- for spring boot -->
<dependency>
       <groupId>org.apache.shardingsphere</groupId>
       <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
       <version>4.0.0-RC1</version>
 </dependency>
 <!-- for spring namespace -->
 <dependency>
       <groupId>org.apache.shardingsphere</groupId>
       <artifactId>sharding-jdbc-spring-namespace</artifactId>
       <version>4.0.0-RC1</version>
  </dependency>
  1. 配置

因爲Apache進行了封裝,所以只須要簡單配置便可使用:apache

spring.shardingsphere.datasource.names=bill_0,bill_1

spring.shardingsphere.datasource.bill_0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.bill_0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.bill_0.url=jdbc:mysql://127.0.0.1:3306/bill_0?characterEncoding=utf8&useSSL=false
spring.shardingsphere.datasource.bill_0.username=root
spring.shardingsphere.datasource.bill_0.password=123456

spring.shardingsphere.datasource.bill_1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.bill_1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.bill_1.url=jdbc:mysql://127.0.0.1:3306/bill_1?characterEncoding=utf8&useSSL=false
spring.shardingsphere.datasource.bill_1.username=root
spring.shardingsphere.datasource.bill_1.password=123456

#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=bill_$->{id % 2}
spring.shardingsphere.sharding.default-database-strategy.complex.sharding-columns=user_id
spring.shardingsphere.sharding.default-database-strategy.complex.algorithm-class-name=com.hongkj.algorithm.CustomDataBaseAlgorithm

spring.shardingsphere.sharding.tables.bill_asset_user.actual-data-nodes=bill_$->{0..1}.bill_asset_user_$->{0..1}
#spring.shardingsphere.sharding.tables.bill_asset_user.table-strategy.inline.sharding-column=id
#spring.shardingsphere.sharding.tables.bill_asset_user.table-strategy.inline.algorithm-expression=bill_asset_user_$->{id % 2}
spring.shardingsphere.sharding.tables.bill_asset_user.table-strategy.complex.sharding-columns=balance_type
spring.shardingsphere.sharding.tables.bill_asset_user.table-strategy.complex.algorithm-class-name=com.hongkj.algorithm.CustomTableAlgorithm
#spring.shardingsphere.sharding.tables.bill_asset_user.key-generator.column=order_no
spring.shardingsphere.sharding.binding-tables=bill_asset_user

#用於單分片鍵的標準分片場景
#spring.shardingsphere.sharding.tables.bill_asset_user.database-strategy.standard.sharding-column= #分片列名稱
#spring.shardingsphere.sharding.tables.bill_asset_user.database-strategy.standard.precise-algorithm-class-name= #精確分片算法類名稱,用於=和IN。該類需實現PreciseShardingAlgorithm接口並提供無參數的構造器
#spring.shardingsphere.sharding.tables.bill_asset_user.database-strategy.standard.range-algorithm-class-name=

#利用雪花算法自增id
spring.shardingsphere.sharding.tables.bill_asset_user.key-generator.column=id
spring.shardingsphere.sharding.tables.bill_asset_user.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.bill_asset_user.key-generator.props.worker.id=123
spring.shardingsphere.sharding.tables.bill_asset_user.key-generator.props.max.tolerate.time.difference.milliseconds=0
#spring.shardingsphere.sharding.tables.bill_asset_user.key-generator.props.<property-name>= #屬性配置, 注意:使用SNOWFLAKE算法,須要配置worker.id與max.tolerate.time.difference.milliseconds屬性
spring.shardingsphere.props.sql.show=true
  • 策略

一共提供了5種分片策略,以下:框架

1.StandardShardingStrategy--標準分片策略
2.ComplexShardingStrategy--複合分片策略(可由開發者本身實現算法)
3.InlineShardingStrategy-Inline表達式分片策略(最多見的就是取模)
4.HintShardingStrategy--經過Hint而非SQL解析的方式分片的策略
5.NoneShardingStrategy--不分片策略

我選擇的最靈活的複合分片策略,這樣能夠自由的本身定義算法。具體實現以下:

public class CustomAlgorithm implements ComplexKeysShardingAlgorithm<String> {
    [@Override](https://my.oschina.net/u/1162528)
    public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<String> complexKeysShardingValue) {
       String userId = complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("user_id").toArray()[0].toString();
       for (String s : collection) {
           int hash = userId.hashCode() % 2;
           if(s.endsWith(hash + "")){
               List<String> list = new ArrayList<>();
               list.add(s);
               return list;
           }
       }
       throw new UnsupportedOperationException();
   }
}

上面這個簡單的算法,就已經實現了根據不一樣的用戶id來取模,從而來選擇不一樣的庫或者表。

  • 以後

這裏只是先暫時實現了一個demo,可是分庫分表很明顯只是剛剛開始。接下去分佈式鎖,數據遷移等分庫分表的相關問題都會蜂擁而至。接下去一點點記錄吧!

未完,待續。。。如有問題,歡迎一塊兒討論,一塊兒學習進步!

相關文章
相關標籤/搜索