通常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/數據庫
如上文全部,每一個項目都須要依賴相關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>
因爲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,可是分庫分表很明顯只是剛剛開始。接下去分佈式鎖,數據遷移等分庫分表的相關問題都會蜂擁而至。接下去一點點記錄吧!
未完,待續。。。如有問題,歡迎一塊兒討論,一塊兒學習進步!