spring boot sharding-jdbc实现分佈式读写分离和分库分表的实现
分布式读写分离和分库分表采用sharding-jdbc实现。
sharding-jdbc是当当网推出的一款读写分离实现插件,其他的还有mycat,或者纯粹的Aop代码控制实现。
接下面用spring boot 2.1.4 release 版本实现读写分离。
1. 引入jar包
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.9</version>
</dependency>
<!-- sharding-jdbc -->
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>1.5.4</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> 2. 添加配置文件
分别添加三份,配置为database0,database1,database2。
3. 添加DataSourceConfig
package com.fintecher.cn.elasticjobdemo.config; import com.dangdang.ddframe.rdb.sharding.api.ShardingDataSourceFactory;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
import com.dangdang.ddframe.rdb.sharding.api.strategy.database.DatabaseShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;
import com.dangdang.ddframe.rdb.sharding.keygen.DefaultKeyGenerator;
import com.dangdang.ddframe.rdb.sharding.keygen.KeyGenerator;
import com.fintecher.cn.elasticjobdemo.service.DatabaseShardingAlgorithm;
import com.fintecher.cn.elasticjobdemo.service.TableShardingAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DataSourceConfig { @Autowired
private Database1Config database1Config; @Autowired
private Database2Config database2Config; @Autowired
private DatabaseShardingAlgorithm databaseShardingAlgorithm; @Autowired
private TableShardingAlgorithm tableShardingAlgorithm; @Bean
public DataSource getDataSource() throws SQLException {
return buildDataSource();
} private DataSource buildDataSource() throws SQLException {
//设置从库数据源集合
Map<String, DataSource> slaveDataSourceMap = new HashMap<>();
slaveDataSourceMap.put(database1Config.getDatabaseName(), database1Config.createDataSource());
slaveDataSourceMap.put(database2Config.getDatabaseName(), database2Config.createDataSource()); //设置默认数据库
DataSourceRule dataSourceRule = new DataSourceRule(slaveDataSourceMap, database1Config.getDatabaseName()); //分表设置
TableRule orderTableRules = TableRule.builder("user").actualTables(Arrays.asList("user_0", "user_1")).dataSourceRule(dataSourceRule).build(); //分库分表策略
ShardingRule shardingRule = ShardingRule.builder()
.dataSourceRule(dataSourceRule)
.tableRules(Arrays.asList(orderTableRules))
.databaseShardingStrategy(new DatabaseShardingStrategy("id", databaseShardingAlgorithm))
.tableShardingStrategy(new TableShardingStrategy("name", tableShardingAlgorithm))
.build(); //获取数据源对象
// DataSource dataSource = MasterSlaveDataSourceFactory.createDataSource("masterSlave", database0Config.getDatabaseName()
// , database0Config.createDataSource(), slaveDataSourceMap, MasterSlaveLoadBalanceStrategyType.getDefaultStrategyType()); DataSource dataSource = ShardingDataSourceFactory.createDataSource(shardingRule); return dataSource;
} @Bean
public KeyGenerator keyGenerator() {
return new DefaultKeyGenerator();
} }
4. 分库实现方案
@Component
public class DatabaseShardingAlgorithm implements SingleKeyDatabaseShardingAlgorithm<Long> { @Autowired
private Database2Config database2Config; @Autowired
private Database1Config database1Config; @Override
public String doEqualSharding(Collection<String> collection, ShardingValue<Long> shardingValue) {
Long value = shardingValue.getValue();
if (value <= 20L)
return database1Config.getDatabaseName();
else
return database2Config.getDatabaseName();
} @Override
public Collection<String> doInSharding(Collection<String> collection, ShardingValue<Long> shardingValue) {
return null;
} @Override
public Collection<String> doBetweenSharding(Collection<String> collection, ShardingValue<Long> shardingValue) {
return null;
} } 5. 分表实现方案
@Component
public class TableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<String> { @Override
public String doEqualSharding(Collection<String> tableNames, ShardingValue<String> shardingValue) {
for (String each : tableNames) {
if (each.endsWith("0") && shardingValue.getValue().contains("军")) {
return "user_0";
} else
return "user_1";
}
return null;
} @Override
public Collection<String> doInSharding(Collection<String> collection, ShardingValue<String> shardingValue) {
return null;
} @Override
public Collection<String> doBetweenSharding(Collection<String> collection, ShardingValue<String> shardingValue) {
return null;
} }
5. 环境参数配置
#jpa 配置
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=none
##数据库database0配置
database0.url=jdbc:mysql://192.168.3.32:3306/database0?characterEncoding=utf8&useSSL=false
database0.username=root
database0.password=123456
database0.driverClassName=com.mysql.jdbc.Driver
database0.databaseName=database0
##数据库database1地址
database1.url=jdbc:mysql://192.168.3.32:3306/database1?characterEncoding=utf8&useSSL=false
database1.username=root
database1.password=123456
database1.driverClassName=com.mysql.jdbc.Driver
database1.databaseName=database1
##数据库database2地址
database2.url=jdbc:mysql://192.168.3.32:3306/database2?characterEncoding=utf8&useSSL=false
database2.username=root
database2.password=123456
database2.driverClassName=com.mysql.jdbc.Driver
database2.databaseName=database2
6. 测试
7. 达到的效果
插入40条数据,20条在base1,20条在base2,base1中张军的数据在user_0,李四的数据在user_1
8. 问题总结:
在写代码的过程中自己引包的时候很随便,引入了一些其他的包,如下:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.18.RELEASE</version>
</dependency>
导致在起服务的时候报 :
解决方案:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
将上面三个包换成这两个即可。
9. 总结
在使用sharding-jdbc过程中实现了
SingleKeyDatabaseShardingAlgorithm 这个接口,这个接口有三个方法 equal,in ,between ,这三个方法的作用是在比较传送过来的值的时候分别用这三种方案进行比较。 10. 遗留问题,当把数据库分库分表存后,查询怎么获取到所有的数据呢。 11. 参考文档:https://yq.aliyun.com/articles/690021https://www.dalaoyang.cn/article/95?spm=a2c4e.11153940.blogcont690021.12.2057195fd9jYc312. 获取数据解决方案:
1. 广发复制法, 比如主表 Personal表,分别存在于多个数据库,关联表 persona_address, 只存在于主服务数据库,这种方式就是在修改了persona_address表之后将这张表再复制一份到从数据库,这样查询的时候从从数据库关联后再汇总查询。
2. 从数据库实时同步主数据库,从主数据库查询。
spring boot sharding-jdbc实现分佈式读写分离和分库分表的实现的更多相关文章
- mycat+mysql集群:实现读写分离,分库分表
1.mycat文档:https://github.com/MyCATApache/Mycat-doc 官方网站:http://www.mycat.org.cn/ 2.mycat的优点: 配 ...
- Mycat数据库中间件对Mysql读写分离和分库分表配置
Mycat是一个开源的分布式数据库系统,不同于oracle和mysql,Mycat并没有存储引擎,但是Mycat实现了mysql协议,前段用户可以把它当做一个Proxy.其核心功能是分表分库,即将一个 ...
- MyCat读写分离、分库分表
系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...
- Mycat实现读写分离、分库分表
系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...
- sharding demo 读写分离 U (分库分表 & 不分库只分表)
application-sharding.yml sharding: jdbc: datasource: names: ds0,ds1,dsx,dsy ds0: type: com.zaxxer.hi ...
- sharing-jdbc实现读写分离及分库分表
需求: 分库:按业务线business_id将不同业务线的订单存储在不同的数据库上: 分表:按user_id字段将不同用户的订单存储在不同的表上,为方便直接用非分片字段order_id查询,可使用基因 ...
- Mysql之Mycat读写分离及分库分表
## 什么是mycat ```basic 1.一个彻底开源的,面向企业应用开发的大数据库集群 2.支持事务.ACID.可以替代MySQL的加强版数据库 3.一个可以视为MySQL集群的企业级数据库,用 ...
- Ameba读写分离_mycat分库分表_redis缓存
1 数据库的读写分离 1.1 Amoeba实现读写分离 1.1.1 定义 Amoeba是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy 优点: 配置读写分离时较为简单.配置 ...
- mysql主从读写分离,分库分表
1.分表 当项目上线后,数据将会几何级的增长,当数据很多的时候,读取性能将会下降,更新表数据的时候也需要更新索引,所以我们需要分表,当数据量再大的时候就需要分库了. a.水平拆分:数据分成多个表 b. ...
随机推荐
- IE条件注释,为IE单独写js
<!--[if IE ]> <body class="ie"> <![endif]--> <!--[if !IE]>--> & ...
- Flask入门之上传文件到服务器
今天要做一个简单的页面,可以实现将文件 上传到服务器(保存在指定文件夹) #Sample.py # coding:utf-8 from flask import Flask,render_templa ...
- pandas用法小结
前言 个人感觉网上对pandas的总结感觉不够详尽细致,在这里我对pandas做个相对细致的小结吧,在数据分析与人工智能方面会有所涉及到的东西在这里都说说吧,也是对自己学习的一种小结! pandas用 ...
- 压力测试工具ab - Apache HTTP server benchmarking tool
搞互联网开发,压力测试必不可少.压力测试的工具很多,我用过ab和JMeter,今天主要讲ab的用法. 1.ab是什么 ab is a tool for benchmarking your Apache ...
- Python_字符串的大小写变换
''' lower().upper().capitalize().title().swapcase() 这几个方法分别用来将字符串转换为小写.大写字符串.将字符串首字母变为大写.将每个首字母变为大写以 ...
- 第六章之S5PV210正确启动u-boot
1,根据上一章最后一步生成u-boot写入到板子上,生成如下代码 UARU 0x43110220 DDR IS OK! 0x12345678 0xEA000014 U-Boot - ::) CPU: ...
- Switch在swift中的使用
switch的简单使用: 相比 C 和 objective - C 中的 switch 语句,Swift 中的 switch 语句不会默认的掉落到每个 case 的下面进入 另一个 case.相反,第 ...
- Oracle-09:聚合函数
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 数据库脚本放一下,供测试使用 create table DEPT ( deptno ) not null, d ...
- 【原】用Java编写第一个区块链(一)
写这篇随笔主要是尝试帮助自己了解如何学习区块链技术开发. [本文禁止任何形式的全文粘贴式转载,本文来自 zacky31 的随笔] 目标: 创建一个最基本的"区块链" 实现一个简单的 ...
- React Native在特赞的应用与实践
基于React技术栈构建开发前端项目,并使用React Native开发特赞移动APP 目前正在使用Node.js开发和维护特赞服务网关,希望Node.js能够在更轻量级的微服务架构中发挥重要作用 课 ...