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。

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

  • 相关阅读:
    object sender和EventArgs e含义
    将十进制小数转化为二进制小数的方法
    什么是类、对象、方法、属性、类的成员
    asp.net代码中尖括号和百分号的含义
    打开某个AVI文件,explorer.exe遇到问题需要关闭的解决方法
    中国娱乐学习门户负责人吴晓林讲解项目
    系统流程图与业务流程图
    如何去掉Zblog的版权信息(powered by)
    利用教育游戏丰富与深化综合实践活动课程教与学的理论与实践研究 课题
    浅析C# 中object sender与EventArgs e(转)
  • 原文地址:https://www.cnblogs.com/f-zhao/p/7877468.html
Copyright © 2011-2022 走看看