概述
一主多从,读写分离,主动同步,是一种常见的数据库架构优化手段。
一般来说当你的应用是读多写少,数据库扛不住读压力的时候,采用读写分离,通过增加从库数量可以线性提升系统读性能。
主库,提供数据库写服务;从库,提供数据库读能力;主从之间,通过binlog同步数据。
主要是用于解决 “数据库读性能问题”。
项目案例
读写分离
1.导入sharding-jdbc依赖
<dependency>
<groupId>io.shardingjdbc</groupId>
<artifactId>sharding-jdbc-core</artifactId>
<version>2.0.3</version>
</dependency>
2.配置主从数据源和读写分离规则
sharding-jdbc会自动的根据DML和DQL语句类型连接主或者从数据源
#shardingjdbc配置
sharding:
jdbc:
data-sources:
# 主数据库配置
ds_master:
jdbc-url: jdbc:mysql://127.0.0.1:3306/ds1database?useUnicode=true&characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
# 配置第一个从数据库
ds_slave_0:
jdbc-url: jdbc:mysql://127.0.0.1:3306/ds2database?useUnicode=true&characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
# 配置读写分离
master-slave-rule:
# 配置从库选择策略,提供轮询与随机,这里选择用轮询
load-balance-algorithm-type: round_robin
# 指定主数据库
master-data-source-name: ds_master
# 指定从数据库
slave-data-source-names: ds_slave_0
# 读写分离名称,随便起。
name: ds_ms
3.配置类绑定配置文件属性
@Data
@ConfigurationProperties(prefix = "sharding.jdbc")
public class ShardingMasterSlaveConfig {
// 绑定主从数据源
private Map<String, HikariDataSource> dataSources = new HashMap<>();
// 绑定读写分离规则
private MasterSlaveRuleConfiguration masterSlaveRule;
}
4.配置类设置主从数据源和分离规则到DataSource
@Configuration
@EnableConfigurationProperties(ShardingMasterSlaveConfig.class)
@Slf4j
@ConditionalOnProperty({
"sharding.jdbc.data-sources.ds_master.jdbc-url",
"sharding.jdbc.master-slave-rule.master-data-source-name"
})
public class ShardingDataSourceConfig {
@Autowired
private ShardingMasterSlaveConfig shardingMasterSlaveConfig;
@Bean
public DataSource masterSlaveDataSource() throws SQLException {
final Map<String, DataSource> dataSourceMap = Maps.newHashMap();
dataSourceMap.putAll(shardingMasterSlaveConfig.getDataSources());
MasterSlaveRuleConfiguration masterSlaveRule = shardingMasterSlaveConfig.getMasterSlaveRule();
final Map<String, Object> newHashMap = Maps.newHashMap();
// 设置主从数据源和分离规则到DataSource
DataSource dataSource = MasterSlaveDataSourceFactory.createDataSource(dataSourceMap,
masterSlaveRule, newHashMap);
log.info("masterSlaveDataSource config complete");
return dataSource;
}
}
主从同步
sharding-jdbc 本身并不直接提供主从同步的功能。主从同步通常是由数据库层面来保障的,比如 MySQL 的主从复制功能。在使用 sharding-jdbc 进行读写分离时,你需要确保你的主库和从库之间的数据是同步的
以 MySQL 为例,主从同步的大致流程如下:
- 配置主库(Master):在主库上启用二进制日志(binary log),这样主库上的所有更改(如 INSERT、UPDATE、DELETE 操作)都会被记录到这个日志中。
- 配置从库(Slave):在从库上配置连接到主库,并指定从哪个二进制日志的位置开始复制数据。从库会连接到主库,并请求发送二进制日志的内容。
- 复制数据:主库将二进制日志的内容发送给从库,从库接收并解析这些日志,然后执行相应的 SQL 语句,从而保持与主库的数据同步。
- 持续同步:从库会持续地监听主库的二进制日志变化,并实时地应用这些变化,确保数据的实时同步。
在使用 sharding-jdbc 进行读写分离时,你需要:
- 配置好数据库的主从复制。
- 在 sharding-jdbc 的配置中,指定哪些数据源是主库,哪些是从库。
- 确保你的应用按照预期的方式使用主库和从库。通常,写操作(如 INSERT、UPDATE、DELETE)会路由到主库,而读操作(如 SELECT)会路由到从库。
需要注意的是,虽然主从复制可以提供数据的冗余和备份,但它并不是一种高可用性解决方案。例如,如果主库出现故障,从库虽然可以提供读服务,但写服务将不可用。为了解决这个问题,你可能需要考虑更复杂的方案,如 MySQL 的 Group Replication 或其他数据库的高可用解决方案。