Hint路由介绍
在一些应用场景中,分片条件并不存在于SQL,而存在于外部业务逻辑。因此需要提供一种通过在外部业务代码中指定路由配置的一种方式,在ShardingSphere中叫做Hint。如果使用Hint指定了强制分片路由,那么SQL将会无视原有的分片逻辑,直接路由至指定的数据节点操作。
HintManager
主要使用ThreadLocal
管理分片键信息,进行hint强制路由。在代码中向HintManager
添加的配置信息只能在当前线程内有效。
Hint使用场景:
- 数据分片操作,如果分片键没有在SQL或数据表中,而是在业务逻辑代码中
- 读写分离操作,如果强制在主库进行某些数据操作
Hint路由实战
我们的实战基于博文MySQL之Sharding-JDBC数据分片中的实战案例。
创建自定义路由规则类:
package com.rubin.shardingjdbcdemo.hint;
import org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.hint.HintShardingValue;
import java.util.ArrayList;
import java.util.Collection;
public class RubinHintShardingAlgorithm implements HintShardingAlgorithm<Long> {
@Override
public Collection<String> doSharding(Collection<String> collection, HintShardingValue<Long> hintShardingValue) {
Collection<String> result = new ArrayList<>();
for (String each : collection){
for (Long value : hintShardingValue.getValues()){
if(each.endsWith(String.valueOf(value % 2))){
result.add(each);
}
}
}
return result;
}
}
我们在sharding-jdbc-demo项目中新建配置文件application-hint-database.properties:
# datasource
spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://127.0.0.1:3306/rubin_shard_1?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://127.0.0.1:3306/rubin_shard_2?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# hint
spring.shardingsphere.sharding.tables.city.database-strategy.hint.algorithm-class-name=com.rubin.shardingjdbcdemo.hint.RubinHintShardingAlgorithm
修改配置文件application.properties中的profile:
#spring.profiles.active=sharding-database
#spring.profiles.active=master-slave
spring.profiles.active=hint-database
spring.shardingsphere.props.sql.show=true
创建测试类:
package com.rubin.shardingjdbcdemo;
import com.rubin.shardingjdbcdemo.entity.City;
import com.rubin.shardingjdbcdemo.repository.CityRepository;
import org.apache.shardingsphere.api.hint.HintManager;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@SpringBootTest(classes = ShardingJdbcDemoApplication.class)
@RunWith(SpringRunner.class)
public class TestHintAlgorithm {
@Autowired
private CityRepository cityRepository;
@Test
public void test1() {
HintManager hintManager = HintManager.getInstance();
hintManager.setDatabaseShardingValue(1L); //强制路由到ds${xx%2}
List<City> list = cityRepository.findAll();
list.forEach(city -> {
System.out.println(city.getId() + " " + city.getName() + " " + city.getProvince());
});
}
}
通过修改 hintManager.setDatabaseShardingValue(1L); 的值,我们会发现始终会路由到ds${shardingValue%2}
的数据源上,达到了强制指定路由的目的。
以上就是本博文的全部内容,欢迎小伙伴们积极留言交流~~~
文章评论