zoukankan      html  css  js  c++  java
  • 【源码解析】Sharding-Jdbc中的算法

    Sharding-jdbc中的很多地方涉及到算法,比如主从配置这块、分库分表这块。本文主要从源码角度介绍下,目前主要包含哪些算法,以及这些算法的内容。

    一、读写分离(主从配置)

    这块的代码主要在core模块中的api/algorithm/masterslave下面,这块的算法的主要目的,其实是在读的时候,如何选择从数据库。按照常规的理解,可以有以下几种(参考dubbo):

    • 随机算法
    • 轮询
    • 最小活跃
    • 一致性hash

    目前在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的名称,后续根据这个名称可以获取到连接池。

    下面我们看下两种实现:

    • RandomMasterSlaveLoadBalanceAlgorithm
    public String getDataSource(final String name, final String masterDataSourceName, final List<String> slaveDataSourceNames) {
        return slaveDataSourceNames.get(new Random().nextInt(slaveDataSourceNames.size()));
    }
    

    可以看到,随机了一个slave集群大小的随机数,然后从slave list中获取对应的slave name。

    • RoundRobinMasterSlaveLoadBalanceAlgorithm
    private static final ConcurrentHashMap<String, AtomicInteger> COUNT_MAP = new ConcurrentHashMap<>();
    
    @Override
    public String getDataSource(final String name, final String masterDataSourceName, final List<String> slaveDataSourceNames) {
        AtomicInteger count = COUNT_MAP.containsKey(name) ? COUNT_MAP.get(name) : new AtomicInteger(0);
        COUNT_MAP.putIfAbsent(name, count);
        count.compareAndSet(slaveDataSourceNames.size(), 0);
        return slaveDataSourceNames.get(count.getAndIncrement() % slaveDataSourceNames.size());
    }
    

    这块用了一个缓存,COUNT_MAP,缓存的内容是name-count的键值对,而count是一个原子类,它的值一直是0,1,...,slaves.size()-1,0,1..这样循环,所以每个slave都会被轮询到。

    二、分库分表

    分库分表的算法目前支持的内容包括:

    • 精确分库分表PreciseShardingValue
    • 按照范围分库分表RangeShardingValue
    • 按照列表分库分表ListShardingValue

    这块主要是定义了一些接口,具体的实现还是要看自己来实现。我们来看下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。

    总的来说,分片算法这块其实根据自己的业务需求自己进行扩展的,总的来说还是要根据实际的机器部署情况来。另外读写分离这块是否需要进行扩展,也是看后续的需要。

  • 相关阅读:
    Silverlight 3 Beta版的变化
    路由事件[转]
    使用Live writer写博客(转)
    Silverlight 3.0正式版RTW的发布日期
    向NBA神化人物们致敬
    英语新闻网站大全
    《Silverlight开发者期刊第一期》Silverlight开发者团队(银客帝国)
    逻辑树与可视树[转]
    微软下载中心使用Silverlight搜索
    DeskViewer基于Silverlight 2.0开发的个性相册展示系统
  • 原文地址:https://www.cnblogs.com/f-zhao/p/7877468.html
Copyright © 2011-2022 走看看