前面我們使用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