分库分表之ShardingSphere读写分离源码分析

1. 问题

读写分离如何执行

2. 源码

ShardingMasterSlaveRouter为核心入口

 

public SQLRouteResult route(SQLRouteResult sqlRouteResult) {
    Iterator var2 = this.masterSlaveRules.iterator();

    while(var2.hasNext()) {
        MasterSlaveRule each = (MasterSlaveRule)var2.next();
        // 开始路由
        this.route(each, sqlRouteResult);
    }

    return sqlRouteResult;
}
private void route(MasterSlaveRule masterSlaveRule, SQLRouteResult sqlRouteResult) {
    Collection<RoutingUnit> toBeRemoved = new LinkedList();
    Collection<RoutingUnit> toBeAdded = new LinkedList();
    Iterator var5 = sqlRouteResult.getRoutingResult().getRoutingUnits().iterator();

    while(var5.hasNext()) {
        RoutingUnit each = (RoutingUnit)var5.next();
        if (masterSlaveRule.getName().equalsIgnoreCase(each.getDataSourceName())) {
            toBeRemoved.add(each);
            String actualDataSourceName;
            // 判断是否走主库
            if (this.isMasterRoute(sqlRouteResult.getSqlStatementContext().getSqlStatement())) {
                MasterVisitedManager.setMasterVisited();
                actualDataSourceName = masterSlaveRule.getMasterDataSourceName();
            } else {
            //  从库如果有多个,默认是轮询,也可以选择随机访问策略
                actualDataSourceName = masterSlaveRule.getLoadBalanceAlgorithm().getDataSource(masterSlaveRule.getName(), masterSlaveRule.getMasterDataSourceName(), new ArrayList(masterSlaveRule.getSlaveDataSourceNames()));
            }

            toBeAdded.add(this.createNewRoutingUnit(actualDataSourceName, each));
        }
    }

    sqlRouteResult.getRoutingResult().getRoutingUnits().removeAll(toBeRemoved);
    sqlRouteResult.getRoutingResult().getRoutingUnits().addAll(toBeAdded);
} 

判断是否走主库,包括hint和非查询操作等 

private boolean isMasterRoute(SQLStatement sqlStatement) {
    return this.containsLockSegment(sqlStatement) || !(sqlStatement instanceof SelectStatement) || MasterVisitedManager.isMasterVisited() || HintManager.isMasterRouteOnly();
}

// HintManager可以设置强制走主库,或者非查询操作走主库

 

 

RoundRobinMasterSlaveLoadBalanceAlgorithm类执行轮询查询从库策略
// 轮询访问从库
@Override
public String getDataSource(final String name, final String masterDataSourceName, final List<String> slaveDataSourceNames) {
    AtomicInteger count = COUNTS.containsKey(name) ? COUNTS.get(name) : new AtomicInteger(0);
    COUNTS.putIfAbsent(name, count);
    count.compareAndSet(slaveDataSourceNames.size(), 0);
    // 计数器来实现轮询
    return slaveDataSourceNames.get(Math.abs(count.getAndIncrement()) % slaveDataSourceNames.size());
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值