分布式读写分离和分库分表采用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实现分佈式读写分离和分库分表的实现的更多相关文章

  1. mycat+mysql集群:实现读写分离,分库分表

    1.mycat文档:https://github.com/MyCATApache/Mycat-doc       官方网站:http://www.mycat.org.cn/ 2.mycat的优点: 配 ...

  2. Mycat数据库中间件对Mysql读写分离和分库分表配置

    Mycat是一个开源的分布式数据库系统,不同于oracle和mysql,Mycat并没有存储引擎,但是Mycat实现了mysql协议,前段用户可以把它当做一个Proxy.其核心功能是分表分库,即将一个 ...

  3. MyCat读写分离、分库分表

    系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...

  4. Mycat实现读写分离、分库分表

    系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...

  5. sharding demo 读写分离 U (分库分表 & 不分库只分表)

    application-sharding.yml sharding: jdbc: datasource: names: ds0,ds1,dsx,dsy ds0: type: com.zaxxer.hi ...

  6. sharing-jdbc实现读写分离及分库分表

    需求: 分库:按业务线business_id将不同业务线的订单存储在不同的数据库上: 分表:按user_id字段将不同用户的订单存储在不同的表上,为方便直接用非分片字段order_id查询,可使用基因 ...

  7. Mysql之Mycat读写分离及分库分表

    ## 什么是mycat ```basic 1.一个彻底开源的,面向企业应用开发的大数据库集群 2.支持事务.ACID.可以替代MySQL的加强版数据库 3.一个可以视为MySQL集群的企业级数据库,用 ...

  8. Ameba读写分离_mycat分库分表_redis缓存

    1 数据库的读写分离 1.1 Amoeba实现读写分离 1.1.1 定义 Amoeba是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy 优点: 配置读写分离时较为简单.配置 ...

  9. mysql主从读写分离,分库分表

    1.分表 当项目上线后,数据将会几何级的增长,当数据很多的时候,读取性能将会下降,更新表数据的时候也需要更新索引,所以我们需要分表,当数据量再大的时候就需要分库了. a.水平拆分:数据分成多个表 b. ...

随机推荐

  1. 微信小程序-框架详解(1)

    配置 -app.json文件对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.tab等 { "pages": [ //决定页面文件的路径 "pag ...

  2. Java数组的复制全解

    1.将一个基本数据类型数组的引用赋值给另一个数组 public class Array_copy { int[] array1=new int[]{1,2,3,4,5,6}; int[] array2 ...

  3. Python 处理时间的模块

    1.由日期格式转化为字符串格式的函数为: datetime.datetime.strftime().date() 2.由字符串格式转化为日期格式的函数为: datetime.datetime.strp ...

  4. [CVPR2017] Deep Self-Taught Learning for Weakly Supervised Object Localization 论文笔记

    http://openaccess.thecvf.com/content_cvpr_2017/papers/Jie_Deep_Self-Taught_Learning_CVPR_2017_paper. ...

  5. 进阶-JMS 知识梳理

    JMS 一. 概述与介绍 ActiveMQ 是Apache出品,最流行的.功能强大的即时通讯和集成模式的开源服务器.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Pro ...

  6. MYSQL使用方法

    显示所有数据库:show databases; 创建数据库:create database 数据库名; 删除数据库:drop database 数据库名:   查看表结构: describe(desc ...

  7. MySQL 的性能(下篇)—— 性能优化方法

    简介 文中内容均为阅读前辈的文章所整理而来,参考文章已在最后全指明 本文分为上下两篇: 上篇:MySQL 的 SQL 执行分析 下篇:MySQL 性能优化 下面为下篇内容,分为以下部分: 一.创建表时 ...

  8. WARN: Establishing SSL connection without server's identity verification is not recommended

    0.要想用Java连接mysql数据库,首先装好JDK,配置好环境变量,将jdk*.*.*\lib放入classpath,将jdk*.*.*\bin放入path中(*.*.*表示版本号):其次安装好m ...

  9. XSS(笔记1)

    概念 跨站脚本(Cross-Site Scripting,XSS) 发生在目标网站中目标用户的浏览器层面上,当用户浏览器渲染整个HTML文档的过程中出现了不被预期的脚本指令并执行时,XSS就会发生.为 ...

  10. 写完批处理脚本,再写个Gradle脚本,解放双手

    前言 上一篇写个批处理来帮忙干活---遍历&字符串处理中,我们已经学习如何写批处理脚本来帮我们做一些简单的重复性工作,本篇继续来学习如何用 Gradle 写脚本,让它也来帮我们干活 Gradl ...