ShardingJDBC是什么
看一看ChatGPT对他的解释:
ShardingJDBC是一个数据库连接池,它为数据库的分片和读/写拆分提供支持。它允许您跨多个物理数据库和服务器分发数据,并根据设置的配置将读写操作路由到适当的数据库。
以下是它的工作原理:
1、您可以使用数据库服务器列表配置数据库集群,并指定哪些服务器应用于读写操作。
2、将应用程序配置为使用ShardingJDBC作为连接池。
3、当应用程序需要执行数据库操作时,它会从ShardingJDBC请求连接。
ShardingJDBC根据您设置的配置将请求路由到适当的数据库服务器。如果请求是读取操作,则将其路由到指定用于读取操作的数据库服务器。如果请求是写操作,则将其路由到指定用于写操作的数据库服务器。
这有助于通过将负载分布到多个服务器并将读写操作路由到最合适的服务器来提高数据库集群的性能和可扩展性。
依赖
<!--sharding-jdbc依赖-->
<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version>
</dependency>
数据源配置
在application.properties文件中定义数据源
#配置多个数据源
spring.shardingsphere.datasource.names=m1,m2,m3
#数据源1
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://115.29.197.4:3306/course1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root
#数据源2
spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://115.29.197.5:3306/course2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=root
#数据源3
spring.shardingsphere.datasource.m3.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m3.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m3.url=jdbc:mysql://115.29.197.6:3306/course2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m3.username=root
spring.shardingsphere.datasource.m3.password=root
# 指定主库和从库
# 采用静态读写分离规则
spring.shardingsphere.rules.readwrite-spliting.data-sources.readwrite-ds.type=Static
# 指定主库
spring.shardingsphere.rules.readwrite-spliting.data-sources.readwrite-ds.props.write-data-source-name=m1
# 指定从库,多个从库用逗号分割
spring.shardingsphere.rules.readwrite-spliting.data-sources.readwrite-ds.props.read-data-source-name=m2,m3
# 因为从服务器有两台,为了避免老是从一台从服务器薅羊毛,应该配置负载均衡策略
# 指定负载均衡名字
spring.shardingsphere.rules.readwrite-spliting.data-sources.readwrite-ds.load-balancer-name=lbs
# 配置负载lbs,下面是按权重负载,负载均衡策略还有RANDOM随机、ROUND_ROBIN轮询
spring.shardingsphere.rules.readwrite-spliting.load-balancers.lbs.type=WEIGHT
# m2数据库负载90%
spring.shardingsphere.rules.readwrite-spliting.load-balancers.lbs.props.m2=90# m3数据库负载10%
spring.shardingsphere.rules.readwrite-spliting.load-balancers.lbs.props.m3=10
# 路由过程打印到控制台方便调试spring.shardingsphere.props.sql-show=true
刚写的数据由于网络延迟导致读数据不一致
有时候可能会遇到执行完写操作后,立刻去读发现读不到或者读到旧状态的尴尬场景。这是由于主从同步可能存在延迟,在主节点执行完写操作,再去从节点执行读操作,读取了之前旧的状态。
解决方案:
1、强制走主库
如果你需要读取最新的数据,最好直接读主库的数据。使用下面两行代码会让sql直接走主库。
2、全同步复制(MGR)
也就是说主从同步的时候会阻塞你查询这个数据的操作,等同步完成之后才给你返回。
MGR要求:
1、引擎必须为 innodb,因为需事务支持在 commit 时对各节点进行冲突检查
2、每个表必须有主键,在进行事务冲突检测时需要利用主键值对比
3、必须开启 binlog 且为 row 格式
4、开启 GTID,且主从状态信息存于表中(–master-info-repository=TABLE 、–relay-log-info-repository=TABLE)–log-slave-updates 打开
5、一致性检测设置 --transaction-write-set-extraction=XXHASH64
MGR使用限制:
1、和普通复制 binlog 校验不能共存,需设置 --binlog-checksum=none
2、不支持 gap lock(间隙锁)隔离级别需设置为 read_committed
3、不支持对表进行锁操作(lock/unlock table)不会发送到其他节点执行,影响需要对表进行加锁操作的情况,列入 mysqldump 全表备份恢复操作
4、不支持 serializable(序列化)隔离级别
5、DDL 语句不支持原子性,不能检测冲突,执行后需自行校验是否一致
6、多主模式下不支持外键,单主模式不存在此问题
7、最多支持 9 个节点,超过 9 台 server 无法加入组