前面我们使用sharding-jdbc配置了分库分表。sharding-jdbc还有个用法,就是实现读写分离。
什么时候需要或者可以使用读写分离?
当我们的项目所使用的数据库查询的访问量,访问频率,及访问的并发量远大于修改的时候,我们需要将访问数据库的方式读写分离。比如我们使用的微博,更多人都只是刷一刷,发布微博动态的次数还是远小于我们刷微博的次数的。
sharding-jdbc
sharding-jdbc较于MyCat,我认为最大的优势是:sharding-jdbc是轻量级的第三方工具,我们只需要在项目中引用指定的jar包即可,然后根据项目的业务需要配置分库分表或者读写分离的规则和方式。
我们开始实现读写分离:
一. 先准备好数据库
我们在自己本地新建三个一毛一样的数据库database0,database1,database2.然后这三个数据库里各建一张user表:
CREATE TABLE `user` ( `id` bigint(64) NOT NULL AUTO_INCREMENT, `city` varchar(20) NOT NULL, `name` varchar(20) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=102 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES ('100', 'beijing', 'dalaoyang');---database0数据 INSERT INTO `user` VALUES ('101', 'beijing', 'dalaoyang');---database0数据
INSERT INTO `user` VALUES ('101', 'beijing', 'dalaoyang');---database1数据
INSERT INTO `user` VALUES ('101', 'beijing', 'dalaoyang');---database2数据
因为是例子,我们三个database就放在同一台电脑的同一个数据库中了。实际情况下,使用到sharding-jdbc来做读写分离的话,一定是拥有海量数据的项目,一般会又多台数据库服务器。因为这些服务器需要实现数据同步。关于数据同步,后面再说。
二. 新建springboot项目吧
1.pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dalaoyang</groupId> <artifactId>springboot2_shardingjdbc_dxfl</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot2_shardingjdbc_dxfl</name> <description>springboot2_shardingjdbc_dxfl</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.shardingjdbc</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>2.0.0.M3</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.3</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
这里主要是加上sharding-jdbc-spring-boot-starter的启动器,注意版本就好。
这里插上一句,很多人都说现在的程序员必须要会,并且使用springboot,除了springboot自身的各种优势和便利意外,你会发现,很多优秀的第三方工具都自觉加入了springboot的怀抱,springboot要使用这些第三方工具包的时候,只需要在pom文件中注入对应的依赖就可。除了这个sharding-jdbc,还有比如,redis,solr,mybatis,kafka,elasticsearch等等等等,很多很多。
用起来就一个字“爽的呀批”;
2.application.yml
server: port: 8084 sharding: jdbc: datasource: names: ds0,ds1,ds2 ds0: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/database0 username: root password: 1234 ds1: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/database1 username: root password: 1234 ds2: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/database2 username: root password: 1234 config: sharding: props: sql.show: true masterslave: load-balance-algorithm-type: round_robin name: dataSource master-data-source-name: ds0 slave-data-source-names: ds1,ds2
配置三个数据源,然后主数据库为ds0,从数据库为ds1和ds2.
主数据库是修改操作使用的,从数据库是查询使用的。这是默认的。
然后从数据库的配置规则是轮询(round_robin),配置规则还有一个:随机(random)
3.访问接口提供下
@RestController public class UserController { @Autowired private UserMapper userMapper; @GetMapping("save") public void save(){ User user = new User(); user.setName("dalaoyang"); user.setCity("beijing"); userMapper.insertSelective(user); } @GetMapping("getAll") public Object getAll(){ return userMapper.selectAll(); } }
其他的启动类啊,service,mapper之类的就写了,没啥特别的。详细的下载代码。
测试
启动项目,多次访问localhost:8084/getAll。
得到的数据为:
[{"id":10001,"city":"beijing","name":"dalaoyang1"}]和[{"id":10002,"city":"beijing","name":"dalaoyang2"}]
轮番出现,这就说明数据库ds1和ds2被轮询访问。
再多次访问localhost:8084/save
看数据库,你会发现插入的数据都保存在ds0中。
那么这时可以说,我们实现了读写分离。
代码下载地址:https://gitee.com/fengyuduke/my_open_resources/blob/master/springboot2_shardingjdbc_dxfl.zip