前言

前面我们学习的分库分表架构,还有一种常用架构是主从架构,两者区别如下:

主从架构:读写分离,目的是高可用、读写扩展。主从库内容相同,根据SQL语义进行路由,具体就是 select语句走从库,增删改语句走主库。

分库分表架构:数据分片,目的读写扩展、存储扩容。库和表内容不同,根据分片配置进行路由。

下面我们来进行主从架构的配置。

准备数据

city表的sql:

1
2
3
4
5
6
CREATE TABLE `city` (
`Id` bigint(11) NOT NULL AUTO_INCREMENT,
`name` varchar(256) DEFAULT NULL,
`province` varchar(256) DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

两个数据库lagou1,lagou2。

将lagou1当做主库,lagou2当做从库。

需要配置主从复制,我们这里只是需要演示shardingjdbc对读写分离的支持,我们只需验证写入操作对主库表进行操作,而读取操作时对于从库中的表即可,所以可暂时不配置mysql层面的读写分离。如果有同学想配置的话,可参考 mysql主从复制配置文章

代码及配置

具体的实体类及JPA操作相关代码在此不赘述(可参见文末源代码)。

配置文件:

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  @Test
public void testAdd(){
City city = new City();
city.setName("shanghai");
city.setProvince("shanghai");
cityRepository.save(city);
}

@Test
public void testFind(){
List<City> list = cityRepository.findAll();
list.forEach(city->{
System.out.println(city.getId()+" "+city.getName()+" "+city.getProvince());
});
}

执行testAdd()方法添加一条记录,查看数据库中表如下:

执行testFind()方法,结果如下:

可以看到,写操作走的是主库,读操作走的是从库。

附录

读写分离的应用方案

读写分离:

分表+读写分离

在数据量达到500万的时候,这时数据量预估千万级别,我们可以将数据进行分表存储。

分库分表+读写分离

在数据量继续扩大,这时可以考虑分库分表,将数据存储在不同数据库的不同表中,如下:

ShardingJdbc对于主库、从库、主从同步、负载均衡的支持如下:

核心功能

  • 提供一主多从的读写分离配置。仅支持单主库,可以支持独立使用,也可以配合分库分表使用

  • 独立使用读写分离,支持SQL透传。不需要SQL改写流程

  • 同一线程且同一数据库连接内,能保证数据一致性。如果有写入操作,后续的读操作均从主 库读取。

  • 基于Hint的强制主库路由。可以强制路由走主库查询实时数据,避免主从同步数据延迟。

不支持项

  • 主库和从库的数据同步
  • 主库和从库的数据同步延迟
  • 主库双写或多写
  • 跨主库和从库之间的事务的数据不一致。建议在主从架构中,事务中的读写均用主库操作

源码

sharding-jdbc读写分离demo