强制路由剖析
在一些应用场景中,分片条件并不存在于SQL,而存在于外部业务逻辑。因此需要提供一种通过在外部业务代码中指定路由配置的一种方式,在ShardingSphere中叫做Hint。如果使用Hint指定了强制分片路由,那么SQL将会无视原有的分片逻辑,直接路由至指定的数据节点操作。
HintManager主要使用ThreadLocal管理分片键信息,进行hint强制路由。在代码中向HintManager添加的配置信息只能在当前线程内有效。
Hint使用场景:
- 数据分片操作,分片键没有在SQL或数据表中,而是在业务逻辑代码中
- 读写分离操作,强制在主库进行某些数据操作
Hitt使用过程:
-
编写分库或分表路由策略,实现HintShardingAlgorithm接口
public class MyHintShardingAlgorithm implements HintShardingAlgorithm<Integer> { @Override public Collection<String> doSharding(Collection<String> collection, HintShardingValue<Integer> hintShardingValue) { //添加分库或分表路由逻辑 } }
-
在配置文件指定分库或分表策略
#强制路由库和表 spring.shardingsphere.sharding.tables.b_order.database- strategy.hint.algorithm-class-name=com.lagou.hint.MyHintShardingAlgorithm spring.shardingsphere.sharding.tables.b_order.table-strategy.hint.algorithm- class-name=com.lagou.hint.MyHintShardingAlgorithm spring.shardingsphere.sharding.tables.b_order.actual-data-nodes=ds$-> {0..1}.b_order$->{0..1}
-
在代码执行查询前使用HintManager指定执行策略值
@Test//路由库和表 public void test(){ HintManager hintManager = HintManager.getInstance(); hintManager.addDatabaseShardingValue("b_order",1); hintManager.addTableShardingValue("b_order",1); List<Order> list = orderRepository.findAll(); hintManager.close(); list.forEach(o -> { System.out.println(o.getOrderId()+" "+o.getUserId()+" "+o.getOrderPrice()); }); }
在读写分离结构中,为了避免主从同步数据延迟及时获取刚添加或更新的数据,可以采用强制路由走主库查询实时数据,使用
hintManager.setMasterRouteOnly
设置主库路由即可。