Sharding-jdbc中的很多地方涉及到算法,比如主从配置这块、分库分表这块。本文主要从源码角度介绍下,目前主要包含哪些算法,以及这些算法的内容。
这块的代码主要在core模块中的api/algorithm/masterslave下面,这块的算法的主要目的,其实是在读的时候,如何选择从数据库。按照常规的理解,可以有以下几种(参考dubbo):
目前在sharding-jdbc中,实现了前两种,我们看下是如何实现的。
首先是一个接口,定义了获取slave的方法,即:
- public interface MasterSlaveLoadBalanceAlgorithm {
- /**
- * Get data source.
- *
- * @param name master-slave logic data source name
- * @param masterDataSourceName name of master data sources
- * @param slaveDataSourceNames names of slave data sources
- * @return name of selected data source
- */
- String getDataSource(String name, String masterDataSourceName, List < String > slaveDataSourceNames);
- }
最终需要返回的是slave的名称,后续根据这个名称可以获取到连接池。
下面我们看下两种实现:
- public String getDataSource(final String name, final String masterDataSourceName, final List < String > slaveDataSourceNames) {
- return slaveDataSourceNames.get(new Random().nextInt(slaveDataSourceNames.size()));
- }
@Override
public String getDataSource(final String name, final String masterDataSourceName, final List
这块用了一个缓存,COUNT_MAP,缓存的内容是name-count的键值对,而count是一个原子类,它的值一直是0,1,...,slaves.size()-1,0,1..这样循环,所以每个slave都会被轮询到。
分库分表的算法目前支持的内容包括:
这块主要是定义了一些接口,具体的实现还是要看自己来实现。我们来看下example中的一些已经实现的算法。
- public final class PreciseModuloDatabaseShardingAlgorithm implements PreciseShardingAlgorithm < Integer > {
- @Override public String doSharding(final Collection < String > availableTargetNames, final PreciseShardingValue < Integer > shardingValue) {
- for (String each: availableTargetNames) {
- if (each.endsWith(shardingValue.getValue() % 2 + "")) {
- return each;
- }
- }
- throw new UnsupportedOperationException();
- }
- }
这块就是实现了一个精准分片的算法,我们主要看下doSharding这个方法,里面包含两个参数availableTargetNames和shardingValue。那么这两个是什么呢?我们debug一下,跟踪一下代码,可以看到,shardingValue其实就是分片项,也就是比如order_id、user_id等等字段值,而availableTargetNames就是所谓的实际数据库表节点。这边遍历的也是实际节点,当分片项(或分片字段)满足一定的条件时,返回实际数据库表节点,用于组装sql。
总的来说,分片算法这块其实根据自己的业务需求自己进行扩展的,总的来说还是要根据实际的机器部署情况来。另外读写分离这块是否需要进行扩展,也是看后续的需要。
来源: http://www.cnblogs.com/f-zhao/p/7877468.html